mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Original problem in following mail. I implemented JDK1.1 compatibility and performance
improvements: Subject: Rhino: Problem in NativeJavaMethod Date: Tue, 14 Aug 2001 10:23:35 +0200 From: felix.meschberger@day.com To: Norris Boyd <nboyd@atg.com> Hi Norris, While working with wrapped Java classes we discovered a problem in NativeJavaMethod : If the public method to be called is part of a non-public class, the Sun Java VM throws an IllegalAccessException. This bug in the Sun VM has been reported as Bug 4071593 to Sun, but has not been resolved since.... I implemented a circumvention, for which I provide you the patch. I quickly tested it, and it seems to work. Regards Felix And here's the patch : diff -w -r1.19 NativeJavaMethod.java 227a228,234 > /** > * Due to a bug in Suns VM, public methods in private > * classes are not accessible by default (Sun Bug #4071593). > * We have to explicitly set the method accessible beforehand > */ > meth.setAccessible(true); > ----------------------------------------------------------------- This message is a private communication. If you are not the intended recipient, please do not read, copy, or use it, and do not disclose it to others. Please notify the sender of the delivery error by replying to this message, and then delete it from your system. Thank you. The sender does not assume any liability for timely, trouble-free, complete, virus free, secure, error free or uninterrupted arrival of this e-mail. For verification please request a hard copy version. mailto:felix.meschberger@day.com http://www.day.com Felix Meschberger Development Day Interactive AG Steinenberg 21-23 4001 Basel Switzerland T 41 61 226 98 98 F 41 61 226 98 97
This commit is contained in:
parent
c8695a1a29
commit
115380ea02
@ -220,44 +220,68 @@ public class NativeJavaMethod extends NativeFunction implements Function {
|
||||
}
|
||||
javaObject = ((Wrapper) o).unwrap();
|
||||
}
|
||||
try {
|
||||
if (debug) {
|
||||
printDebug("Calling ", meth, args);
|
||||
}
|
||||
retry:
|
||||
for (int attempt=0; ; attempt++) {
|
||||
try {
|
||||
if (debug) {
|
||||
printDebug("Calling ", meth, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Due to a bug in Suns VM, public methods in private
|
||||
* classes are not accessible by default (Sun Bug #4071593).
|
||||
* We have to explicitly set the method accessible beforehand
|
||||
*/
|
||||
meth.setAccessible(true);
|
||||
Object retval = meth.invoke(javaObject, args);
|
||||
Class staticType = meth.getReturnType();
|
||||
Object retval = meth.invoke(javaObject, args);
|
||||
Class staticType = meth.getReturnType();
|
||||
|
||||
if (debug) {
|
||||
Class actualType = (retval == null) ? null : retval.getClass();
|
||||
System.err.println(" ----- Returned " + retval +
|
||||
" actual = " + actualType +
|
||||
" expect = " + staticType);
|
||||
}
|
||||
if (debug) {
|
||||
Class actualType = (retval == null) ? null
|
||||
: retval.getClass();
|
||||
System.err.println(" ----- Returned " + retval +
|
||||
" actual = " + actualType +
|
||||
" expect = " + staticType);
|
||||
}
|
||||
|
||||
Object wrapped = NativeJavaObject.wrap(scope, retval, staticType);
|
||||
Object wrapped = NativeJavaObject.wrap(scope, retval, staticType);
|
||||
|
||||
if (debug) {
|
||||
Class actualType = (wrapped == null) ? null : wrapped.getClass();
|
||||
System.err.println(" ----- Wrapped as " + wrapped +
|
||||
" class = " + actualType);
|
||||
}
|
||||
if (debug) {
|
||||
Class actualType = (wrapped == null) ? null
|
||||
: wrapped.getClass();
|
||||
System.err.println(" ----- Wrapped as " + wrapped +
|
||||
" class = " + actualType);
|
||||
}
|
||||
|
||||
if (wrapped == Undefined.instance)
|
||||
if (wrapped == Undefined.instance)
|
||||
return wrapped;
|
||||
if (wrapped == null && staticType == Void.TYPE)
|
||||
return Undefined.instance;
|
||||
return wrapped;
|
||||
if (wrapped == null && staticType == Void.TYPE)
|
||||
return Undefined.instance;
|
||||
return wrapped;
|
||||
} catch (IllegalAccessException accessEx) {
|
||||
throw Context.reportRuntimeError(accessEx.getMessage());
|
||||
} catch (InvocationTargetException e) {
|
||||
throw JavaScriptException.wrapException(scope, e);
|
||||
} catch (IllegalAccessException accessEx) {
|
||||
if (Modifier.isPublic(meth.getModifiers()) && attempt == 0) {
|
||||
/**
|
||||
* Due to a bug in Suns VM, public methods in private
|
||||
* classes are not accessible by default (Sun Bug #4071593).
|
||||
* We have to explicitly set the method accessible
|
||||
* via meth.setAccessible(true) but we have to use
|
||||
* reflection because the setAccessible() in Method is
|
||||
* not available under jdk 1.1. We wait until a failure
|
||||
* to retry to avoid the overhead of this call on cases
|
||||
* that don't require it.
|
||||
*/
|
||||
if (method_setAccessible != null) {
|
||||
Object[] args_wrapper = { Boolean.TRUE };
|
||||
try {
|
||||
method_setAccessible.invoke(meth, args_wrapper);
|
||||
}
|
||||
catch (IllegalAccessException ex) { }
|
||||
catch (IllegalArgumentException ex) { }
|
||||
catch (InvocationTargetException ex) { }
|
||||
}
|
||||
continue retry;
|
||||
}
|
||||
throw Context.reportRuntimeError(
|
||||
"While attempting to call \"" + meth.getName() +
|
||||
"\" in class \"" + meth.getDeclaringClass().getName() +
|
||||
"\" receieved " + accessEx.toString());
|
||||
} catch (InvocationTargetException e) {
|
||||
throw JavaScriptException.wrapException(scope, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,6 +531,17 @@ public class NativeJavaMethod extends NativeFunction implements Function {
|
||||
return methods;
|
||||
}
|
||||
|
||||
// Utility to call Class.getMethod and get null instead of thrown exceptions
|
||||
private static Method getMethod(Class cl, String name, Class[] signature) {
|
||||
try {
|
||||
return cl.getMethod(name, signature);
|
||||
}
|
||||
catch (NoSuchMethodException ex) { }
|
||||
catch (SecurityException ex) { }
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static final boolean debug = false;
|
||||
|
||||
private static void printDebug(String msg, Member member, Object[] args) {
|
||||
@ -519,5 +554,10 @@ public class NativeJavaMethod extends NativeFunction implements Function {
|
||||
}
|
||||
|
||||
Method methods[];
|
||||
|
||||
private static final Method method_setAccessible
|
||||
= getMethod(Method.class,
|
||||
"setAccessible", new Class[] { Boolean.TYPE });
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user