Data corruption with Nashorn + Handlebars and concurrent requests

A. Sundararajan sundararajan.athijegannathan at oracle.com
Mon May 25 07:56:24 UTC 2015


Hi,

Thanks for (near!) standalone test. I've further simplified -- copied 
all relevant scripts, removed testng dependency. Just a main class, 
Comment class and associated scripts. I've filed a nashorn bug to track 
this issue/thread:

https://bugs.openjdk.java.net/browse/JDK-8080975

I've attached a .zip file with the standalone program which I mentioned.

Now, even with loadWithNewGlobal, you're leaking Handlebars object to 
the new global - that is quite not an isolation. New global isolation 
will work only if you use simple data being passed (like string, numbers 
etc.). In your case, you're passing "Handlebars: object to the script 
executed in new global. And "compile" method of Handlebars object is 
called. That compile method is executed in the old global- i.e., it'd 
refer to global variables in which Handlebars object was picked from! We 
do *not* really know if handlebars.js is designed with concurrency in 
mind at all!! In other words, is handlebars library thread safe? For eg. 
if "compile" function uses any global variable, the variable is from 
that old global in which Handlebars object is defined. That is asking 
for trouble.

-Sundar

On Friday 22 May 2015 07:46 PM, Sebastien Deleuze wrote:
> Hi,
>
> I have added a very simple unit test, without any Spring Boot code, that
> reproduces the issue [1].
>
> Rendering concurrently templates with Mustache works as expected.
> Rendering concurrently templates with Handlebars generates the exceptions
> described previously, even if I use loadWithNewGlobal().
>
> Does that help you to find the issue?
> Is it the expected way to use loadWithNewGlobal() to avoid concurrency
> issues?
>
> Regards,
> Sébastien
>
> [1]
> https://github.com/sdeleuze/script-engine-test/blob/master/src/test/java/demo/NashornConcurencyIssueTests.java
>
> On Tue, May 12, 2015 at 6:49 PM, A. Sundararajan <
> sundararajan.athijegannathan at oracle.com> wrote:
>
>> Hi,
>>
>> Sorry for the delayed response.  It has been very difficult locating
>> anything in particular.
>>
>> Is it possible for you to reduce the test further? I think you'd in better
>> position because of the domain knowledge..
>>
>> Thanks,
>>
>> -Sundar
>>
>>
>> On Wednesday 06 May 2015 05:32 AM, Sebastien Deleuze wrote:
>>
>>> Hi,
>>>
>>> I currently try to implement support for Script based templating in Spring
>>> Framework [1] using Nashorn and template engines like Mustache or
>>> Handlebars.
>>>
>>> As discussed today on Twitter [2], I have some strange argument corruption
>>> issues when using Nashorn + Handlebars with concurrent request. I am aware
>>> of loadWithNewGlobal() but it seems I don't use it properly because I
>>> still
>>> see the issue using it.
>>>
>>> In order to make things simpler, I have created a repo project [3]. To
>>> make
>>> it work, simply execute TestApplication main class.
>>>
>>> MustacheJS seems to works with concurrent requests :
>>> ab -n 5000 -c 4 http://localhost:8080/mustache/
>>>
>>> But Handlebars seems to have some strange data corruption issues [4] (the
>>> template contains <title>{{title}}</title> but <title>{title}}</title> is
>>> printed in the log error message !!!) running both raw
>>> and loadWithNewGlobal() alternatives:
>>> ab -n 5000 -c 4 http://localhost:8080/handlebars/
>>> ab -n 5000 -c 4 http://localhost:8080/handlebars/newglobal/
>>> (the errors are displayed in the system output)
>>>
>>> Could you please have a look to this repro project in order to see if:
>>>    - There is a better way to use loadWithNewGlobal() (without the
>>> intermediate render() function maybe)
>>>    - If there is an issue in my code ?
>>>    - If there is an issue in Nashorn ?
>>>
>>> Running ab -n 5000 -c 1 http://localhost:8080/handlebars/ produces no
>>> error, so this is really related to concurrency.
>>>
>>> This is a feature we would like to ship with Spring Frameworks 4.2, so
>>> making it running flawlessly is mandatory for us, I hope it will be
>>> possible!
>>>
>>> Thanks in advance for your help,
>>> Sébastien Deleuze
>>>
>>> [1] https://jira.spring.io/browse/SPR-12266
>>> [2] https://twitter.com/sdeleuze/status/595586467298222082
>>> [3] https://github.com/sdeleuze/script-engine-test
>>> [4] jdk.nashorn.internal.runtime.ECMAException: Error: Parse error on line
>>> 3:
>>> ...ead>        <title>{title}}</title>
>>> ----------------------^
>>> Expecting 'EOF', 'COMMENT', 'CONTENT', 'END_RAW_BLOCK', 'OPEN_RAW_BLOCK',
>>> 'OPEN_BLOCK', 'OPEN_INVERSE', 'OPEN_INVERSE_CHAIN', 'INVERSE',
>>> 'OPEN_ENDBLOCK', 'OPEN', 'OPEN_UNESCAPED', 'OPEN_PARTIAL', got 'INVALID'
>>> at
>>>
>>> jdk.nashorn.internal.scripts.Script$\^eval\_$2._L36$_L874$_L880$parseError(<eval>:1025)
>>> at
>>>
>>> jdk.nashorn.internal.scripts.Script$\^eval\_$2._L36$_L874$_L880$parse(<eval>:1077)
>>> at
>>>
>>> jdk.nashorn.internal.scripts.Script$\^eval\_$4._L36$_L1910$parse(<eval>:1936)
>>> at
>>>
>>> jdk.nashorn.internal.scripts.Script$\^eval\_$5._L36$_L1944$compile$compileInput(<eval>:2396)
>>> at
>>>
>>> jdk.nashorn.internal.scripts.Script$\^eval\_$4._L36$_L1944$compile$_L2403(<eval>:2405)
>>> at
>>> jdk.nashorn.internal.scripts.Script$\^eval\_.renderHandlebars(<eval>:17)
>>> at
>>>
>>> jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:502)
>>>
>>



More information about the nashorn-dev mailing list