<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<p>Hello!</p>
<p><br>
</p>
<p>I am working on porting a rather large code base from nashorn to graal.js. The original code was using javax.script.ScriptEngine. I would like to replace it by the polyglot Context API if possible<br>
</p>
<pre><code> private ScriptEngine engine =
new ScriptEngineManager().getEngineByName("nashorn");
</code></pre>
<p>I have decided to replace the ScriptEngine with the polyglot Context API.</p>
<pre><code>private Context cx = Context.newBuilder().allowAllAccess(true).allowHostAccess(HostAccess.ALL).build();
</code></pre>
<p>I replaced every call to engine.put() with a call to cx.getBindings("js").putMember() and similarly engine.get() with cx.getBindings("js").getMember() like this:</p>
<pre><code>cx.getBindings("js").putMember("mote", mote);
cx.getBindings("js").putMember("id", id);
//engine.put("mote", mote);
//engine.put("id", id);
</code></pre>
<p>I also replaced the engine.eval() call with a cx.eval() call. However, there is one place in the code where I cannot get rid of the engine. The engine is cast as an Invocable and runs a Thread in a thread group:</p>
<pre><code>scriptThread = new Thread(group, new Runnable() {
public void run() {
try {
((Invocable)engine).getInterface(Runnable.class).run();
} catch (RuntimeException e) {
Throwable throwable = e;
while (throwable.getCause() != null) {
throwable = throwable.getCause();
}
if (throwable.getMessage() != null &&
throwable.getMessage().contains("test script killed") ) {
logger.info("Test script finished");
} else {
if (!Cooja.isVisualized()) {
logger.fatal("Test script error, terminating Cooja.");
logger.fatal("Script error:", e);
System.exit(1);
}
logger.fatal("Script error:", e);
deactivateScript();
simulation.stopSimulation();
if (Cooja.isVisualized()) {
Cooja.showErrorDialog(Cooja.getTopParentContainer(),
"Script error", e, false);
}
}
}
/*logger.info("test script thread exits");*/
}
});
scriptThread.start(); /* Starts by acquiring semaphore (blocks) */
while (!semaphoreScript.hasQueuedThreads()) {
Thread.yield();
}
</code></pre>
<p>This is the part I would like to change:</p>
<pre><code> ((Invocable)engine).getInterface(Runnable.class).run();
</code></pre>
<p>Is there a Context equivalent for this? I could not find any documentation regarding Invocables in the Context API. I have, however, read somewhere that it I should use Context to execute JavaScript code when using GraalVM. So my question is, is there a
way to change this piece of code, so that it keeps its functionality but I don't have to use the engine anymore and use the Context API instead? If not, what would be a good way to do it?</p>
<p><br>
</p>
<p>Thanks in advance.</p>
<p><br>
</p>
<p>Best regards,<br>
</p>
<p> Katarina<br>
</p>
<br>
</div>
</body>
</html>