5

I compiled following JavaScript file, "test.js", into the "test.class" :

var test = (function () {
  var that = {};

  that.addNumbers = function (a, b) {
    return a+b;
  };

  return that;
}());

I would like to call the compiled JavaScript function, "test.addNumbers(1,2)", in the simple Java program "run.java" as follows :

public class run {

  public static void main(String[] args) throws Exception {

    Context cx = Context.enter();
    
    try {
      Scriptable scope = cx.initStandardObjects();
    
      // HOW TO CALL THE METHOD, Test.addNumbers(1,2)?  Please help me!
        
    } finally {
      Context.exit();
    }
  }
}

I tried many ways, but failed. I read Rhino tutorial and examined many articles and examples, BUT they only show how to call JavaScript methods from the command line or the source file, "test.js". I need to call the method from the compiled "test.class" file.

1 Answer 1

5

Using javap, I believe that the JavaScript type test does not mean that the resultant Java type is this class. The generated Java type invokes the script code in its constructor; this will not result in exposing addNumbers as a Java method.

>javap -classpath . test
public class test extends org.mozilla.javascript.NativeFunction implements org.m
ozilla.javascript.Script{
    public test(org.mozilla.javascript.Scriptable, org.mozilla.javascript.Contex
t, int);
    public test();
    public static void main(java.lang.String[]);
    public final java.lang.Object exec(org.mozilla.javascript.Context, org.mozil
la.javascript.Scriptable);
    public final java.lang.Object call(org.mozilla.javascript.Context, org.mozil
la.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])
;
    public int getLanguageVersion();
    public java.lang.String getFunctionName();
    public int getParamCount();
    public int getParamAndVarCount();
    public java.lang.String getParamOrVarName(int);
    public java.lang.String getEncodedSource();
    public boolean getParamOrVarConst(int);
}

Reading between the lines, I'd say you need to map to Java types to do what you want. From the jsc doc:

-implements java-intf-name

Specifies that a java class implementing the Java interface java-intf-name should be generated from the incoming JavaScript source file. Each global function in the source file is made a method of the generated class, implementing any methods in the interface by the same name.

Define this interface:

//Adder.java
public interface Adder {
  public int addNumbers(int a, int b);
}

Write this implementation:

//AdderImpl.js
function addNumbers(a, b) {
  return a+b;
}

Compile the JavaScript with the arguments -implements Adder AdderImpl.js. Invoke the method like so:

Adder adder = new AdderImpl();
int n = adder.addNumbers(1, 2);
System.out.println(n);

I'd hazard a guess that it was probably necessary to do it this way because of differences in the languages' type systems.

I used Rhino 1.7R2. For the sake of brevity, I've avoided using packages, etc.

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

2 Comments

Thank you very much for your help, it works! I dont need to worry about preparing Context things, instead "new" on the implementation class and just use the interface methods. Fantastic!
Now, what if you want to add class shutters to the final compiled code.

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.