0

Does anyone know how to debug java servlets that use the Android API when they are hosted on i-Jetty ?

For a regular website (not on Android / i-jetty), it can be debugged with Eclipse EE on a local server using Debug As -> Debug On Server.

For Android applications, I use Android Development Tools for Eclipse and run Debug As -> Android Application.

But, in this case, I have Android code packaged in a war.

I use the following POM.xml file and maven to package the war file for use with i-Jetty. It runs the dx utility to convert the servlets from Java to Dalvik. I can deploy the result and run it on i-jetty on Android. But, I can't figure out how to debug servlet calls with any other method than via LogCat printouts. I considered trying to get i-jetty built in Eclipse (it's also built with maven) and seeing if ADT could trace execution into the servlets but wasn't sure if that path would be fruitful.

  <?xml version="1.0" encoding="UTF-8" ?> 
  <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0      http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <parent>
  <groupId>org.mortbay.ijetty</groupId> 
  <artifactId>example-webapps-parent</artifactId> 
  <version>3.2-SNAPSHOT</version> 
  <relativePath>../pom.xml</relativePath> 
  </parent>
  <modelVersion>4.0.0</modelVersion> 
  <artifactId>blahblah</artifactId> 
  <name>I-Jetty :: blahblah</name> 
  <version>1.0-SNAPSHOT</version> 
  <packaging>war</packaging> 
  <url>http://maven.apache.org</url> 
  <build>
  <plugins>
  <plugin>
  <artifactId>maven-compiler-plugin</artifactId> 
  <configuration>
  <source>1.5</source> 
  <target>1.5</target> 
  <verbose>false</verbose> 
  </configuration>
  </plugin>
  <!--  Convert the compiled classes into a clases.dex. 
  --> 
  <plugin>
  <groupId>org.codehaus.mojo</groupId> 
  <artifactId>exec-maven-plugin</artifactId> 
  <version>1.1</version> 
  <executions>
  <execution>
  <id>generate-dex</id> 
  <phase>process-classes</phase> 
  <goals>
  <goal>exec</goal> 
  </goals>
  <configuration>
  <!--  executable>${env.ANDROID_HOME}/platform-tools/dx</executable 
  --> 
  <executable>java</executable> 
  <arguments>
  <!--  <argument>-JXmx1024M</argument> 
  --> 
  <argument>-jar</argument> 
  <argument>${env.ANDROID_HOME}/platform-tools/lib/dx.jar</argument> 
  <argument>--dex</argument> 
  <argument>--verbose</argument> 
  <argument>--core-library</argument> 
  <argument>--output=${project.build.directory}/classes.dex</argument> 
  <argument>--positions=lines</argument> 
  <argument>${project.build.directory}/classes/</argument> 
  </arguments>
  </configuration>
  </execution>
  </executions>
  </plugin>
  <plugin>
  <artifactId>maven-antrun-plugin</artifactId> 
  <executions>
  <execution>
  <id>copydex</id> 
  <phase>process-classes</phase> 
  <goals>
  <goal>run</goal> 
  </goals>
  <configuration>
  <tasks>
  <mkdir dir="${project.build.directory}/${project.artifactId}-${project.version}/WEB-    INF/lib" /> 
  <jar basedir="${project.build.directory}" update="true" includes="classes.dex"     destfile="${project.build.directory}/${project.artifactId}-${project.version}/WEB-INF/lib/classes.zip" /> 
  </tasks>
  </configuration>
  </execution>
  </executions>
  </plugin>
  </plugins>
  </build>
 <dependencies>

 <dependency>
  <groupId>org.mortbay.jetty</groupId> 
  <artifactId>servlet-api</artifactId> 
  <version>${servlet.version}</version> 
  <scope>provided</scope> 
  </dependency>
  <dependency>
  <groupId>com.google.android</groupId> 
  <artifactId>android</artifactId> 
  <version>${android.version}</version> 
  <scope>provided</scope> 
  </dependency>
  </dependencies>
  <repositories>
  <repository>
  <id>repo</id> 
  <releases>
  <enabled>true</enabled> 
  <checksumPolicy>ignore</checksumPolicy> 
  </releases>
  <snapshots>
  <enabled>false</enabled> 
  </snapshots>
  <url>file://${project.basedir}/repo</url> 
  </repository>
  </repositories>
  </project>
bluesky
  • 150
  • 1
  • 1
  • 11

1 Answers1

0

The way I did it was I used LogCat for debugging the Android code, and the ServletOutputStream on the response for debugging the servlet code. After adding a few helper methods I was able to get really detailed JSON formatted output for the requests coming in.

An example:

private static String debugStringHeaders(HttpServletRequest request, int indent)
{
    String indentString = RequestPrinter.repeat(INDENT_UNIT, indent);
    StringBuilder sb = new StringBuilder();
    sb.append(indentString).append("{\n");
    Enumeration headerNames = request.getHeaderNames();
    while (headerNames.hasMoreElements()) {
        String headerName = (String) headerNames.nextElement();
        Enumeration headerValues = request.getHeaders(headerName);
        List<String> headerValuesList = new ArrayList<String>(); 
        while (headerValues.hasMoreElements()) {
            String headerValue = (String) headerValues.nextElement();
            headerValuesList.add(headerValue);
        }
        sb.
            append(RequestPrinter.debugStringHeader(indentString, headerName, headerValuesList)).
            append(",\n");
    }
    sb.append(indentString).append("}\n");
    return sb.toString();
}

You can also bridge the Jetty Logger to point to the Android Logger. This will allow you to make Log.e("TAG", "Error to log") type calls inside your servlet code and have them show in the debugger.

System.setProperty( "org.eclipse.jetty.util.log.class", "org.mortbay.ijetty.AndroidLogger" );
org.eclipse.jetty.util.log.Log.setLog( new AndroidLogger() );
zimmryan
  • 1,099
  • 10
  • 19