Subject:
optimizer SecurityException
Date:
Mon, 11 Oct 1999 17:37:51 -0400
From:
Andrew Wason <aw@softcom.com>
To:
norris@netscape.com (Norris Boyd)
CC:
Howard Lin <howard@softcom.com>
We use our own SecuritySupport implementation in Rhino. This is properly
getting called by the optimizer to generate new classes (e.g.
org.mozilla.javascript.gen.c5 etc.)
However, after defining the class, Codegen.compile calls getClassLoader()
on the new class. The default SecurityManager doesn't allow
getClassLoader() to be called and so an exception is thrown:
java.lang.RuntimeException: Malformed optimizer package
java.security.AccessControlException: access denied
(java.lang.RuntimePermission getClassLoader )
at org.mozilla.javascript.optimizer.Codegen.compile(Codegen.java:138)
at org.mozilla.javascript.Context.compile(Context.java:1761)
at org.mozilla.javascript.Context.compile(Context.java:1691)
at org.mozilla.javascript.Context.compileReader(Context.java:810)
at org.mozilla.javascript.Context.evaluateReader(Context.java:725)
[...]
This is kind of a pain to duplicate outside of our application, but if you
require a test case I can create one.
Codegen is attempting to call loadClass() after it uses
SecuritySupport.defineClass(). Our SecuritySupport calls loadClass()
internally in its defineClass() implementation. This is what JavaAdapter
expects.
This is from Codegen.compile():
if (securitySupport == null) {
if (Context.isSecurityDomainRequired())
throw new SecurityException("Required " +
"security context missing");
if (classLoader == null)
classLoader = new JavaScriptClassLoader();
clazz = classLoader.defineClass(name, classFile);
} else {
clazz = securitySupport.defineClass(name,
classFile,
securityDom
securityDomain);
}
ClassLoader loader = clazz.getClassLoader();
clazz = loader.loadClass(name);
This is from JavaAdapter.createAdapterClass():
SecuritySupport ss = cx.getSecuritySupport();
if (ss != null) {
Object securityDomain = cx.getSecurityDomainForStackDepth(-1);
return ss.defineClass(adapterName, bytes, securityDomain);
} else {
if (classLoader == null)
classLoader = new MyClassLoader();
classLoader.defineClass(adapterName, bytes);
return classLoader.loadClass(adapterName, true);
}
So JavaAdapter is assuming SecuritySupport.defineClass() will call
ClassLoader.loadClass() on the new class, while Codegen is assuming it
needs to call ClassLoader.loadClass() on the class defined by
SecuritySupport.defineClass().
These should be made consistent, and in both cases it should be assumed
that SecuritySupport will both define and load the class.
Andrew
--
Andrew Wason
SoftCom, Inc.
aw@softcom.com