Closed
Bug 8842
Opened 26 years ago
Closed 14 years ago
Rhino : Public methods are lost when subclassed with a "non-public" class.
Categories
(Core Graveyard :: Java: Live Connect, defect, P3)
Tracking
(Not tracked)
RESOLVED
INCOMPLETE
People
(Reporter: time, Unassigned)
Details
Attachments
(1 file)
|
12.61 KB,
text/plain
|
Details |
If I have a "public class SuperC", which has a method "public void pubmeth()",
and then I subclass "SuperC", with "final class SubC", and I DO NOT define
"pubmeth()" in "SubC", then when I have a "SubC" in my JavaScript, I can not
see the method "pubmeth()". This is not correct.
If I do a "SubC.instance.getClass().getMethods()", "pubmeth" is listed, and if
I call "isPublic()" on pubmeth's Method, it returns true. Sounds like
LiveConnect is mistakenly making the method private because the subclass is not
explicitly declared as public (or because it is final?).
Comment 1•26 years ago
|
||
First, I couldn't duplicate your problem. (See my test case, below.)
Second, LiveConnect uses getMethods() internally to enumerate the methods of a
class, so it seems unlikely that the method would be enumerated when
getMethods() is called "by hand", but not when called by LiveConnect. Possibly,
this is a problem with your JVM. Which JVM are you using ?
I used this test case with JDK1.1.7:
public class SuperC {
public SuperC() {super();}
public int pubmeth() {return 7;}
static public SubC instantiate() {return new SubC();}
}
final class SubC extends SuperC {
}
js> s = Packages.SuperC.instantiate()
netscape.javascript.SubC@20684b
js> for (p in s) print (p)
pubmeth
wait
notifyAll
notify
toString
equals
hashCode
getClass
js> s.pubmeth()
7
posting message sent by tim in mail.
------
On Thu, Jun 24 1999, bugzilla-daemon@mozilla.org wrote:
bugzil> + ------- Additional Comments From fur@netscape.com 06/24/99 10:18
-------
bugzil> + First, I couldn't duplicate your problem. (See my test case, below.)
Bummer.
bugzil> + Second, LiveConnect uses getMethods() internally to enumerate the
methods of
a
bugzil> + class, so it seems unlikely that the method would be enumerated when
bugzil> + getMethods() is called "by hand", but not when called by LiveConnect.
Possibly,
bugzil> + this is a problem with your JVM. Which JVM are you using ?
I use Sun's JDK1.1.7B. The problem lies with a class
'com.sun.jndi.ldap.LdapAttribute',
which subclasses 'javax.naming.directory.BasicAttribute'. I had been writing
scripts
that were calling 'getID()'. Suddenly, when I upgraded the ldap.jar, the code
stopped
working. I ran Mocha on the two versions of the class, and here are the diffs:
-------------------------------------------------------------------------------
-----------
12c12
< final synchronized class LdapAttribute extends BasicAttribute
---
> public synchronized class LdapAttribute extends BasicAttribute
14,17c14,17
< private transient DirContext baseCtx;
< private Name rdn;
< private String baseCtxURL;
< private Hashtable baseCtxEnv;
---
> protected transient DirContext baseCtx;
> protected Name rdn;
> protected String baseCtxURL;
> protected Hashtable baseCtxEnv;
26c26
< LdapAttribute(String string)
---
> public LdapAttribute(String string)
32c32
< LdapAttribute(String string, Object object)
---
> public LdapAttribute(String string, Object object)
38c38
< LdapAttribute(Attribute attribute, DirContext dirContext, Name name)
---
> public LdapAttribute(Attribute attribute, DirContext dirContext, Name
name)
49c49
< LdapAttribute(String string, DirContext dirContext, Name name)
---
> public LdapAttribute(String string, DirContext dirContext, Name name)
57c57
< LdapAttribute(String string, Object object, DirContext dirContext, Name
name)
---
> public LdapAttribute(String string, Object object, DirContext dirContext,
Name
name)
65c65
< void setParent(DirContext dirContext, Name name)
---
> public void setParent(DirContext dirContext, Name name)
71c71
< private DirContext getBaseCtx()
---
> protected DirContext getBaseCtx()
90c90
< private void setBaseCtxInfo()
---
> protected void setBaseCtxInfo()
-------------------------------------------------------------------------------
-----------
I looked through the code in JavaMembers.java, and saw how the function was
located.
I wrote my own test program to iterate through the methods and my test program
did
show
the getID() method as public. Therefore, it would have to be something in the
code
that
follows, AFTER my comment in the code.
void reflectMethod(Scriptable scope, Method method) {
int mods = method.getModifiers();
if (!Modifier.isPublic(mods))
return;
// I AM PRESUMING THAT I GET THIS FAR, BUT HAVE NOT CONFIRMED...
boolean isStatic = Modifier.isStatic(mods);
Hashtable ht = isStatic ? staticMembers : members;
String name = method.getName();
NativeJavaMethod fun = (NativeJavaMethod) ht.get(name);
if (fun == null) {
fun = new NativeJavaMethod();
fun.setParentScope(scope);
fun.setPrototype(ScriptableObject.getFunctionPrototype(scope));
ht.put(name, fun);
fun.add(method);
}
else
fun.add(method);
}
So that is as far as I have been able to take it.
I sure hope that helps.
I have tried this with both the 1.4v3 and 'tip' releaseses of Rhino.
Thanks very much for your attention.
tim.
bugzil> + I used this test case with JDK1.1.7:
bugzil> +
bugzil> + public class SuperC {
bugzil> + public SuperC() {super();}
bugzil> + public int pubmeth() {return 7;}
bugzil> + static public SubC instantiate() {return new SubC();}
bugzil> + }
bugzil> +
bugzil> + final class SubC extends SuperC {
bugzil> + }
bugzil> +
bugzil> + js> s = Packages.SuperC.instantiate()
bugzil> + netscape.javascript.SubC@20684b
bugzil> + js> for (p in s) print (p)
bugzil> + pubmeth
bugzil> + wait
bugzil> + notifyAll
bugzil> + notify
bugzil> + toString
bugzil> + equals
bugzil> + hashCode
bugzil> + getClass
bugzil> + js> s.pubmeth()
Tim Endres - time@ice.com
ICE Engineering, Inc. - http://www.ice.com/
"USENET - a slow moving self parody." - Peter Honeyman
adding frank since it appears this is a rhino issue, not a C engine problem.
Updated•26 years ago
|
Assignee: fur → rogerl
Tim says:
Ok, I have a little more input that may mean more to you than it does to me.
What I did was go into JavaMembers and add debugging to the methods get() and
reflectMethod(). What I see when I run this is that the JavaMembers instance
that is called to get() the function is NOT the same as the one that was
called
to reflectMethod(). On the other hand, when I run the test case that works,
the
JavaMembers instance is the same in both cases.
I have tried to change everything that I can think of in the test app to try
and
reproduce the problem to no avail. Everytime, the JavaMembers instance remains
the same.
SO, can anyone think of a reason why the application that fails might cause a
different JavaMembers instance to be called for get(), versus the instance
that
is called for reflectMethod()?! In other words, what is the instance tied to
and where does it come from? It appears that the first time is it tied to the
javax.naming.directory.BasicAttribute and the second time it is tied to
java.lang.Object (based on the "cl" field of JavaMembers).
Anyway, here is the output for what it is worth. JMGET is the get() method's
output. I have attached the source code with the debugging lines in it so you
can make sense of the output.
tim.
-----------------------------------------------------------------------
----- COMPILE -----
----- EXEC -----
// HERE IS THE CALL TO JavaMembers.relectMethod( "getID" )...
REFLECTMETHOD: this = 'org.mozilla.javascript.JavaMembers@1cba76
REFLECTMETHOD: cl 'javax.naming.directory.BasicAttribute' = class
javax.naming.directory.BasicAttribute
REFLECTMETHOD: method getID() = public java.lang.String
javax.naming.directory.BasicAttribute.getID()
method MODS = 1
isAbstract()? = false
isFinal()? = false
isInterface()? = false
isPrivate()? = false
isProtected()? = false
isPublic()? = true
isStatic()? = false
REFLECTMETHOD: FUN = null
REFLECTMETHOD: SCOPE '[object Object]
REFLECTMETHOD: NEW PUT 'getID',
org.mozilla.javascript.NativeJavaMethod@1cb5bd,
into {clone=org.mozilla.javascript.NativeJavaMethod@1cb696,
wait=org.mozilla.jav
ascript.NativeJavaMethod@1cb64b,
getClass=org.mozilla.javascript.NativeJavaMetho
d@1cb686, hashCode=org.mozilla.javascript.NativeJavaMethod@1cb66a,
toString=org.
mozilla.javascript.NativeJavaMethod@1cb69a,
getID=org.mozilla.javascript.NativeJ
avaMethod@1cb5bd,
equals=org.mozilla.javascript.NativeJavaMethod@1cb691, size=or
g.mozilla.javascript.NativeJavaMethod@1cb659,
getAll=org.mozilla.javascript.Nati
veJavaMethod@1cb651,
notify=org.mozilla.javascript.NativeJavaMethod@1cb643, get=
org.mozilla.javascript.NativeJavaMethod@1cb63f,
notifyAll=org.mozilla.javascript
.NativeJavaMethod@1cb647}
ATTR isa com.sun.jndi.ldap.LdapAttribute
// HERE IS THE CALL TO JavaMembers.get( "getID" )...
JMGET: this = 'org.mozilla.javascript.JavaMembers@1d2425
JMGET: cl 'java.lang.Object' = class java.lang.Object
JMGET: scope 'org.mozilla.javascript.NativeJavaObject@1d2422'
JMGET: name 'getID'
JMGET: ht '{wait=org.mozilla.javascript.NativeJavaMethod@1d2158,
getClass=org.mo
zilla.javascript.NativeJavaMethod@1d210f,
hashCode=org.mozilla.javascript.Native
JavaMethod@1d2113,
toString=org.mozilla.javascript.NativeJavaMethod@1d2122, equa
ls=org.mozilla.javascript.NativeJavaMethod@1d2117,
notify=org.mozilla.javascript
.NativeJavaMethod@1d2133,
notifyAll=org.mozilla.javascript.NativeJavaMethod@1d21
54}'
JMGET: member 'null'
Exception occurred during event dispatching:
org.mozilla.javascript.EvaluatorException: undefined is not a function.
at
org.mozilla.javascript.DefaultErrorReporter.runtimeError(DefaultErrorReporter.j
ava:44)
at org.mozilla.javascript.Context.reportRuntimeError(Context.java:390)
at org.mozilla.javascript.Context.reportRuntimeError(Context.java:406)
at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1222)
at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:1597)
at
org.mozilla.javascript.InterpretedScript.call(InterpretedScript.java:
-----------------------------------------------------------------------
FOR REFERENCE, THIS IS THE OUTPUT OF THE PROGRAM THAT WORKS OK
-----------------------------------------------------------------------
REFLECTMETHOD: this = 'org.mozilla.javascript.JavaMembers@1d1874
REFLECTMETHOD: cl 'com.sun.jndi.ldap.LdapAttribute' = class
com.sun.jndi.ldap.LdapAttribute
REFLECTMETHOD: method getID() = public java.lang.String
javax.naming.directory.BasicAttribute.getID()
method MODS = 1
isAbstract()? = false
isFinal()? = false
isInterface()? = false
isPrivate()? = false
isProtected()? = false
isPublic()? = true
isStatic()? = false
REFLECTMETHOD: FUN = null
REFLECTMETHOD: SCOPE '[object Object]
REFLECTMETHOD: NEW PUT 'getID',
org.mozilla.javascript.NativeJavaMethod@1d1769,
into {clone=org.mozilla.javascript.NativeJavaMethod@1d17ff,
wait=org.mozilla.jav
ascript.NativeJavaMethod@1d180f,
getClass=org.mozilla.javascript.NativeJavaMetho
d@1d17f3, hashCode=org.mozilla.javascript.NativeJavaMethod@1d17f7,
toString=org.
mozilla.javascript.NativeJavaMethod@1d1803,
getID=org.mozilla.javascript.NativeJ
avaMethod@1d1769,
equals=org.mozilla.javascript.NativeJavaMethod@1d17fb, size=or
g.mozilla.javascript.NativeJavaMethod@1d17c8,
getAll=org.mozilla.javascript.Nati
veJavaMethod@1d1815,
notify=org.mozilla.javascript.NativeJavaMethod@1d1807, get=
org.mozilla.javascript.NativeJavaMethod@1d1819,
notifyAll=org.mozilla.javascript
.NativeJavaMethod@1d180b}
JMGET: this = 'org.mozilla.javascript.JavaMembers@1d1874
JMGET: cl 'com.sun.jndi.ldap.LdapAttribute' = class
com.sun.jndi.ldap.LdapAttribute
JMGET: scope 'org.mozilla.javascript.NativeJavaObject@1d1873'
JMGET: name 'getID'
JMGET: ht '{hashCode=org.mozilla.javascript.NativeJavaMethod@1d17f7,
remove=org.
mozilla.javascript.NativeJavaMethod@1d16ae,
clone=org.mozilla.javascript.NativeJ
avaMethod@1d17ff, size=org.mozilla.javascript.NativeJavaMethod@1d17c8,
getID=org
.mozilla.javascript.NativeJavaMethod@1d1769,
clear=org.mozilla.javascript.Native
JavaMethod@1d16b2,
getAll=org.mozilla.javascript.NativeJavaMethod@1d1815, wait=o
rg.mozilla.javascript.NativeJavaMethod@1d180f,
getAttributeSyntaxDefinition=org.
mozilla.javascript.NativeJavaMethod@1d16b9,
notify=org.mozilla.javascript.Native
JavaMethod@1d1807,
toString=org.mozilla.javascript.NativeJavaMethod@1d1803, cont
ains=org.mozilla.javascript.NativeJavaMethod@1d16a6,
add=org.mozilla.javascript.
NativeJavaMethod@1d16aa,
notifyAll=org.mozilla.javascript.NativeJavaMethod@1d180
b,
getAttributeDefinition=org.mozilla.javascript.NativeJavaMethod@1d16bd, get=or
g.mozilla.javascript.NativeJavaMethod@1d1819,
getClass=org.mozilla.javascript.Na
tiveJavaMethod@1d17f3,
equals=org.mozilla.javascript.NativeJavaMethod@1d17fb}'
JMGET: member 'org.mozilla.javascript.NativeJavaMethod@1d1769'
Updated•26 years ago
|
Status: NEW → ASSIGNED
Comment 6•26 years ago
|
||
The JavaMembers object that is used to perform the 'get' method is a field
stored in the NativeJavaObject that wraps the java object itself. This is (or
should be) the same value stored in the JavaMembers classTable Hashtable for the
class of the object. However, the debug info provided makes it look as if the
unwrapped java object is a java.lang.Object instead of the expected one.
Can you describe further the process by which the SubC instance is created and
the pubmeth() method invoked? I'm suspecting that we're losing the class type
info somewhere rather than LC mishandling the reflection.
It sure would be nice to have a reproducible case of this, any chance of getting
that?
Updated•26 years ago
|
Target Milestone: M13 → M14
Comment 7•26 years ago
|
||
Not going to make M13 for these.
Comment 10•25 years ago
|
||
This doesn't seem to be a blocker for the M15 stability checkpoint.
Pushing to M16 to facilitate M15 branching.
Target Milestone: M15 → M16
Updated•25 years ago
|
Summary: Public methods are lost when subclassed with a "non-public" class. → Rhino : Public methods are lost when subclassed with a "non-public" class.
Target Milestone: M16 → M30
Comment 12•21 years ago
|
||
Comment #7 targets Milestone M13, Comment #10 pushes this to Milestone M16....
Since then activities seem pretty limited.
Is this still a valid bug?
Comment 13•19 years ago
|
||
-> default assignee for old netscape assigned bugs.
Assignee: rogerl → live-connect
Status: ASSIGNED → NEW
QA Contact: rginda → pschwartau
Target Milestone: Future → ---
Comment 14•14 years ago
|
||
Firefox code moved from custom Liveconnect code to the NPAPI/NPRuntime bridge a while back. Mass-closing the bugs in the liveconnect component which are likely invalid. If you believe that this bug is still relevant to modern versions of Firefox, please reopen it and move it the "Core" product, component "Plug-Ins".
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → INCOMPLETE
You need to log in
before you can comment on or make changes to this bug.
Description
•