Skip to main content

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


Looks like going in the right direction, but yes, do move to Mars when you can since I believe there could be fixes for alot of Java 8 related "quirks".

(can't promise though ;)

/max

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

[image: 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*
<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*
<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*
   <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* <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* <http://about.me/maxandersen>

          On 14 Mar 2015, at 19:24, Harald Wellmann <
            *hwellmann.de@xxxxxxxxx* <hwellmann.de@xxxxxxxxx>>
         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?

            [1] *https://developer.jboss.org/message/920239*
            <https://developer.jboss.org/message/920239>

            Best regards,
            Harald
            _______________________________________________
            wtp-dev mailing list
*wtp-dev@xxxxxxxxxxx* <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*
            <https://dev.eclipse.org/mailman/listinfo/wtp-dev>
         _______________________________________________
         wtp-dev mailing list
*wtp-dev@xxxxxxxxxxx* <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*
         <https://dev.eclipse.org/mailman/listinfo/wtp-dev>
          _______________________________________________
      wtp-dev mailing list
*wtp-dev@xxxxxxxxxxx* <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*
      <https://dev.eclipse.org/mailman/listinfo/wtp-dev>


   /max
*http://about.me/maxandersen* <http://about.me/maxandersen>


/max
*http://about.me/maxandersen* <http://about.me/maxandersen>
_______________________________________________
wtp-dev mailing list
*wtp-dev@xxxxxxxxxxx* <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*
<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


[graycol.gif]
_______________________________________________
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


Back to the top