JSDT/Equinox hook for Nashorn
Nashorn in lib/ext
Eclipse plug-ins are OSGi bundles which, by default, are using the "boot class loader", which excludes the lib/ext
As JSDT.core is using Nashorn, the JSDT team elaborated a way to load this external lib.
Hooking Nashorn at Runtime
At runtime, we have the
org.eclipse.wst.jsdt.nashorn.extension plug-in fragment, which contains a class extending
ClassLoaderHook, which give the option to extend the bundle classpath by adding the lib/ext folder.
To activate the ClassLoaderHook you need to add the following param to the launch configuration:
Practically: you will need to add the parameter to your running configuration or to your product configuration to have it working at a runtime.
Hooking Nashorn in Dev, Test and Build
In testing at development time, and in local Tycho build you will need to specify a parameter to tell the Equinox classloader to load the normal Java extension classloader to load the normal Java extension classloader.
For this you will need to use the following param:
Practically you will need to add the param to your test configuration, and in your tycho configuration. As an example check the webtools.jsdt\tests\pom.xml, where you can see the argline passes to maven:
Override the createClassloader
The override is made in two bundles:
- org.eclipse.wst.jsdt.core : that depends on extension and imports extension.loader
- org.eclipse.wst.jsdt.nashorn.extension : fragment, containing a class that extends Hook
See the wiki page explaining the
The hook is implemented in the extension bundle, by the NashornLoaderHook class, which extends ClassLoaderHook. (more details on framework hooks here: https://wiki.eclipse.org/Adaptor_Hooks)
In our implementation, the class checks for which parent bundle is loading the extension bundle, and when the bundle is JSDT.core, we extend the classpath.
Activate Equinox Hook
Equinox looks in every fragment for classes extending the Hook and calls the methods overriding the API, only when a specific parameter is effective.
So, At runtime, the eclipse configuration needs the parameter below to be effective
The default vmargs can be specified in the target file in the Environment tab.
More information about using the osgi.framework.extensions mechanism in Adaptor Hooks.
EPP, Build, Dev and Test
Also when running the EPP Packaging we need this param in the product configuration.
The same is in testing, at development time and in local Tycho build.
To avoid issues with Tycho reactor, there is the option to use a different parameter from Equinox, to specify an external classloader. This is not standard in OSGi, so we can not use it at runtime.
In webtools.jsdt\tests\pom.xml, you see the arg.line which allow Tycho to run tests during the build, and the same trick can be used during the build.
“Look in the bundle parent classloader, which includes the lib/ext that are not in the boot classloader that is the default for OSGi”
What happens when it goes wrong
If the classloaders are not working properly, the first indication of a problem will be failure to load one of the Nashorn classes. A typical error message may include one of the following in the stack trace:
java.lang.ClassNotFoundException: jdk.nashorn.internal.runtime.ECMAException cannot be found by org.eclipse.wst.jsdt.core_2.0.0.v201605200022
- This is how it works in M6. We’re not really happy of this, as there are other options, TBC
- See also: OSGi and Equinox: Creating Highly Modular Java Systems, Chap 23.9