Search code examples
javanashorn

Put java class to nashorn's global scope


I use sandboxed Nashorn like this:

ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine(
            new String[]{"--no-java", "--no-syntax-extensions", "--optimistic-types=true", "--language=es6"},
            null);

But I want to use a single particular class in my javascript. How to do that? For example, I have a class:

class MyClass
{
    public void m1()
    {
        System.out.println("This is m1");
    }
    public void m2()
    {
        System.out.println("This is m2");
    }
}

And I want to use it in the script like

let a=new MyClass();
a.m1();
a.m2();

How to do that? Thank you


Solution

  • you can use Bindings to provide java objects to the ScriptEngine:

    import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
    
    import javax.script.Bindings;
    import javax.script.ScriptEngine;
    import javax.script.ScriptException;
    
    
    public class MyClass {
        public static void main(String[] args) {
    
         ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine(
                new String[]{"--no-java", "--no-syntax-extensions", "--optimistic-types=true", "--language=es6"},
                null);
    
        Bindings bindings = engine.createBindings();
        bindings.put("myclass", new MyClass());
        engine.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
    
        String code = "myclass.m1();";
    
        try {
            engine.eval(code, bindings);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        }
    
        public void m1() {
            System.out.println("This is m1");
        }
    
        public void m2(String str) {
            System.out.println("This is m2 " + str);
        }
    
        public void m3(Class claz) {
            System.out.println(claz);
        }
    
    }
    

    or if MyClass really needs to be instantiated in the JS code you could do (works with Java >=9):

        Bindings bindings = engine.createBindings();
        bindings.put("myclass", StaticClass.forClass(MyClass.class));
    
        var code = "var a = new myclass(); a.m1();";
    
        try {
            engine.eval(code, bindings);
        } catch (ScriptException e) {
            e.printStackTrace();
        }