Skip to Content
Technical Articles

Ghost In The Machine

Javascript within B1i is a valuable enhancement of the overall options, but this involves the development of code. In turn, development requires debugging of Javascript within B1i.

Being on the XML-side of B1i, pos-execution debugging is pretty convenient, using the browser based graphical debugger- and profiler-capabilities that allow watching the overall data-flow and error-outcome. It is / was well integrated to the IDE’s of the respective development models (be it B1iSN, B1if or /dev). If having the need to debug XSLT, the usage of Altova XML-Spy‘s XSLT debug capabilities would be the way to go (there does not exist other comparable functionality elsewhere). But what’s about the new kid on the block, what about Javascript?

Live-debugging on that level involves leaving the zero-footprint browser comfort zone, but things are pretty straightforward / relatively convenient, even for the non-hardcore developers. People being familiar with Java-debugging (on Tomcat) will realize that the here-mentioned way just is a bit enhanced variant they’re used to do.

Basically, almost all to be said is summarized in this blog-post:
https://blogs.oracle.com/sundararajan/remote-debugging-of-nashorn-scripts-with-netbeans-ide-using-debugger-statements
Don’t complain that the link above does not work as you expect to, this is done by intent, i want you to continue to read on this post!

Because this post primary addresses non-Java, but B1i developers, so it intros the important things that look strange to non-Java developers.

Debugging a Java server-process (as e.g. B1i is – it just only is a Java Servlet application hosted / run by the Apache Tomcat Servlet Container) involves to attach to this process from an outside client at the point in time when this is demanded – synchronicity live!
This outside client hosts / is the Java(script) debugger to be used.

Enable debugger attachment

So the first thing to be done is to enable / prepare the server process for a debugger attachment, because this is not enabled by default (for some good reasons, as we still will see). On Windows, therefore invoke (as an administrator) Tomcat8w.exe located in your <tomcat-base-directory>\bin directory. On digits in the mentioned file- and directory-names, transpose to your respective concrete Tomcat version.
Navigate to the Java-Tab and add the both leading lines (if not yet existing):

tomcatdebug

As the 2nd line is truncated in the screenshot above, here it is printed in detail (note that the syntax was different in earlier Java versions):

-Xdebug
-Xrunjdwp:transport=dt_socket,address=9000,server=y,suspend=n

This opens the network port 9000 to listen for an incoming debugger request. You should not leave this open all the time, in particular on productive machines, as the debugger attachment cannot be protected by some kind of authentication! Anybody knowing the port could attach to the process and do anything with it (e.g. look around for data). Also, debugger enablement makes the JVM slightly slower, as some internal runtime code optimizations cannot be done. These concerns even hold stronger for cloud environments. Possibly, on cloud environments, it might be a better idea to do a local (=on premise) development using B1i. Enabling / disabling debugging could get a bit awkward otherwise. Also, on cloud, don’t forget to enable the respective debugger port in your network-infrastructure. In general even on-premise, in the times of the personal firewalls, always consider them and don’t forget they do exist (otherwise, you can forget about the debugging…).
I do not address further how to enable Tomcat on a Linux installation – the trick just only is to add the same JVM Java options as mentioned above to the invocation of the JVM in the respective Tomcat control shell-script. In general, it’s a similar thing like setting the used memory for the JVM.

Get the debugger client

As we’d like to inspect Javascript, even more concretely, the Nashorn engine, we cannot make use of any Java Debugger: Eclipse or its derivates won’t work, neither SAP NetWeaver Developer Studio. Instead, it should be NetBeans: This is the only known freely available IDE that knows about the internas of Nashorn these days.
Download and install the version that fits for your client computer environment, you only need an edition that supports bare minimum plain vanilla Java (if there are choices). There is no need for the server-bundled variants.

Prepare the debugger client

Before you can start, there needs to be done an initial configuration for the first time.
In the IDE, call Debug -> New Breakpoint and add a breakpoint as to the settings shown below (the shown dialog originates from NetBeans 8):

This breakpoint targets a specific class + method of the Nashorn engine that is in place to rendez-vous with a potential debugger client. Having done this, the debugger knows where to stop if he is told to do so (see later).

Next, you need to physically address your intended debugger target (means, the server process to attach to). In Netbeans 8, this is done using the dialog Debug -> Attach Debugger. Beside the general technical settings about how to attach that always are the same, the destination host and port matter. Again, think about all potential firewall-obstacles that might be in your way!

debugger

Start Javascript debugging

If everything went fine, the indicator for success is that you can bring up / see the populated Debugging-Tab as shown in the screenshot below (don’t get overwhelmed about its very content – 99% of it are not of interest for you, unless you want to understand / debug the B1iP engine). Now, you’re live on-the-air!

debugger2

It’s time to care about your concrete debugging task. In your B1iP related editor of choice (XML-Spy e.g. also is able to show / edit Javascript – whereas this capability (still) is without frills – if you find me a WebDAV plugin for Notepad++, you’ll get a bottle of beer (or whatever else) from me), prepare you Javascript source of interest for debugging. It may be (XSLT-embedded) field-level Javascript or (XForm-Atom / ECMA-Adapter embedded) message-level Javascript, everything will be addressable.
What you need to do is set breakpoints at the code-locations of interest. As there is no integrated IDE that addresses the whole development cycle, this is not done by simple mouse-clicks at the right place. Instead, you have to type within your source: Simply inject a debugger; statement at the locations of your interest. The Nashorn Javascript runtime translates this statement to an execution of the internal class and method as prepared before on establishing a generic breakpoint.
Find below a short code-snippet of a Javascript source shown in a recent post in order to get an impression about how this is done:

debugger;
var url = scriptIO.getProperty ("url");
var factor = 1;

// Get the necessary Java classes at hand
var ByteArrayInputStream = Java.type ("java.io.ByteArrayInputStream");
var ByteArrayOutputStream = Java.type ("java.io.ByteArrayOutputStream");
var ImageIO = Java.type ("javax.imageio.ImageIO");
var Math = Java.type ("java.lang.Math");
var URL = Java.type ("java.net.URL");
var AffineTransform = Java.type ("java.awt.geom.AffineTransform");
var BufferedImage = Java.type ("java.awt.image.BufferedImage");
//var Graphics2D = Java.type ("java.awt.Graphics2D");


var bim;

if (url == null)
{
    debugger;
    var props = new Array ();
    props [0] = "bpm.pltype";
    props [1] = "jpg";

    . . . .

Now run your Javascript-containing code. The debugger should stop execution at the first located breakpoint and this should be detectable in the Debugging Tab: You should see a call-stack describing the breakpoint location (the green area). Depending on the kind of your Javascript usage (message-level, field–level, ECMA-Adapter, nested BizFlows, IPO-Steps…), the call-stack may look differently. What is common to all cases is the pretty top line with the eval keyword inside. Make a double-click to it and you get your Javascript-source on the screen!
Now you can use all debugger capabilities (single step, step over, continue to run and so on). You can use the various inspection windows, as e.g. the known variables and their values at a given location.
For the mentioned code-snippet, the screen therefore roughly should look like that (note the triangle for the current execution location at line #4):

debugger3

If you e.g. continue to execute in single step mode (using the F8 key), you even see a green arrow at the beginning of the current line and the line is highlighted in green.

For debugging Javascript, you don’t need to create / open any NetBeans project / files, as the very debug-info comes from the concretely debugged Javascript code. So NetBeans has everything it needs from its destination at runtime and does not need any external provisioning with the Javascript source files. That’s a remarkable difference to Java: On Java, you need to supply the source files matching to the debugged binaries in order to get a meaningful picture of the situation.

If you’re done with debugging and have disconnected your debugger again, you could leave the debugger; statements in your Javascript code. They should not cause any remarkable execution overhead in a productive operating environment.

Conclusion

Using the well known basis of server-side Java-debugging and adding the Nashorn Javascript context by using NetBeans as a debugger client is a promising and powerful approach for live Javascript debugging within B1i. The offered overall convenience can be deemed as being state-of-the-art these days. Care has to be taken – as always – in cloud environments, as debugging adds a temporary, technically non-avoidable vulnerability to it – a temporary open door where it is hard to control who’s going to enter it. Alleviation can be brought by applying dedicated technical firewall rules – e.g. by restricting the IP-address of allowed clients.

At the end of the day, as you’ve reached to the end of this post, here is the (now working!) link to the other post:
https://blogs.oracle.com/sundararajan/remote-debugging-of-nashorn-scripts-with-netbeans-ide-using-debugger-statements

(This blog-post originally appeared on my Da Vinci Space Blog:
https://davincispace.wordpress.com/2019/07/30/ghost-in-the-machine/)

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.