Ben McCann
Ben McCann

Reputation: 19014

Which JS Script Engine will be chosen by Java?

ScriptEngineManager.getEngineByName looks up and creates a ScriptEngine for a given name.

Rhino registers itself as "js", "rhino", "JavaScript", "javascript", "ECMAScript", and "ecmascript"

Nashorn registers itself as "nashorn", "Nashorn", "js", "JS", "JavaScript", "javascript", "ECMAScript", and "ecmascript"

If I use a name like "js" which both Nashorn and Rhino have registered with, which script engine will be used? Will it use Nashorn on Java 8 and Rhino otherwise?

Upvotes: 5

Views: 1759

Answers (2)

seanf
seanf

Reputation: 6734

Reading the code, registerEngineName is indeed deterministic, however the discovery mechanism is a separate thing (as implied by the JavaDoc), and it is non-deterministic, because it adds all the engines to a HashSet during discovery, and when asked for an engine by name, it just uses the first match it finds.

You can run into this if you install an updated Rhino ScriptEngine in Java 7 and request it by any of the usual names (js, rhino, etc).

But unless you do that, both Java 7 and Java 8 come with exactly one implementation, which answers to js, javascript, ecmascript, etc. As long as you don't ask for rhino or nashorn, it should work in both cases.

Upvotes: 0

Robby Cornelissen
Robby Cornelissen

Reputation: 97322

Looking at the JavaDoc for registerEngineName:

Registers a ScriptEngineFactory to handle a language name. Overrides any such association found using the Discovery mechanism.

And also at the registerEngineName source code (note that nameAssociations is a hash map):

public void registerEngineName(String name, ScriptEngineFactory factory) {
    if (name == null || factory == null) throw new NullPointerException();
        nameAssociations.put(name, factory);
}

So, it seems that, for a given name, getEngineByName will return the script engine factory that was the last to be registered for that name.

As script engine factories are loaded through the ServiceLoader mechanism, the loading order will depend on the order that the service configuration files are enumerated by the relevant class loaders' getResources method.

For a default installation, all this does not matter too much as Java 8 only includes Nashorn, and Java 7 and earlier only include Rhino. If you would add an additional engine through the system class path, it will be loaded after the one loaded by the bootstrap/extension class loader, and thus take precedence.

Upvotes: 4

Related Questions