I need to call (with Nashorn) from a Java code a function defined in JavaScript and pass some parameters there. Instead of using Invocable.invokeFunction ("Foo", arg1, arg2), I was going to define an interface and then request Invocable to implement it, just as Oracle suggests here , "Embedding Oracle Nashorn":
package mypackage; public final class MyClass { public interface Composer { void compose(final StringBuilder subject, final StringBuilder body); } public void composeEmail(...) { ... final ScriptEngineManager engineManager = new ScriptEngineManager(); final ScriptEngine engine = engineManager.getEngineByName("nashorn"); engine.eval(scriptText); final Invocable invocable = (Invocable) engine; final Composer composer = (Composer)invocable.getInterface(Composer); composer.compose(subject, body); ... } }
The problem is that since I am doing this in a web application running on Tomcat, my Composer is loaded by the application class loader and the nashorn classes are loaded by the extensions class loader. Therefore, getInterface fails saying TypeError: cannot find a common classloader for ScriptObject and mypackage.Composer
Any ideas how to overcome this? I could, of course, try loading Composer in the parent classloader, assuming (hack-like) that it is actually an extloader, but there is at least one problem with this: it cannot find my class. I believe this is correct: my package is in my web application, and the extension loader does not look there. Any other great ideas?
PS And now I noticed that this message is strange: if the application loader class delegates the ext classloader command, then, of course, the latter is a common class loader for them. Perhaps they were trying to say that the target interface of the loadload class should be equal to the actual loader of the implementation classes, or should the loader of the implementation class delegate the target (but not vice versa)?
source share