Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [wtp-dev] Nashorn Debugging

Max and Michael,

thanks for your feedback and advice so far. I'll be happy to submit Bugzilla issues and share my code, though not before next Tuesday, as I'll be away for a while. Sharing the code might take a bit longer, I'm mainly kicking tyres at the moment, so I'd like to clean things up first.

I'm working with Luna SR1 at the moment, using the latest JSDT sources from Git in my workspace. (I.e. JDT is from Luna SR1.)

I have some standalone tests (i.e. not using Eclipse) launching a Java VM with a simple Java/Nashorn/_javascript_ class via JDI and settings breakpoints and inspecting Nashorn classes directly via the JDI API. The script classes only have the default Java stratum - it would be interesting to know why Nashorn developers did not add a JS stratum, they probably had a reason for that. So I don't think upgrading to a Mars snapshot would make a big difference in this respect.

Anyway, via DebuggerSupport, you can obtain SourceInfo for each script class, and this is enough to map the line numbers from the Java stratum to the _javascript_ source files.

The point with the wildcard ClassPrepareBreakpoint is: Nashorn generates one or more Java classes from each JS source file, it seems there is at least one additional class per JS function. The class names satisfy the naming pattern jdk.nashorn.internal.scripts.Script$*, but there is no way to determine the suffixes beforehand, so the easiest way of implementing something like a ScriptLoad breakpoint is to use a ClassPrepareBreakpoint for this pattern and to expect this to be triggered multiple times per script file, each class contributing a couple of Locations from the given file.

This works fine in my stand-alone test. With JDT, I can set the breakpoint, but my breakpoint listener does not get called, since the JDI event handler compares class names by equals() and does not fire a breakpoint event for the pattern match.

Regards,
Harald


2015-03-18 16:17 GMT+01:00 Michael Rennie <Michael_Rennie@xxxxxxxxxx>:

> Yes, that's just the stuff I'd found out for so far (i.e. DebuggerSupport according to JDK-8044798), see my first message. I've also looked at NetBeans sources to get an understanding of > how to gather of script source line info by tracking ClassPrepare events for jdk.nashorn.internal.scripts.Script* classes. That looks like the easier part of the story.

This is pretty much the same way the JSDT works (for Rhino anyways). We listen for script compilation events and build up a model / line infos / etc. on the fly.

For specific examples have a look at the following bundle:

http://git.eclipse.org/c/jsdt/webtools.jsdt.git/tree/bundles/org.eclipse.wst.jsdt.debug.rhino.debugger

> The harder part (at least for me) is how to fit this into the JDT and JSDT design. (I'm familiar with Eclipse plugin development in general, but not really with J(S)DT details.)

In JSDT the design basically has you provide a way to launch the backend, the connector to talk to it, and you get the UI for *free*. See the *.rhino or *.crossfire bundles in JSDT for examples.

In JDT we support Java and debugging in the VM via JDI and alternate stratums - we do not have any code in the Java debugger for specific languages other than Java.
 
> So far, I've created an alternative NashornLaunchDelegate for the standard Java debug launcher to create extra breakpoints for DebuggerSupport and Script* classes in the

> JDIDebugTarget. This should eventually let me step from Java into _javascript_ code invoked from a plain old Java application via ScriptEngine. 

Your idea sounds like a really good place to start, but I am surprised this doesn't "just work" with JDI and alternate strata. Perhaps the classfiles created do not properly create an alternate strata that JDI can use, or JDT debug has more bugs in it?

Which version of Eclipse are you developing / testing this against? The Xtext/Xtend folks provided a lot of fixes around alternate
strata in the Java debugger in Mars, which might help here.

> (Directly launching a *.js source like jjs does would be a different story, which I'm not considering for now.)

This would probably be very similar to: http://git.eclipse.org/c/jsdt/webtools.jsdt.git/tree/bundles/org.eclipse.wst.jsdt.debug.rhino.debugger/src/org/eclipse/wst/jsdt/debug/rhino/debugger/shell/DebugMain.java

Can you open a bug in JSDT debug about direct Nashorn debugging? It would be good to have support for this built right in.


> There were two issues:
> - JavaClassPrepareBreakpoint does not handle wildcards in class names. I had to extend this class.


This should be simple enough to fix. Can you open a bug in JDT debug for this?

> - ReferenceType.allLineLocations() throws an AbsentInformationException when at least one of the methods of the type has no line info. The JDK implementation returns all line info

> that's available and only throws an exception when NONE of the methods have line locations. The JDI Javadoc is a bit vague about this, but I would consider this as a JDT bug. (The
> point is that the Script* classes generated by Nashorn do contain line locations only for those methods corresponding to _javascript_ functions or top-level scripts, and there are some
> other methods without line info.) As a workaround, I iterate over the methods myself.

This also sounds wrong. Can you open another bug (in JDT debug) for this as well?


> Now my next idea is to create a new IJavaScriptDebugTarget implementation which delegates to the JDIDebugTarget, transforming _javascript_ debugger commands/events to JDI
> commands and events and vice versa. Does this make sense?

That sounds like a cool idea.

I have not tried debugging in Nashorn yet (with JDI or otherwise),  so I can't say for sure why it doesn't work as-is (with JDI and the standard Java debug target), but it really feels to me like it should.

Have you tried debugging through the JDI code to confirm your suspicion about there only being a Java strata?

Perhaps throw a breakpoint in ReferenceTypeImpl#allLineLocations around line 1991 to see what stratum ID it asks for / thinks it has (using a normal JDI connection)?

Michael Rennie

Inactive hide details for Harald Wellmann ---17/03/2015 06:17:58 AM---Yes, that's just the stuff I'd found out for so far (i.e.Harald Wellmann ---17/03/2015 06:17:58 AM---Yes, that's just the stuff I'd found out for so far (i.e. DebuggerSupport according to JDK-8044798),

From: Harald Wellmann <hwellmann.de@xxxxxxxxx>
To: "General discussion of project-wide or architectural issues." <wtp-dev@xxxxxxxxxxx>
Date: 17/03/2015 06:17 AM
Subject: Re: [wtp-dev] Nashorn Debugging
Sent by: wtp-dev-bounces@xxxxxxxxxxx





Yes, that's just the stuff I'd found out for so far (i.e. DebuggerSupport according to JDK-8044798), see my first message. I've also looked at NetBeans sources to get an understanding of how to gather of script source line info by tracking ClassPrepare events for jdk.nashorn.internal.scripts.Script* classes. That looks like the easier part of the story.

The harder part (at least for me) is how to fit this into the JDT and JSDT design. (I'm familiar with Eclipse plugin development in general, but not really with J(S)DT details.)

So far, I've created an alternative NashornLaunchDelegate for the standard Java debug launcher to create extra breakpoints for DebuggerSupport and Script* classes in the JDIDebugTarget. This should eventually let me step from Java into _javascript_ code invoked from a plain old Java application via ScriptEngine.  (Directly launching a *.js source like jjs does would be a different story, which I'm not considering for now.)


There were two issues:

- JavaClassPrepareBreakpoint does not handle wildcards in class names. I had to extend this class.

- ReferenceType.allLineLocations() throws an AbsentInformationException when at least one of the methods of the type has no line info. The JDK implementation returns all line info that's available and only throws an exception when NONE of the methods have line locations. The JDI Javadoc is a bit vague about this, but I would consider this as a JDT bug. (The point is that the Script* classes generated by Nashorn do contain line locations only for those methods corresponding to _javascript_ functions or top-level scripts, and there are some other methods without line info.) As a workaround, I iterate over the methods myself.


Now my next idea is to create a new IJavaScriptDebugTarget implementation which delegates to the JDIDebugTarget, transforming _javascript_ debugger commands/events to JDI commands and events and vice versa. Does this make sense?

Regards,
Harald



2015-03-17 11:37 GMT+01:00 Max Rydahl Andersen <manderse@xxxxxxxxxx>:
    Okey, so I reached out to netbeans guys and he confirmed to me it is really underdocumented, but
    apparently the DebuggerSupport class is part of the key and the only known public documentation for it
    is in this example:
    https://github.com/wickund/nashornexamples

    this is showing how a debugger can connect to nashorn over the debug protocol.

    Interested in picking up that challenge ?


    /max


      On 15 Mar 2015, at 9:27, Harald Wellmann wrote:
        Yes, it's a normal JDI connection. And it doesn't "just work", I'm afraid,
        nor do I see why it might. I don't know how it works with JSPs. Do compiled
        JSP classes contain a stratum with JSP line info?

      Yes, the sourcelocation info on class'es would have a filename:linenumber piece of info.
        Nashorn script classes
        only contain a Java stratum, as far as I can tell.

      Yeah, I tried googling and apparently nashorn doesn't fit as smooth as rhino did.

      I'm still looking and will ask around but I did find this jira:
      https://bugs.openjdk.java.net/browse/JDK-8044798
      which talks about jdk.nashorn.internal.runtime.DebuggerSupport  being what is supposed to be used
      for external debuggers.

      I think thats what netbeans/intellij uses - but i'm not sure.

      /max

        Regards,
        Harald


        2015-03-15 0:12 GMT+01:00 Max Rydahl Andersen <
        manderse@xxxxxxxxxx>:
          Is the connection made over normal jVm debugging ? Then my guess is that
          it should "just work". Like with when debugging java with jsps.

          But otherwise it might be necessary to have both debuggers connected ?

          /max

          http://about.me/maxandersen

          wrote:

            Continuing a conversation [1] started in the JBoss Tools Forum, I would
          like to discuss what it would take to support mixed _javascript_/Java
          debugging on Nashorn with JSDT.

            This is a feature that works very smoothly in NetBeans, but is not
          currently supported by official Eclipse projects or any third-party
          plugins, as it seems.

            Scenario:

            We are debugging a plain old Java application which embeds Nashorn via
          javax.script.ScriptEngine and loads some _javascript_ files. Some of the
          _javascript_ functions call Java methods via Nashorn extensions.

            Using the Eclipse debugger, we can set breakpoints both in _javascript_
          and Java sources and step through our application, from Java into
          _javascript_ and back into Java, with the appropriate source lines being
          highlighted in the editor.

            In the call stack, we can see Java and _javascript_ stack frames embodied
          by method calls of generated Java classes. When selecting a stack frame
          corresponding to a _javascript_ call, the variable inspector automatically
          switches from Java to _javascript_ mode, so we can inspect _javascript_ objects.



            So far, I've experimented with JDI and
          jdk.nashorn.internal.runtime.DebuggerSupport and I sort of understand how
          to track scripts being loaded and how to map breakpoints to _javascript_
          source lines and vice versa.

            I've taken a look at JSDT and JDT sources, and I'm not quite sure how
          this mixed source scenario would fit into the existing approaches.

            Implementing a new JSDI adapter for Nashorn along the lines of the Rhino
          debugger would only cover the _javascript_ part.

            Would it be possible to start with a JDT debug launcher and extend it or
          create some kind of mixin to switch between the Nashorn/Java and _javascript_
          aspects of the same application?

            Are there any solutions for other JVM languages supporting
          mixed-language applications that might serve as an example? from this list, visit _______________________________________________
          wtp-dev mailing list

          wtp-dev@xxxxxxxxxxx
          To change your delivery options, retrieve your password, or unsubscribe
          from this list, visit

          https://dev.eclipse.org/mailman/listinfo/wtp-dev
        _______________________________________________
        wtp-dev mailing list

        wtp-dev@xxxxxxxxxxx
        To change your delivery options, retrieve your password, or unsubscribe from this list, visit

        https://dev.eclipse.org/mailman/listinfo/wtp-dev


      /max

      http://about.me/maxandersen


    /max

    http://about.me/maxandersen
    _______________________________________________
    wtp-dev mailing list

    wtp-dev@xxxxxxxxxxx
    To change your delivery options, retrieve your password, or unsubscribe from this list, visit

    https://dev.eclipse.org/mailman/listinfo/wtp-dev
_______________________________________________
wtp-dev mailing list
wtp-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/wtp-dev


_______________________________________________
wtp-dev mailing list
wtp-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/wtp-dev

GIF image


Back to the top