Nashorn and AsciidoctorJs

A. Sundararajan sundararajan.athijegannathan at
Mon Jul 28 07:54:27 UTC 2014


Each unique ENGINE_SCOPE Bindings either (a) wraps a Nashorn/ECMAScript 
'global' instance or (b) is associated with a Nashorn/ECMAScript 
'global' instance. There is also a default ScriptContext with it's own 
ENGINE_SCOPE bindings - which is a wrapper over a (default) 
nashorn/ecmascript 'global' instance.

ECMAScript global instance is where all your function and variable 
definitions ("function func() {...} and var c =... ") go.

Invocable's invokeFunction, invokeMethod and getInterface methods look 
for backing scripting functions in ENGINE_SCOPE of script engine's own 
Script Context (you can get/set that by ScriptEngine.getContext, 
ScriptEngine.setContext methods).

In your test, you seem to evaluate code in a (non-default) ScriptContext 
and then set that as engine's default context - which is right.  The 
following simple example works for me:

import javax.script.*;

public class Test {
   public static void main(String[] args) throws Exception {
     ScriptEngineManager m = new ScriptEngineManager();
     ScriptEngine e = m.getEngineByName("nashorn");

     SimpleScriptContext sctxt = new SimpleScriptContext();
     Bindings b = new SimpleBindings();
     sctxt.setBindings(b, ScriptContext.ENGINE_SCOPE);

     e.eval("function run() { print('hello') }", sctxt);
     Runnable r = ((Invocable)e).getInterface(Runnable.class);;

Please check the following:

* you've corresponding global function definitions to implement 
AsciidoctorJs (in that SimpleScriptContext). Per spec. getInterface may 
return null if method definitions are missing.

* What is the version of Java you use? Is there a default method in 
AsciidoctorJs interface? There was a bug regarding interfaces with 
default methods ( 8031359: Invocable.getInterface() works incorrectly if 
interface has default methods - This was fixed in 8u20.

If everything fails, please file a bug with all info. needed to 
reproduce the bug + stack trace + JDK/OS version information.

Hope this helps,

On Saturday 26 July 2014 05:32 PM, Alex Soto wrote:
> Hi guys,
> currently I am working on integrating Asciidoctor to Java using Nashorn and
> Opal. Nowadays we have got an asciidoctor java running above JRuby.
> Apart from Asciidoctor java we also have an asciidoctorjs which is created
> using Opal (a gem to convert Ruby programs to JavaScript).
> So next step is to integrate this js to java using nashorn. But we are
> having one problem.
> I have created a project with a test so you can take a look as well:
> The test is located at
> (although it is called Rhino currently we are using Nashorn).
> If I create an script engine an I use the eval method everywhere it works
> perfectly but because I would like to use some more typesafe approach I
> decided to create an interface mirroring some asciidoctor operations so I
> call invocable.getInterface(AsciidoctorJs.class) to create the proxied
> instance and then I call defined methods.
> This interface mimics the js asciidoctorjava.js which internally calls
> asciidoctor.js operations. This is done because I only want some operations
> available from Java part, not the whole operations that asciidoctor.js
> offers.
> asciidoctorjava.js looks like:
> var render = function(content, optionsHash2) {
>      return Opal.Asciidoctor.$render(content, optionsHash2);
> };
> The problem is that when I run the test an exception is thrown notifying
> that Opal.Asciidoctor.$render is not found. If I change that line to:
>   var render = function(content, optionsHash2) {
>      return "Hello World";
> };
> then it works so it seems that Nashorn don't load the asciidoctor.js but
> this is not exactly true because if I execute the same operation but using
> eval method it works.
> Probably I am missing something in the creation of proxied interface, but
> currently I cannot see what.
> Any idea on why this happens?
> Thank you so much for your help in advance.
> Alex.

More information about the nashorn-dev mailing list