From 34427cc0a9ac520bf7c41d02f595f6147c0d7f25 Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Tue, 31 Dec 2002 09:42:42 +0000 Subject: [PATCH] Allow application to customize class loader used for loading generated code. For that I added new method createClasssLoader to Context, which by default returns new instance of DefiningClassLoader and changed the code to use this method instead of creating DefiningClassLoader directly. I moved DefiningClassLoader to org.mozilla.javascript package so core Rhino classes would not depend on org.mozilla.classfile package. I also changed SecurityController.createClasssLoader to take additional parentLoader argument to explicitly specify which class loader should be parent for generated code. --- .../classfile/DefiningClassLoader.java | 39 ++------- .../src/org/mozilla/javascript/Context.java | 5 ++ .../javascript/DefiningClassLoader.java | 84 +++++++++++++++++++ .../mozilla/javascript/FunctionObject.java | 10 +-- .../src/org/mozilla/javascript/Invoker.java | 2 +- .../org/mozilla/javascript/JavaAdapter.java | 5 +- .../mozilla/javascript/NativeJavaPackage.java | 1 - .../javascript/SecurityController.java | 4 +- .../mozilla/javascript/optimizer/Codegen.java | 6 +- .../javascript/optimizer/InvokerImpl.java | 23 +++-- .../tools/shell/JavaPolicySecurity.java | 5 +- 11 files changed, 129 insertions(+), 55 deletions(-) create mode 100644 js/rhino/src/org/mozilla/javascript/DefiningClassLoader.java diff --git a/js/rhino/src/org/mozilla/classfile/DefiningClassLoader.java b/js/rhino/src/org/mozilla/classfile/DefiningClassLoader.java index 93a56913a325..4faf089f1298 100644 --- a/js/rhino/src/org/mozilla/classfile/DefiningClassLoader.java +++ b/js/rhino/src/org/mozilla/classfile/DefiningClassLoader.java @@ -43,40 +43,13 @@ import java.lang.reflect.InvocationTargetException; import org.mozilla.javascript.GeneratedClassLoader; /** - * Load generated classes. + * @deprecated The class is moved to org.mozilla.javascript + * package. * - * @author Norris Boyd + * @see org.mozilla.javascript.DefiningClassLoader */ -public class DefiningClassLoader extends ClassLoader - implements GeneratedClassLoader +public class DefiningClassLoader + extends org.mozilla.javascript.DefiningClassLoader { - public DefiningClassLoader() { - this.parentLoader = getClass().getClassLoader(); - } - - public Class defineClass(String name, byte[] data) { - return super.defineClass(name, data, 0, data.length); - } - - public void linkClass(Class cl) { - resolveClass(cl); - } - - public Class loadClass(String name, boolean resolve) - throws ClassNotFoundException - { - Class clazz = findLoadedClass(name); - if (clazz == null) { - if (parentLoader != null) { - clazz = parentLoader.loadClass(name); - } else { - clazz = findSystemClass(name); - } - } - if (resolve) - resolveClass(clazz); - return clazz; - } - - private ClassLoader parentLoader; + public DefiningClassLoader() { } } diff --git a/js/rhino/src/org/mozilla/javascript/Context.java b/js/rhino/src/org/mozilla/javascript/Context.java index 15ec6844dd75..11f9e07c6e23 100644 --- a/js/rhino/src/org/mozilla/javascript/Context.java +++ b/js/rhino/src/org/mozilla/javascript/Context.java @@ -1865,6 +1865,11 @@ public class Context { */ protected void observeInstructionCount(int instructionCount) {} + public GeneratedClassLoader createClassLoader(ClassLoader parent) { + return new DefiningClassLoader(parent); + + } + /********** end of API **********/ static String getMessage0(String messageId) { diff --git a/js/rhino/src/org/mozilla/javascript/DefiningClassLoader.java b/js/rhino/src/org/mozilla/javascript/DefiningClassLoader.java new file mode 100644 index 000000000000..3b3c1e95ab80 --- /dev/null +++ b/js/rhino/src/org/mozilla/javascript/DefiningClassLoader.java @@ -0,0 +1,84 @@ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Rhino code, released + * May 6, 1999. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1997-1999 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Norris Boyd + * Roger Lawrence + * Patrick Beard + * Igor Bukanov + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU Public License (the "GPL"), in which case the + * provisions of the GPL are applicable instead of those above. + * If you wish to allow use of your version of this file only + * under the terms of the GPL and not to allow others to use your + * version of this file under the NPL, indicate your decision by + * deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete + * the provisions above, a recipient may use your version of this + * file under either the NPL or the GPL. + */ + +package org.mozilla.javascript; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + +/** + * Load generated classes. + * + * @author Norris Boyd + */ +public class DefiningClassLoader extends ClassLoader + implements GeneratedClassLoader +{ + public DefiningClassLoader() { + this.parentLoader = getClass().getClassLoader(); + } + + public DefiningClassLoader(ClassLoader parentLoader) { + this.parentLoader = parentLoader; + } + + public Class defineClass(String name, byte[] data) { + return super.defineClass(name, data, 0, data.length); + } + + public void linkClass(Class cl) { + resolveClass(cl); + } + + public Class loadClass(String name, boolean resolve) + throws ClassNotFoundException + { + Class clazz = findLoadedClass(name); + if (clazz == null) { + if (parentLoader != null) { + clazz = parentLoader.loadClass(name); + } else { + clazz = findSystemClass(name); + } + } + if (resolve) + resolveClass(clazz); + return clazz; + } + + private ClassLoader parentLoader; +} diff --git a/js/rhino/src/org/mozilla/javascript/FunctionObject.java b/js/rhino/src/org/mozilla/javascript/FunctionObject.java index 213cb41247c2..ec57e92979b9 100644 --- a/js/rhino/src/org/mozilla/javascript/FunctionObject.java +++ b/js/rhino/src/org/mozilla/javascript/FunctionObject.java @@ -411,7 +411,7 @@ public class FunctionObject extends BaseFunction { } try { Object result = method == null ? ctor.newInstance(invokeArgs) - : doInvoke(thisObj, invokeArgs); + : doInvoke(cx, thisObj, invokeArgs); return hasVoidReturn ? Undefined.instance : result; } catch (InvocationTargetException e) { @@ -486,13 +486,13 @@ public class FunctionObject extends BaseFunction { return super.construct(cx, scope, args); } - private final Object doInvoke(Object thisObj, Object[] args) + private final Object doInvoke(Context cx, Object thisObj, Object[] args) throws IllegalAccessException, InvocationTargetException { Invoker master = invokerMaster; if (master != null) { if (invoker == null) { - invoker = master.createInvoker(method, types); + invoker = master.createInvoker(cx, method, types); } try { return invoker.invoke(thisObj, args); @@ -510,14 +510,14 @@ public class FunctionObject extends BaseFunction { try { if (parmsLength == VARARGS_METHOD) { Object[] invokeArgs = { cx, thisObj, args, this }; - Object result = doInvoke(null, invokeArgs); + Object result = doInvoke(cx, null, invokeArgs); return hasVoidReturn ? Undefined.instance : result; } else { Boolean b = inNewExpr ? Boolean.TRUE : Boolean.FALSE; Object[] invokeArgs = { cx, args, this, b }; return (method == null) ? ctor.newInstance(invokeArgs) - : doInvoke(null, invokeArgs); + : doInvoke(cx, null, invokeArgs); } } catch (InvocationTargetException e) { diff --git a/js/rhino/src/org/mozilla/javascript/Invoker.java b/js/rhino/src/org/mozilla/javascript/Invoker.java index a70aa4812e85..306b1424a6db 100644 --- a/js/rhino/src/org/mozilla/javascript/Invoker.java +++ b/js/rhino/src/org/mozilla/javascript/Invoker.java @@ -47,7 +47,7 @@ public abstract class Invoker { public abstract Object invoke(Object that, Object [] args); /** Factory method to get invoker for given method */ - public Invoker createInvoker(Method method, Class[] types) { + public Invoker createInvoker(Context cx, Method method, Class[] types) { return null; } diff --git a/js/rhino/src/org/mozilla/javascript/JavaAdapter.java b/js/rhino/src/org/mozilla/javascript/JavaAdapter.java index 8ef70ba07251..764cb5e43b75 100644 --- a/js/rhino/src/org/mozilla/javascript/JavaAdapter.java +++ b/js/rhino/src/org/mozilla/javascript/JavaAdapter.java @@ -331,13 +331,14 @@ public class JavaAdapter extends ScriptableObject { } } + ClassLoader parentLoader = cx.getClass().getClassLoader(); GeneratedClassLoader loader; SecurityController sc = cx.getSecurityController(); if (sc == null) { - loader = new DefiningClassLoader(); + loader = cx.createClassLoader(parentLoader); } else { Object securityDomain = sc.getDynamicSecurityDomain(null); - loader = sc.createClassLoader(securityDomain); + loader = sc.createClassLoader(parentLoader, securityDomain); } Class result = loader.defineClass(adapterName, bytes); loader.linkClass(result); diff --git a/js/rhino/src/org/mozilla/javascript/NativeJavaPackage.java b/js/rhino/src/org/mozilla/javascript/NativeJavaPackage.java index 745f64270a80..e5317116dff9 100644 --- a/js/rhino/src/org/mozilla/javascript/NativeJavaPackage.java +++ b/js/rhino/src/org/mozilla/javascript/NativeJavaPackage.java @@ -38,7 +38,6 @@ package org.mozilla.javascript; import java.lang.reflect.*; -import org.mozilla.classfile.DefiningClassLoader; /** * This class reflects Java packages into the JavaScript environment. We diff --git a/js/rhino/src/org/mozilla/javascript/SecurityController.java b/js/rhino/src/org/mozilla/javascript/SecurityController.java index 311f2dbb8dc5..010f9e6fdc09 100644 --- a/js/rhino/src/org/mozilla/javascript/SecurityController.java +++ b/js/rhino/src/org/mozilla/javascript/SecurityController.java @@ -67,11 +67,13 @@ public abstract class SecurityController { /** * Get class loader-like object that can be used * to define classes with the given security context. + * @param parentLoader parent class loader to delegate search for classes + * not defined by the class loader itself * @param securityDomain some object specifying the security * context of the code that is defined by the returned class loader. */ public abstract GeneratedClassLoader - createClassLoader(Object securityDomain); + createClassLoader(ClassLoader parentLoader, Object securityDomain); /** * Get dynamic security domain that allows an action only if it is allowed diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java b/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java index a85e416006c3..8397158b6464 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java @@ -80,11 +80,13 @@ public class Codegen extends Interpreter { Exception e = null; Class result = null; + ClassLoader parentLoader = cx.getClass().getClassLoader(); GeneratedClassLoader loader; if (securityController == null) { - loader = new DefiningClassLoader(); + loader = cx.createClassLoader(parentLoader); } else { - loader = securityController.createClassLoader(securityDomain); + loader = securityController.createClassLoader(parentLoader, + securityDomain); } nameHelper.reset(); diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/InvokerImpl.java b/js/rhino/src/org/mozilla/javascript/optimizer/InvokerImpl.java index 60cc0b62f007..6f5807c70c86 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/InvokerImpl.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/InvokerImpl.java @@ -40,9 +40,10 @@ import java.util.Hashtable; import java.lang.reflect.Method; import org.mozilla.javascript.Invoker; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.GeneratedClassLoader; import org.mozilla.classfile.ByteCode; import org.mozilla.classfile.ClassFileWriter; -import org.mozilla.classfile.DefiningClassLoader; /** * Avoid cost of java.lang.reflect.Method.invoke() by compiling a class to @@ -50,13 +51,19 @@ import org.mozilla.classfile.DefiningClassLoader; */ public class InvokerImpl extends Invoker { - public Invoker createInvoker(Method method, Class[] types) { + public Invoker createInvoker(Context cx, Method method, Class[] types) { - Invoker result = (Invoker)invokersCache.get(method); - if (result != null) { return result; } - - int classNum = 0; + Invoker result; + int classNum; synchronized (this) { + if (invokersCache == null) { + invokersCache = new Hashtable(); + ClassLoader parentLoader = cx.getClass().getClassLoader(); + classLoader = cx.createClassLoader(parentLoader); + } else { + result = (Invoker)invokersCache.get(method); + if (result != null) { return result; } + } classNum = ++classNumber; } @@ -291,6 +298,6 @@ public class InvokerImpl extends Invoker { } int classNumber; - Hashtable invokersCache = new Hashtable(); - DefiningClassLoader classLoader = new DefiningClassLoader(); + Hashtable invokersCache; + GeneratedClassLoader classLoader; } diff --git a/js/rhino/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java b/js/rhino/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java index 1854fb3ea403..9ffac3952402 100644 --- a/js/rhino/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java +++ b/js/rhino/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java @@ -172,9 +172,10 @@ public class JavaPolicySecurity extends SecurityProxy return new ProtectionDomain(cs, pc); } - public GeneratedClassLoader createClassLoader(Object securityDomain) { + public GeneratedClassLoader + createClassLoader(ClassLoader parentLoader, Object securityDomain) { ProtectionDomain domain = (ProtectionDomain)securityDomain; - return new Loader(getClass().getClassLoader(), domain); + return new Loader(parentLoader, domain); } public Object getDynamicSecurityDomain(Object securityDomain)