【问题标题】:Run Javascript code with export function in Java with Nashorn使用 Nashorn 在 Java 中运行带有导出功能的 Javascript 代码
【发布时间】:2019-02-02 06:12:06
【问题描述】:

是否可以使用 Nashorn 在 Java 中运行包含导出函数的 Javascript 代码?我是 Nashorn 的新手,所以我不确定 js 代码是否有限制。另外,如何将参数从 Java 传递给 js 代码?

Javascript 代码如下所示(取自here):

/** Given two circles (containing a x/y/radius attributes),
returns the intersecting points if possible.
note: doesn't handle cases where there are infinitely many
intersection points (circles are equivalent):, or only one intersection point*/
function circleCircleIntersection(p1, p2) {
    var d = distance(p1, p2),
        r1 = p1.radius,
        r2 = p2.radius;

    // if to far away, or self contained - can't be done
    if ((d >= (r1 + r2)) || (d <= Math.abs(r1 - r2))) {
        return [];
    }

    var a = (r1 * r1 - r2 * r2 + d * d) / (2 * d),
        h = Math.sqrt(r1 * r1 - a * a),
        x0 = p1.x + a * (p2.x - p1.x) / d,
        y0 = p1.y + a * (p2.y - p1.y) / d,
        rx = -(p2.y - p1.y) * (h / d),
        ry = -(p2.x - p1.x) * (h / d);

    return [{x: x0 + rx, y : y0 - ry },
            {x: x0 - rx, y : y0 + ry }];
}

/** Returns the center of a bunch of points */
function getCenter(points) {
    var center = {x: 0, y: 0};
    for (var i =0; i < points.length; ++i ) {
        center.x += points[i].x;
        center.y += points[i].y;
    }
    center.x /= points.length;
    center.y /= points.length;
    return center;
}

作为一个例子,我想通过使用代码提供多个点来调用 js 中的 getCenter 函数:

    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    //      engine.eval("print('Hello World!');");
    engine.eval(new FileReader("circleintersection.js"));

    Invocable invocable = (Invocable) engine;

    Point a = new Point(3,2);
    Point b = new Point(5,3);
    Point c = new Point(1,4);
    Point d = new Point(2,5);
    Point e = new Point(6,6);

    Point[] points = {a,b,c,d,e};

    Point result = (Point) invocable.invokeFunction("getCenter", points);
    System.out.println(result.x);

但它给了我这样的错误

线程“主”java.lang.ClassCastException 中的异常: jdk.nashorn.api.scripting.ScriptObjectMirror 无法转换为 Point

如何从js代码中得到结果?

【问题讨论】:

  • 是否可以使用 Nashorn 从 Java 调用 Javascript 函数?是的。但export 与此无关。您需要ScriptEngine,然后您可以eval 调用您的函数或获取Invocable 来调用您的函数。
  • @ElliottFrisch 所以不管是导出函数还是普通函数,只要我用 ScriptEngine 调用函数本身?
  • 加载 js 函数的同一脚本引擎。不仅仅是任何脚本引擎。

标签: javascript java nashorn


【解决方案1】:

Nashorn 不完全支持 ECMA6 功能,导出是其中之一,不受支持。

参考资料:

ECMA 6 support in Nashorn

http://openjdk.java.net/jeps/292

它开始支持 JDK8 本身的一些,以及 JDK 9 中的一些。但我找不到它支持 export 的证据。

另外,如何将参数从 Java 传递给 js 代码? 如果你有以下功能

var fun1 = function(name) {
    print('Hi there from Javascript, ' + name);
    return "greetings from javascript";
};

var fun2 = function (object) {
    print("JS Class Definition: " + Object.prototype.toString.call(object));
};

那么,你就可以了,

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(new FileReader("script.js"));

Invocable invocable = (Invocable) engine;

Object result = invocable.invokeFunction("fun1", "Peter Parker");
System.out.println(result);
System.out.println(result.getClass());

// Hi there from Javascript, Peter Parker
// greetings from javascript
// class java.lang.String

这取自https://winterbe.com/posts/2014/04/05/java8-nashorn-tutorial/

【讨论】:

  • 如果我只是删除导出以便它只是一个正常功能可以吗?
  • 我已经尝试过你的代码,但它仍然给我错误,请查看我的代码实现的更新问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多