Java 8 ScriptEngine across ClassLoaders

I need to execute some javascript code 'inside' different classloaders. If it is java, each task will run in separate class loader. Now I need this to be javascript.

Do I need to create new instance of ScriptEngine in each classloader, or is it ok to share one across class loaders?


From your question it is not clear why'd you look for such classloader isolation. So, I'm summarizing nashorn's classloader here - may be, you'll get what you're looking for.

Nashorn and classloaders:

  1. Nashorn classes (jdk.nashorn.*) are loaded by Java extension class loader
  2. Generated script classes, adapters (subclasses, interface implementations from script) are loaded by nashorn's internal class loaders.
  3. Java classes referred from script are loaded by Nashorn "app class loader".

(1) and (2) can not be customized. There are assumptions in nashorn code that it's a privileged code. And there are assumptions about genarated script class loaders and adapter loaders.

(3) is by default the thread context classloader at the time of nashorn engine creation. If the thread context class loader is null, then Nashorn's own loader - the extension loader - is used.

So if you create Nashorn engine after setting suitable thread context loader via Thread.setContextClassLoader API, you can control script engine's "app class loader".

If you're okay with using NashornScriptEngineFactory (nashorn specific API https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/NashornScriptEngineFactory.html) to create script engine, you can programmatically pass any classloader as "app class loader" as well. You may want to check out the NashornScriptEngineFactory methods that accept ClassLoader argument.

In addition to the "app class loader", optionally, you can also use another additional classloader that is searched before "app class loader". This is specified by "-cp" or "-classpath" nashorn command line option. Note that you can specify nashorn command line options for script engine via "nashorn.args" System property or programmatically pass using NashornScriptEngineFactory class's getScriptEngine methods. See also: https://wiki.openjdk.java.net/display/Nashorn/Nashorn+jsr223+engine+notes

Hope this helps.