Sunday, 17 February 2013

JavaScript: debugging with embedded Rhino in Eclipse

The Eclipse JavaScript Development Tools allow step-through-debugging of JavaScript files using a provided Rhino instance. The Wiki describes how to utilise Eclipse plugins to connect your own embedded Rhino context to Eclipse.

Versions: Java 7; Rhino 1.7R4; Eclipse Juno (4.2) SR1 (Eclipse IDE for Java EE Developers).

Debugging in embedded code

To utilise the Eclipse connector, it is necessary to add the org.eclipse.wst.jsdt.debug.rhino.debugger and org.eclipse.wst.jsdt.debug.transport IDE plugins to the classpath.

This code will block and wait for the debugger to connect on port 9000:

import java.io.*;
import org.eclipse.wst.jsdt.debug.rhino.debugger.RhinoDebugger;
import org.mozilla.javascript.*;

public class DbgEclipse {

  public static void main(String[] args) throws Exception {
    String file = "test.js";
    String rhino = "transport=socket,suspend=y,address=9000";

    RhinoDebugger debugger = new RhinoDebugger(rhino);
    debugger.start();

    ContextFactory factory = new ContextFactory();
    factory.addListener(debugger);
    Context context = factory.enterContext();
    Scriptable scope = context.initStandardObjects();
    try (final Reader in = new FileReader(file)) {
      context.evaluateReader(scope, in, file, 1, null);
    }
    debugger.stop();
    Context.exit();
  }
}

I used the same test code from a previous post.

Running and debugging

Eclipse JavaScript step-through debugging

To launch the code, two debug configurations are required (accessible through the Run > Debug Configurations... menu.)

Create a Java Application configuration
  1. Set the project and main class.
  2. Launch this configuration before launching the next one.
Create a Remote JavaScript configuration
  1. Set the Connector to Mozilla Rhino - Attaching Connector.
  2. Set the host to localhost and the port to 9000.
  3. Configure the Source tab with the location of your test script.
  4. Launch the configuration.

This last step is necessary if you want Eclipse to honour any break points set in workspace JavaScript files. Otherwise, Eclipse will create resources in a project called External JavaScript Source. Eclipse will honour debugger; statements in the JavaScript code regardless.

Note: use the File > Export... menu to share Run/Debug configurations across teams.

Building the code

I used the Maven integration plugin M2E to build my code, though the same results can be achieved with manual build configuration.

Before building, I pushed my Eclipse dependencies into my local Maven repository:

mvn eclipse:to-maven -DeclipseDir=<path/to/eclipse> -DstripQualifier=true

Here is the Maven POM:

<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>test</groupId>
  <artifactId>rdbg</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.0</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>org.mozilla</groupId>
      <artifactId>rhino</artifactId>
      <version>1.7R4</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.wst.jsdt.debug.rhino</groupId>
      <artifactId>debugger</artifactId>
      <version>1.0.301</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.wst.jsdt.debug</groupId>
      <artifactId>transport</artifactId>
      <version>1.0.101</version>
    </dependency>
  </dependencies>
</project>

No comments:

Post a Comment

All comments are moderated