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