Senior developer and architect, I am a passionate programmer. I work on a java productive technical base called KaleidoFoundry (open source). Jerome has posted 1 posts at DZone. You can read more from them at their website. View Full User Profile

GWT debugging, go further with jetty and maven

09.23.2012
| 3737 views |
  • submit to reddit

Sometimes during the gwt debugging with Google plugin for Eclipse or with maven gwt plugin, you will need to access some jndi datasource or some environment parameters (like you can do it with tomcat). The default embedded  jetty do not provide this feature, and you will need a little hack to do this.

The following exemple define an environment variable and a datasource for tomcat and jetty:

For tomcat : add to your "context.xml" :

<Environment name="yourapp.basedir"
  value="/path/to/project/target/app"
  type="java.lang.String" override="false" />
 
<Resource auth="Container"
  driverClassName="org.apache.derby.jdbc.EmbeddedDriver"
  name="jdbc/yourDatasource" type="javax.sql.DataSource"
  url="jdbc:derby:test;create=true" username="APP" password="APP"
  maxActive="10" maxIdle="4"  />

For jetty embedded in gwt : create a new file jetty-web.xml, in your WEB-INF :

<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="webAppCtx" class="org.mortbay.jetty.webapp.WebAppContext">
  <New id="yourapp.basedir" class="org.mortbay.jetty.plus.naming.EnvEntry">
    <Arg>java:comp/env/yourapp.basedir</Arg>
    <Arg type="java.lang.String">/path/to/project/target/app</Arg>
    <Arg type="boolean">true</Arg>
  </New>
  <New id="yourDatasource" class="org.mortbay.jetty.plus.naming.Resource">
    <Arg>java:comp/env/jdbc/yourDatasource</Arg>
    <Arg>
      <New class="org.apache.derby.jdbc.EmbeddedDataSource">
        <Set name="DatabaseName">test</Set>
        <Set name="createDatabase">create</Set>
      </New>
    </Arg>
  </New>
</Configure>  

For the datasource, don’t forget to add to your web.xml :

<resource-ref>
   <description>DB Connection</description>
   <res-ref-name>jdbc/yourDatasource</res-ref-name>
   <res-type>javax.sql.DataSource</res-type>
   <res-auth>Container</res-auth>
 </resource-ref>
To access it from your java server class (ServletContextListener / Servlet …) :
try {
  Context initCtx = new InitialContext();
 
  // to access your datasource
  Datasource dataSource = (DataSource)context.lookup("java:comp/env/yourDatasource");
  // get a connection and use it ....
 
  // to access the environment entry list
  NamingEnumeration<Binding> bindingsEnum = initCtx.listBindings("java:comp/env");
  while (bindingsEnum.hasMore()) {
    Binding binding = bindingsEnum.next();
    System.out.printf("%s = %s\n", binding.getName(), binding.getObject().toString());
    // memorize this settings parameters somewhere ...
  }
 
 } catch (NamingException e) {
   // ... handle it
 }

Now, back to gwt, maven and eclipse :

Add to your pom.xml  :

<properties>
  <gwtVersion>2.4.0</gwtVersion>
  <webappDirectory>${project.build.directory}/${project.build.finalName}
  </webappDirectory>
</properties>
 
<dependencies>
  <!-- gwt core -->
  <dependency>
    <groupId>com.google.gwt</groupId>
    <artifactId>gwt-servlet</artifactId>
    <version>${gwtVersion}</version>
  </dependency>
  <dependency>
    <groupId>com.google.gwt</groupId>
    <artifactId>gwt-user</artifactId>
    <version>${gwtVersion}</version>
    <scope>provided</scope>
  </dependency>
  <!-- needed by for jndi access (jetty embedded container) -->
  <dependency>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty-plus</artifactId>
    <version>6.1.11</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty-naming</artifactId>
    <version>6.1.11</version>
    <scope>provided</scope>
  </dependency>
  <!-- only needed for datasource testing -->
  <dependency>
    <groupId>org.apache.derby</groupId>
    <artifactId>derbyclient</artifactId>
    <version>10.6.1.0</version>
  </dependency>
  <dependency>
    <groupId>org.apache.derby</groupId>
    <artifactId>derby</artifactId>
    <version>10.6.1.0</version>
  </dependency>
</dependencies>
 
<build>
  <finalName>yourAppContext</finalName>
  <outputDirectory>${webappDirectory}/WEB-INF/classes</outputDirectory>
 
  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>gwt-maven-plugin</artifactId>
    <version>${gwtVersion}</version>
    <executions>
      <execution>
        <goals>
          <goal>compile</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <extraJvmArgs>-Xmx512M -XX:MaxPermSize=196m -Xss1024k -Djava.naming.factory.initial=org.mortbay.naming.InitialContextFactory
      </extraJvmArgs>
      <runTarget>YourApplication.html</runTarget>
      <hostedWebapp>${webappDirectory}</hostedWebapp>
    </configuration>
  </plugin>
 
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1.1</version>
    <executions>
      <execution>
        <phase>compile</phase>
        <goals>
          <goal>exploded</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <webappDirectory>${webappDirectory}</webappDirectory>
    </configuration>
  </plugin>
</build>

To explain, the two jetty dependencies are not included in the gwt-dev core (the debugging tool with the embedded jetty), they are “provided” scope because they are only used during development / testing (“test” scope does not works with gwt-maven plugin). The last two derby dependencies  are only here for the datasource example.

For accessing jdni resources, you then need to define a java environment variable :

-Djava.naming.factory.initial=org.mortbay.naming.InitialContextFactory

 If you use Google plugin for Eclipse : edit the run / debug preferences of your project :

eclipse gwt runner

If you use the maven gwt plugin :  

mvn gwt:run

To compile and install the final war plugin :

mvn clean install

Once the gwt application tested and compiled : If you works with apache tomcat under eclipse, I highly recommend the tomcat plugin (with its DevClassLoader for hot code replace) : http://www.eclipsetotale.com/tomcatPlugin.html

All works with google 2.5.0-rc1 too ;-)

To conclude, you can develop with gwt as though you worked on your prefered servlet container like tomcat / jetty … Without hack , gwt rpc servlets can now uses jndi resources like datasources, environment variables… A simple “war” project could be used for debugging or delivering your web application version.

 

 

 

 

0
Published at DZone with permission of its author, Jerome Raduget.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)