Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 809
igr Avatar asked May 13 '15 21:05

igr


People also ask

Can a class be loaded by two different classloaders in Java?

A class is always identified using its fully qualified name (package. classname). So when a class is loaded into JVM, you have an entry as (package, classname, classloader). Therefore the same class can be loaded twice by two different ClassLoader instances.

Can you have more than one ClassLoader in Java?

Each application might use different versions of the same libraries, and must thus have a different classloader from the others in order to be able to have different versions of the same classes in a single JVM. but the web server has its own loader.it can have several classloaders.

How does a ClassLoader work internally?

The ClassLoader works based on a set of operations given by the delegation model. They are: ClassLoader always follows the Delegation Hierarchy Principle. Whenever JVM comes across a class, it checks whether that class is already loaded or not.

How many types of classloaders are there?

There are three types of built-in ClassLoader in Java. Bootstrap Class Loader – It loads JDK internal classes. It loads rt. jar and other core classes for example java.


1 Answers

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.

like image 194
A. Sundararajan Avatar answered Sep 20 '22 10:09

A. Sundararajan