Как вызвать скомпилированные Rhino методы JavaScript (файлы классов) в программе Java?

Я скомпилировал следующий файл JavaScript «test.js» в «test.class»:

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

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

  return that;
}());

Я хотел бы вызвать скомпилированную функцию JavaScript "test.addNumbers(1,2)" в простой программе Java "run.java" следующим образом:

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 и изучил множество статей и примеров, НО они только показывают, как вызывать методы JavaScript из командной строки или исходного файла «test.js». Мне нужно вызвать метод из скомпилированного файла "test.class".

Заранее большое спасибо за вашу помощь!


person Haesung    schedule 20.02.2011    source источник


Ответы (1)


Используя 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:

-implements 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;
}

Скомпилируйте JavaScript с аргументами -implements Adder AdderImpl.js. Вызовите метод следующим образом:

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

Рискну предположить, что, вероятно, это было необходимо сделать из-за различий в системах типов языков.

Я использовал Rhino 1.7R2. Для краткости я избегал использования пакетов и т. д.

person McDowell    schedule 20.02.2011
comment
Большое спасибо за помощь, все работает! Мне не нужно беспокоиться о подготовке контекстных вещей, вместо этого я новичок в классе реализации и просто использую методы интерфейса. Фантастический! - person Haesung; 21.02.2011
comment
Теперь, что, если вы хотите добавить затворы классов в окончательный скомпилированный код. - person TheRealChx101; 02.08.2018