2

I'm trying to test out JavaScript through Java using simple Nashorn examples, and I'm just not understanding why I can't access a method of my own class from a JS call.

First, the class I want to work with:

package myPackage;

public class myClass
{
    Object internalObj;


    static boolean test()
    {
        return true;
    }

    boolean storeObject(Object obj)
    {
        internalObj = obj;
        return true;
    }

    String whatObjectType()
    {
        return internalObj.getClass().toString();
    }

}

Then, the code that is to provide scripting calls:

package myPackage;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class myTester
{
    public static void main( String[] args )
    {
        System.out.println(">> Script Testing");

        //test out my class
        System.out.println(myClass.test());

        myClass myObj = new myClass();

        myObj.storeObject("test");

        System.out.println(myObj.whatObjectType());

        //now try the same from javascript
        ScriptEngine js = new ScriptEngineManager().getEngineByName("javascript");

        String myScript ="var myJSClass = Java.type('myPackage.myClass');"
                + "var myJSObj = new myJSClass();"
                + "print(myJSObj.test());";

        try
        {
            js.eval(myScript);
        } catch (ScriptException e)
        {
            e.printStackTrace();
        }       
    }
}

Everything is well and good until the evaluation of myJSObj.test(), which craps out. Here's the output:

>> Script Testing
true
class java.lang.String
javax.script.ScriptException: TypeError: myJSObj.test is not a function in <eval> at line number 1

Most of the Nashorn intro material shows similar examples, except they all work. What am I doing wrong?

1
  • I should note that replacing the call to method test() with a non-static method call results in the same error. Commented Feb 21, 2018 at 18:48

1 Answer 1

2

There are two problems:

  1. You're trying to call a non-public method from outside the package (your JavaScript code isn't in myPackage). test will need to be public in order for you to call it.

  2. You're making the call on an instance of your class, not on the class itself, but test is static. Java allows calling static methods through instance references (it's one of the quirkier things about Java), but JavaScript doesn't have that concept. You'll need to make test an instance method, or call it on myJSClass instead.

Fix those, and it works. :-)

Sign up to request clarification or add additional context in comments.

2 Comments

1) Worked perfectly, thank you. I just assumed something being called from within a package would have some sort of operational context for the package itself. Curious, is there a way to include a particular script within the package? Might be useful. 2) I did not know this, thanks again.
@Diego: No worries. I doubt it's possible to put the JavaScript code in a package, not least because JavaScript isn't class-based (even when using ES2015's class syntax), and you can happily copy a "method" from one JavaScript "class" to another. But I don't know that for sure, they may have come up with some clever way of supporting it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.