Nashorn's javax.script.ScriptEngineFactory produces wrong code

Edmond Kemokai ekemokai at
Sat Jan 7 14:02:32 UTC 2017

Ah, I see your point.

I'll say file a bug. If you look at the,
you'll see that it simply concatenates the supplied string between a print
statement, the current implementation requires proper escaping of input.

On Jan 7, 2017 8:52 AM, "Rony G. Flatscher" <Rony.Flatscher at> wrote:

Hi Ed,

On 06.01.2017 17:49, Edmond Kemokai wrote:

The issue seems to go away after I quote the string.

If you supplied a Javascript encoded string to the Nashorn
ScriptEngineFactory.getOutputStatement() you removed the cause of
demonstrating that Nashorn ScriptEngineFactory creates wrong output

The problem is that Nashorn's ScriptEngineFactory.getOutputStatement() does
not analyze the received string (which may be any sequence of characters)
to see whether escaping needs to take place (e.g. containing quotes or
backslashes) and finally enquoting the received (maybe escape processed)
string to make it acceptable as an argument to its print() function!

The task at hand is to create an output statement that will be able to
output the received string as is (no matter what the string contains),
character by character!


Background: the JSR-223/javax.script package was *not* created with a
specific scripting language in mind. A scripting factory cannot assume that
a supplied string adheres to the specific rules of that particular
scripting language. The getOutputStatement() method is there to get an
output statement adhering to the syntax rules of the script language that
outputs (shows) the string exactly as received, character by character!
Each script language may have different syntax, escaping rules etc.,
therefore the ScriptEngineFactory knowing its ScriptEngines syntax and
rules is asked to create a proper output statement.

It is the script factory's responsibility to analyze the received string
and to escape characters in order to have the script engine output the
string exactly as received, character by character.

To test this, my test program feeds any available javax.script language
with a string containing quotes around the script engine name (to test
quote escaping) and has the script engine take its own medicine by
executing the returned output statement.

In the case of Nashorn the script engine is not able to reliably run the
output statement generated by its own ScriptEngineFactory!

So, if getOutputStatement() receives the following string value to output:

abc "def" ghi

it needs to analyze and in this case escape the string first to match the
rules of JavaScript:

abc \"def\" ghi

and then produce the output statement by enquoting the escaped string:

print("abc \"def\" ghi")

This way, this statement can be run correctly by Nashorn and it gives
exactly the received string as output:

abc "def" ghi

Also in the case of Nashorn/Javascript I would add a trailing '\n'
character as usually script engine's output statements supply a trailing
new line character. However, this is not defined/mandated and left to the


P.S.: The Rexx/ooRexx ScriptEngineFactory would create the following output
statement and be able to successfully run it, yielding exactly the string
that was supplied to getOutputStatement():

say "abc ""def"" ghi"

running that statement yields the output:

abc "def" ghi

(The Rexx/ooRexx language escapes quotes in strings by doubling them.)

You can run the code in the browser by right clicking and choosing "Test"
then click "Run". On the top right, click the dropdown button and choose
"Log Viewer" to see the output.


INFO  Invocation                     - ---> language [ECMAScript]:

INFO  Invocation                     -     1) output statement to process:
"hello world, this is ECMAScript speaking! "

INFO  Invocation                     -     --> testing
INFO  Invocation                     - , produced the following
[ECMAScript] output statement

print("hello world, this is ECMAScript speaking! ")

INFO  Invocation                     -     ... now running "eval(code)"
using the scripting engine [ECMAScript]:

INFO  Invocation                     -

INFO  Invocation                     -     2) testing
getMethodCallSyntax(obj, meth, arg...)
INFO  Invocation                     - , produced the following
[ECMAScript] method call statement:


INFO  Invocation                     -     3) testing getProgram(String...)
INFO  Invocation                     -  produced the following [ECMAScript]

print("hello world, this is ECMAScript speaking!

INFO  Invocation                     - <--- end of testing language
[ECMAScript]. <----------------------------------------

On Fri, Jan 6, 2017 at 10:21 AM, Rony G. Flatscher <Rony.Flatscher at>

> Hi Ed,
> On 06.01.2017 16:07, Edmond Kemokai wrote:
> I am the developer of HiveMind, it is a web app platform that relies
> entirely on scripting engines via JSR-223.
> You can access a demo instance:
> Login with: developer/developer
> I have created a test file in: /com/crudzilla/cloudTest/web/r
> ony-groovy.ste
> Put your code (the original one you pasted) in there and save, I'll take a
> look to see what might be missing.
> Done.
> After compiling just run it as "java RunScript" (make sure your CLASSPATH
> picks up the directory that contains RunScript.class, which does not define
> any package name, e.g. "."). It will list all JSR-223 scripting languages
> on your system and give the help. E.g. currently on my Windows system:
> F:\work\svn\bsf4oorexx\trunk\samples\Java\javax.script>java RunScript
> The following javax.script engines are currently available:
>         ECMAScript
>         ooRexx
> usage: java RunScript [{-i | -t | -e enginename filename [args...] |
> filename [args...]}]
>           ... no arguments lists the available javax.script engines
>        -h ... 'help', gives this usage text
>        -i ... lists the available javax.script engines and informs about
> their properties
>        -t ... lists the available javax.script engines and tests
> evaluating their "getOutputStatement(String)" method
>        -e  enginename filename [args...] ... uses "enginename" to evaluate
> "filename" supplying the arguments "args..."
>        filename [args...] ... the "filename" extension determines the
> script engine to evaluate it, supplying the arguments "args..."
> Running with the "-t" switch tests the code generated by the script
> engine's factories by letting it eval()'ed.
> ---rony
> On Fri, Jan 6, 2017 at 9:07 AM, Rony G. Flatscher <Rony.Flatscher at
> > wrote:
>> Besides Java 1.8.0_111 the problem exists in 9ea-+134 (engine version:
>> "9ea", language version:
>> "ECMA 262 - Edition 5.1" ) as well: Nashorn's javax.script factory is
>> used to get an output
>> statement and then it is used to execute it:
>>     ---> language [ECMAScript]: ---------------------------------------->
>>             1) output statement to process: hello world, this is
>> "ECMAScript" speaking!
>>             --> testing getOutputStatement(String), produced the
>> following [ECMAScript] output statement
>>     print(hello world, this is "ECMAScript" speaking! )
>>             ... now running "eval(code)" using the scripting engine
>> [ECMAScript]:
>>     javax.script.ScriptException: <eval>:1:12 Expected , but found world
>>     print(hello world, this is "ECMAScript" speaking! )
>>                 ^ in <eval> at line number 1 at column number 12 while
>> eval() the code: print(hello
>>     world, this is "ECMAScript" speaking! )
>> This time trying to not format the Java code, so hopefully the mailer
>> will not render it illegible:
>>     ... cut ...
>>       // create an output statement and execute output statement with the
>> script engine
>>         static void testEngine(String name, ScriptEngineFactory sef,
>> ScriptEngine se)
>>         {
>>             System.out.println("---> language ["+name+"]:
>> ---------------------------------------->\n");
>>             String text="hello world, this is \""+name+"\" speaking! ";
>>             String code=sef.getOutputStatement(text);
>>             System.out.println("\t1) output statement to process:
>> "+text+"\n");
>>             System.out.print("\t--> testing getOutputStatement(String)");
>>             System.out.println(", produced the following ["+name+"]
>> output statement \n\n"+code+"\n");
>>             System.out.println("\t... now running \"eval(code)\" using
>> the scripting engine
>>     ["+name+"]: \n\n");
>>             try
>>             {
>>                 se.eval(code);
>>                 System.out.println("\n");
>>             }
>>             catch (ScriptException sexc)
>>             {
>>                 System.err.println(sexc+" while eval() the code:
>> "+code+"\n");
>>             }
>>             System.out.print("\t2) testing getMethodCallSyntax(obj, meth,
>> arg...)");
>>             String methCode=sef.getMethodCallSyntax("object", "method",
>> "arg1", "arg2");
>>             System.out.println(", produced the following ["+name+"]
>> method call statement:
>>     \n\n"+methCode+"\n");
>>             System.out.print("\t3) testing getProgram(String...)");
>>             String programCode=sef.getProgram(code, methCode);
>>             System.out.println(" produced the following ["+name+"]
>> program: \n\n"+programCode+"\n");
>>             System.out.println("<--- end of testing language ["+name+"].
>>     <----------------------------------------\n");
>>         }
>>     ... cut ...
>> If I should file a bug then please advise where and how.
>> ---rony
>> On 08.12.2016 16:17, Rony G. Flatscher wrote:
>> > Unfortunately, the mailing list seems to behave as if it was running in
>> the 1970's such that the
>> > formatted text (indented, partially colorized and formatted to
>> preformat and Courier) has turned to
>> > become illegible, unfortunately (using the Thunderbird e-Mail client)!
>> > :(
>> >
>> > The meat is right in the first two paragraphs and the last paragraph
>> before the signature. Should
>> > anyone be interested in the Java-utility, please drop me a personal
>> e-mail and I will send that Java
>> > program as an attachment to you.
>> >
>> > ---rony
>> >
>> >

More information about the nashorn-dev mailing list