The class cache
rick.bullotta at thingworx.com
Wed Mar 12 11:15:29 UTC 2014
In Rhino, you would just inject the classes into a reusable ScriptableObject that provided a context that could be re-used across many executions. We would create a ScriptableObject, call initStandardObjects() on it, call putProperty to add class references and defineFunctionProperties to add new base functions, and then keep that resulting ScriptableObject and re-use it over and over again as the execution context.
Is there nothing analogous to this with Nashorn?
From: nashorn-dev <nashorn-dev-bounces at openjdk.java.net> on behalf of Tal Liron <tal.liron at threecrickets.com>
Sent: Wednesday, March 12, 2014 7:03 AM
To: nashorn-dev at openjdk.java.net
Subject: Re: The class cache
Ugh, you're right ...
Well, I do kinda have a hacky solution I could put in: implement my own
PrintWriter wrapper that uses a thread-local.
I think it would be better if stdout and stderr were in Global.
On 03/12/2014 07:00 PM, Rick Bullotta wrote:
> Tal, I don't think that would work in a multi-threaded environment, would it? Calling setEnv on the single instance of the class would be problematic if it was executing on multiple threads in multiple contexts, I'd think...
> From: nashorn-dev <nashorn-dev-bounces at openjdk.java.net> on behalf of Tal Liron <tal.liron at threecrickets.com>
> Sent: Wednesday, March 12, 2014 6:57 AM
> To: nashorn-dev at openjdk.java.net
> Subject: Re: The class cache
> This architecture is actually still problematic for me.
> My specific problem is that I define a different stdout and stderr per
> request. Because these are stored in the ScriptEnvironment in the
> Context, it means I also need a unique Context per request.
> Why not make it possible to use Context with multiple ScriptEnvironment
> instances? It seems that all that would be necessary is to add a setEnv
> method to the class.
> On 03/12/2014 06:30 PM, A. Sundararajan wrote:
>> Actually, the plan is to get to 8u20 - which is an update release
>> after jdk8 GA.
>> Script engine is associated with a single nashorn Context instance.
>> One nashorn Context instance may be associated with multiple nashorn
>> Global instances. The class sharing as of today is per global instance
>> - after Hannes' change, it'll be per Context instance (and so sharing
>> across all globals associated with a nashorn Context instance).
>> ScriptEnvironment._class_cache_size is set from --class-cache-size
>> option. Currently it is interpreted as per-global cache size. After
>> Hannes' change, it is per-Context class cache size.
>> On Wednesday 12 March 2014 03:28 PM, Tal Liron wrote:
>>> I did see that change come through, but I thought it was a JDK9
>>> feature... great to know it is for JDK8!
>>> I'll note that I'm not using ScriptEngine, but instead working on the
>>> Scripturian implementation. How will ScriptEngine make sure to reuse
>>> the cache?
>>> Would it be possible to also allow a shared ClassCache instance for
>>> all globals? How about a ScriptEnvironment._class_cache_size boolean
>>> option to enable this?
>>> On 03/12/2014 05:50 PM, Hannes Wallnoefer wrote:
>>>> Hi Tal,
>>>> I'm right now pushing a change for JDK-8021350 that allows sharing
>>>> script classes between global scopes. Currently, script classes are
>>>> bound to the global object in various ways, so the change is not
>>>> trivial, and it's not possible to share compiled scripts between
>>>> global scopes with the nashorn.jar in current JDK8 builds. The
>>>> script sharing feature is planned for the 8u20 release.
>>>> The class sharing will be per script engine, meaning that if you use
>>>> multiple scopes with one script engine classes will be reused, when
>>>> you use multiple script engines scripts will be recompiled for each
>>>> I'd be interested to know whether this would work for you. If you'd
>>>> like to test the class sharing feature I can help you getting started.
>>>> Am 2014-03-12 10:27, schrieb Tal Liron:
>>>>> In Nashorn, the ClassCache is set per Global instance.
>>>>> This is fine if your application has only one global instance.
>>>>> However, my application design involves creating many Global
>>>>> instances. (Actually, I create and destroy them on the fly per user
>>>>> request in an HTTP server scenario.) The problem is that all code
>>>>> has to constantly be recompiled, and the cache is essentially never
>>>>> used. Since recompilation is so very expensive in Nashorn, this
>>>>> results in awful performance.
>>>>> How can I implement a shared ClassCache? I can't extend and modify
>>>>> Global behavior, because it's a final class.
>>>>> I've tried to cache ScriptFunction instances myself, but I get
>>>>> exceptions when I try to run them with a different Global instance
>>>>> than the one that created them.
More information about the nashorn-dev