Running Nashorn under java.lang.instrument

David P. Caldwell david at code.davidpcaldwell.com
Tue Oct 14 15:07:03 UTC 2014


OK, I actually have this "working" (not crashing) now. I did not have
to update my JDK.

The main impediment I actually had was the Nashorn is loaded in the
extension class loader, and java.lang.instrument-loaded agents are
loaded in the application class loader.

So in order to get my profiler to work, I have to load it as an
extension (i.e., add its location to the java.ext.dirs property). This
way the instrumented Nashorn classes can "see" the classes in the
agent and invoke them in order to generate profiling data.

This doesn't seem ideal but I am not familiar enough with advanced
javaagent implementation or bytecode manipulation to know whether
there's a better way to approach this.

In any case, my original question was about the ability to profile
Nashorn applications. So I'll return to that. Right now my profiler
emits lots of trees like this:

            elapsed=38 calls=1
jdk.nashorn.internal.scripts.Script$api_rhino L:34
(Ljdk/nashorn/internal/runtime/ScriptFunction;Ljava/lang/Object;)Ljava/lang/Object;
              elapsed=36 calls=0 (self)
              elapsed=2 calls=58
jdk.nashorn.internal.scripts.Script$api_rhino :scopeCall
(Ljdk/nashorn/internal/runtime/ScriptObject;ILjava/lang/Object;)Ljava/lang/Object;
              elapsed=0 calls=1
jdk.nashorn.internal.scripts.Script$api_rhino :getMap
(I)Ljdk/nashorn/internal/runtime/PropertyMap;
            elapsed=14 calls=1
jdk.nashorn.internal.scripts.Script$api_rhino L:58
(Ljdk/nashorn/internal/runtime/ScriptFunction;Ljava/lang/Object;)Ljava/lang/Object;
              elapsed=11 calls=1
jdk.nashorn.internal.scripts.Script$api_rhino L:58$L:59
(Ljdk/nashorn/internal/runtime/ScriptFunction;Ljava/lang/Object;)Ljava/lang/Object;
                elapsed=8 calls=1
jdk.nashorn.internal.scripts.Script$=nashorn!mozilla_compat L:52$L:56
(Ljdk/nashorn/internal/runtime/ScriptFunction;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
                  elapsed=4 calls=1
jdk.nashorn.internal.scripts.Script$engine L:35
(Ljdk/nashorn/internal/runtime/ScriptFunction;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
                  elapsed=4 calls=0 (self)
                elapsed=3 calls=0 (self)
                elapsed=0 calls=1
jdk.nashorn.internal.scripts.Script$api_rhino L:58$L:59$L:67
(Ljava/lang/Object;)Ljava/lang/Object;
                elapsed=0 calls=1
jdk.nashorn.internal.scripts.Script$api_rhino :getMap
(I)Ljdk/nashorn/internal/runtime/PropertyMap;
              elapsed=2 calls=1
jdk.nashorn.internal.scripts.Script$api_rhino L:23
(Ljdk/nashorn/internal/runtime/ScriptFunction;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
              elapsed=1 calls=0 (self)

... and I am still trying to figure out how to translate those into
something that would be useful to application developers attempting to
do CPU profiling of their code.

If anyone has guidance or pointers on how I might pick apart the above
inside my Java agent, I'd be grateful!

-- David P. Caldwell
http://www.davidpcaldwell.com/

On Tue, Oct 14, 2014 at 7:18 AM, David P. Caldwell
<david at code.davidpcaldwell.com> wrote:
> Part of the issue is that I was incorrect that Nashorn would be loaded
> by the system class loader; it is actually loaded by the extensions
> class loader, so my code will indeed attempt to instrument Nashorn
> itself. I don't know whether that should work or not, but it's not
> what I was trying to do, so I'm going to continue debugging and will
> report back if and as I find useful things.
>
> On Mon, Oct 13, 2014 at 5:37 PM, David P. Caldwell
> <david at code.davidpcaldwell.com> wrote:
>> So if I run Nashorn under a Java agent, I can't start it. I haven't
>> yet dug into the error, but when I invoke:
>>
>> return new ScriptEngineManager().getEngineByName("nashorn") != null
>>
>> , which is my "is Nashorn installed" check, the following prints to System.err:
>>
>> ScriptEngineManager providers.next():
>> javax.script.ScriptEngineFactory: Provider
>> jdk.nashorn.api.scripting.NashornScriptEngineFactory could not be
>> instantiated
>>
>> Does anyone immediately know what would be wrong?
>>
>> My Transformer in the class does this:
>>
>> if (protectionDomain == null) return null;
>>
>> ... so it shouldn't be attempting to transform any Nashorn classes.
>>
>> On the other hand, if it's relevant, the ClassLoader that loaded the
>> class above that executes return new ScriptEngineManager() ... is not
>> loaded by the system class loader; it's loaded by an URLClassLoader
>> that sits on top of that (it does delegate to the system class
>> loader). Under normal circumstances, this wouldn't make a difference,
>> but just in case ...
>>
>> Anyone immediately have an idea what I might be dealing with here?
>>
>> -- David P. Caldwell
>> http://www.davidpcaldwell.com/


More information about the nashorn-dev mailing list