Search code examples
javajavascriptnashorn

Nashorn access non-static Java method


In Java 7 (1.7), I could access a Java method from JavaScript by running this:

ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
jse.eval("importClass(net.apocalypselabs.symat.Functions);");
jse.eval("SyMAT_Functions = new net.apocalypselabs.symat.Functions();");

String input = "notify(\"Foo\");"; // This is user input

jse.eval("with(SyMAT_Functions){ "+input+" }");

Which would run the notify() function from the Functions java class:

public class Functions {
    private Object someObjectThatCannotBeStatic;
    public void notify(Object message) {
        JOptionPane.showMessageDialog(null, message.toString());
    }
    /* Lots more functions in here, several working with the same non-static variable */
}

How do I access the Functions class in Java 1.8 with the Nashorn engine? My goal is to run different code for the first snippet if the user has Java 1.8, while still allowing people with 1.7 to use the app.

I've tried http://www.doublecloud.org/2014/04/java-8-new-features-nashorn-javascript-engine/ , https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html , and How to instantiate a Java class in JavaScript using Nashorn? without luck. None of them seem to allow me the same thing as Java 1.7 did, instead assuming I only want to access static functions and objects.

The most common error I get:

I start with...

ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
jse.eval("var SyMAT_Functions;with (new JavaImporter(Packages.net.apocalypselabs.symat)) {"
                    + "SyMAT_Functions = new Functions();}");

...then...

jse.eval("with(SyMAT_Functions){ "+input+" }");

...spits out...

TypeError: Cannot apply "with" to non script object in <eval> at line number 1

Solution

  • I decided to compile and bundle the "old" Rhino interpreter with my application instead of using Nashorn.

    https://wiki.openjdk.java.net/display/Nashorn/Using+Rhino+JSR-223+engine+with+JDK8