2

Is it possible to run a Javascript code containing export functions in Java with Nashorn? I'm new in Nashorn so I am not sure whether there is restriction for the js code to have. Also how do I pass the arguments from Java to the js code?

The Javascript code looks like this (taken from 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;
}

As an example I would like to invoke getCenter function in the js by supplying multiple Points using the code:

    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);

But it gave me error like

Exception in thread "main" java.lang.ClassCastException: jdk.nashorn.api.scripting.ScriptObjectMirror cannot be cast to Point

How can I get the result from the js code?

3
  • Is it possible to call a Javascript function from Java using Nashorn? Yes. But export has nothing to do with it. You'll need the ScriptEngine and then you can either eval to call your function or get an Invocable to call your function. Commented Aug 27, 2018 at 17:04
  • @ElliottFrisch so it doesn't matter if it is export function or normal function as long as I call the function itself with ScriptEngine? Commented Aug 27, 2018 at 17:06
  • The same scriptengine that loaded the js functions. Not just any scriptengine. Commented Aug 27, 2018 at 17:12

1 Answer 1

2

Nashorn does not fully support ECMA6 features and export is one of them and not supported.

References:

ECMA 6 support in Nashorn

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

It started to support some from JDK8 itself, and some in JDK 9. But I couldn't find evidence of it supporting export.

Also how do I pass the arguments from Java to the js code? If you have the following function

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

Then, you can do,

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

This was taken from https://winterbe.com/posts/2014/04/05/java8-nashorn-tutorial/

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

2 Comments

will it be ok if i just remove the export so that it is only a normal function?
I already tried your code but it still gave me error, please take a look at the updated question for my code implementation

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.