如何在Java程序中调用Rhino编译的JavaScript方法(类文件)?

5
我将以下JavaScript文件“test.js”编译成“test.class”文件:
var test = (function () {
  var that = {};

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

  return that;
}());

我希望能在简单的Java程序"run.java"中调用编译后的JavaScript函数"test.addNumbers(1,2)",代码如下:
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();
    }
  }
}

我尝试了很多方法,但都失败了。 我阅读了Rhino教程并查看了许多文章和示例,但它们只展示了如何从命令行或源文件“test.js”中调用JavaScript方法。 我需要从已编译的“test.class”文件中调用该方法。

非常感谢您的帮助!

1个回答

5
使用 javap,我认为 JavaScript 类型test并不意味着生成的 Java 类型是这个类。生成的 Java 类型在其构造函数中调用脚本代码;这不会导致将addNumbers暴露为 Java 方法。
>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);
}

阅读行间,我认为你需要将类型映射到Java类型以实现你的目标。从jsc文档中可以看出:
- 实现java-intf-name 指定一个Java类来实现Java接口java-intf-name,该类从传入的JavaScript源文件生成。源文件中的每个全局函数都成为生成类的方法,并通过相同名称实现接口中的任何方法。
定义这个接口:
//Adder.java
public interface Adder {
  public int addNumbers(int a, int b);
}

写下这个实现:

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

使用参数-implements Adder AdderImpl.js编译JavaScript。像这样调用方法:
Adder adder = new AdderImpl();
int n = adder.addNumbers(1, 2);
System.out.println(n);

我猜这样做可能是因为不同语言的类型系统存在差异。
我使用了Rhino 1.7R2。为了简洁起见,我避免使用包等。

非常感谢您的帮助,它起作用了!我不需要担心准备上下文的事情,而是在实现类上使用“new”并只使用接口方法。太棒了! - Haesung
现在,如果您想将类百叶窗添加到最终编译的代码中,该怎么办? - TheRealChx101

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接