Mercurial > hg > shenandoah-preopenjdk-archive > openjdk8 > nashorn
changeset 52:265c46dbcf43
8007004: nashorn script engine should not use thread context class loader as script 'application loader'
Reviewed-by: attila, hannesw
author | sundar |
---|---|
date | Mon, 28 Jan 2013 21:29:05 +0530 |
parents | 8f7a86f82376 |
children | b6c69beebde6 |
files | src/jdk/nashorn/api/scripting/NashornScriptEngine.java src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java |
diffstat | 2 files changed, 46 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Mon Jan 28 18:10:16 2013 +0530 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Mon Jan 28 21:29:05 2013 +0530 @@ -74,27 +74,18 @@ // default options passed to Nashorn Options object private static final String[] DEFAULT_OPTIONS = new String[] { "-scripting", "-af", "-doe" }; - NashornScriptEngine(final NashornScriptEngineFactory factory) { - this(factory, DEFAULT_OPTIONS); + NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) { + this(factory, DEFAULT_OPTIONS, appLoader); } @SuppressWarnings("LeakingThisInConstructor") - NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args) { + NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader) { this.factory = factory; final Options options = new Options("nashorn"); options.process(args); // throw ParseException on first error from script final ErrorManager errMgr = new Context.ThrowErrorManager(); - // application loader for the context - ClassLoader tmp; - try { - tmp = Thread.currentThread().getContextClassLoader(); - } catch (final SecurityException se) { - tmp = null; - } - final ClassLoader appLoader = tmp; - // create new Nashorn Context this.nashornContext = AccessController.doPrivileged(new PrivilegedAction<Context>() { @Override
--- a/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Mon Jan 28 18:10:16 2013 +0530 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Mon Jan 28 21:29:05 2013 +0530 @@ -31,6 +31,7 @@ import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import jdk.nashorn.internal.runtime.Version; +import sun.reflect.Reflection; /** * JSR-223 compliant script engine factory for Nashorn. The engine answers for: @@ -136,7 +137,7 @@ @Override public ScriptEngine getScriptEngine() { - return new NashornScriptEngine(this); + return new NashornScriptEngine(this, getAppClassLoader()); } /** @@ -146,7 +147,7 @@ * @return newly created script engine. */ public ScriptEngine getScriptEngine(final String[] args) { - return new NashornScriptEngine(this, args); + return new NashornScriptEngine(this, args, getAppClassLoader()); } // -- Internals only below this point @@ -176,4 +177,44 @@ private static List<String> immutableList(final String... elements) { return Collections.unmodifiableList(Arrays.asList(elements)); } + + private static ClassLoader getAppClassLoader() { + if (System.getSecurityManager() == null) { + return ClassLoader.getSystemClassLoader(); + } + + // Try to determine the caller class loader. Use that if it can be + // found. If not, use the class loader of nashorn itself as the + // "application" class loader for scripts. + + // User could have called ScriptEngineFactory.getScriptEngine() + // + // <caller> + // <factory.getScriptEngine()> + // <factory.getAppClassLoader()> + // <Reflection.getCallerClass()> + // + // or used one of the getEngineByABC methods of ScriptEngineManager. + // + // <caller> + // <ScriptEngineManager.getEngineByName()> + // <factory.getScriptEngine()> + // <factory.getAppClassLoader()> + // <Reflection.getCallerClass()> + + // So, stack depth is 3 or 4 (recall it is zero based). We try + // stack depths 3, 4 and look for non-bootstrap caller. + Class<?> caller = null; + for (int depth = 3; depth < 5; depth++) { + caller = Reflection.getCallerClass(depth); + if (caller != null && caller.getClassLoader() != null) { + // found a non-bootstrap caller + break; + } + } + + final ClassLoader ccl = (caller == null)? null : caller.getClassLoader(); + // if caller loader is null, then use nashorn's own loader + return (ccl == null)? NashornScriptEngineFactory.class.getClassLoader() : ccl; + } }