Many folks want to use some features beyond the bare servlet basics with GWT, such as JNDI lookups. It’s not hard to set up, but there are a couple of steps to it so here’s a detailed guide.

Since GWT switched to using Jetty for its hosted mode (also known as development mode) back at GWT 1.6, lots of people have been asking how to use features such as JNDI lookups in their webapps.  Several people have posted helpful instructions, perhaps the best of them being from Nicolas Wetzel in this thread on Google Groups, and from Henning on his blog (in German).

In this blog post, we’ll put all these instructions together in the one place, and give you a couple of projects you can download to get you started faster. You might want to skip down to the downloadable projects.

Customizing the GWT Launcher

The first step is to customize the JettyLauncher provided by GWT.  Unfortunately, at the time of writing (GWT2.3.0) you cannot customize by extension due to the use of final inner classes and private constructors. Therefore, you will need to copy and paste the entire class in order to make the necessary and trivial modifications to enable JNDI.

You can find the source of the JettyLauncher.java class inside the gwt-dev.jar in your local installation of the GWT SDK.  Here’s a link to the jar from Maven Central Repository for convenience: gwt-dev-2.3.0.jar.  Unjar it, and copy the com/google/gwt/dev/shell/jetty/JettyLauncher.java class to a new location and name.

Edit your new class and paste in this declaration:

This declaration tells Jetty to setup JNDI for your web app and process the various xml files concerned.  Nearly done now. All you need to do is now apply these Configuration classes to the WebAppContext that represents your web app. Find the line that creates the WebAppContext:

Now, add this line straight afterwards:

Build your new class and you’re done. To save you some time, here’s a small project with the class modifications already done for you (variants for Ant and Maven):

Modifying your Web App

Step 1

Add the extra jetty jars that implement JDNI lookups to your web app’s WEB-INF/lib directory. Here’s the links to version 6.1.26 of these jars – these have been tested against GWT 2.3.0 and will work, even though GWT is using a much older version of jetty (6.1.11?):

Step 2

Now you can create a WEB-INF/jetty-env.xml file to define the resources that you want to link into your web.xml file, and lookup at runtime with JNDI.

That’s it, you’re good to go with runtime JNDI lookups in GWT hosted mode. Your webapp should also be able to run without modification when deployed into standalone Jetty. If you deploy to a different container (huh?!), then you’ll need to define the JNDI resources appropriately for that container (but you can leave WEB-INF/jetty-env.xml in place and it will be ignored).

If You’re Not Sure How To Define JNDI Resources For Jetty…

The Jetty 6 Wiki contains instructions on how to do his, but here’s a short example that defines a MySQL datasource:

In WEB-INF/jetty-env.xml:

Now link this into your web app with a corresponding entry in your WEB-INF/web.xml:

Of course, you will also need to copy any jars required by your resources – in this case the MySQL jar – into your WEB-INF/lib.

You can then lookup the JNDI resource inside your servlet, filter etc:

An Example WebApp

An example usually helps, so I’ve put together a silly, tiny webapp that does a JNDI lookup. It is based on the standard GWT “Hello World” webapp that is generated by default by the GWT webAppCreator script. This webapp does an RPC call to a servlet to get a message incorporating the name entered by the user. I’ve simply modified the message that is returned to also include an extra sentence obtained by doing a java:com/env lookup.

Here’s my WEB-INF/jetty-env.xml:

This defines the equivalent of an <env-entry> outside of web.xml. In fact, the boolean argument set to “true” means that it would override the value of an <env-entry> of the same name inside WEB-INF/web.xml. This is actually most useful when used in a Jetty context xml file for the webapp instead of WEB-INF/jetty-env.xml, as it would allow you to define a default value inside WEB-INF/web.xml and then customize for each deployment in the context xml file (which is external to the webapp). For this example, we could have just as well defined the <env-entry> in WEB-INF/web.xml instead, but I wanted to show you a WEB-INF/jetty-env.xml file so you have an example of where to define your resources.

Here’s the extra code that does the lookup inside of GreetingServletImpl.java:

Running the built project in hosted mode and hitting the url http://127.0.0.1:8888/HelloJNDI.html?gwt.codesvr=127.0.0.1:9997 I see:
Screen shot of webapp in action.

Here’s an Ant project for this trivial webapp: HelloJNDI

  1. edit the build.xml file to change the property gwt.sdk to where you have the GWT SDK locally installed.
  2. build and run it in hosted mode with: ant devmode
  3. follow the hosted mode instructions to cut and paste the url into your browser

Resource Listing

GWT and JNDI

12 thoughts on “GWT and JNDI

  • Pingback:GWT and JNDI | Eclipse | Syngu

  • September 6, 2011 at 1:52 pm
    Permalink

    Hi,
    i’m following you “Example WebApp”-howto. But it didn’t work for me.
    The lookupMessage replays “null” and i don’t know why…
    What you are make with the make with the GWTJettyPlusLauncher ? Must i add it to the libs? (I’m using eclipse with maven)
    Greetz swi

    • August 4, 2012 at 7:53 am
      Permalink

      Here is the Maven profile you need: jetty-alternateport org.mortbay.jetty jetty-maven-plugin ${jetty-version} 8081 18080 The stopPort is optional but I added in case you have two Maven jetty:run’s running at the same time on the same machine, the stopPort needs to be set to something other than the default on one of them.

  • September 7, 2011 at 12:25 am
    Permalink

    HI,
    Nice article. Is it also possible to customize the java agent property for jetty. My application uses load time weaving and i have to pass javaagent argument during the gwt application startup. But the javaagent argument is ignored when i launch it.

  • October 2, 2011 at 6:14 pm
    Permalink

    There is a missing step here. How do I tell GWT to use a different launcher? The easy way is just to replace their stock class with the modified class, but from your example (GWTJettPlusLauncher), I can tell there must be a way to specify a different launcher.

  • October 2, 2011 at 6:37 pm
    Permalink

    I fixed this.To use the new launcher, modify your run configuration. In the arguments tab add:

    -server org.mortbay.gwt.GWTJettyPlusLauncher

  • October 2, 2011 at 6:52 pm
    Permalink

    I’m still missing something. I get a failure on startup:

    [WARN] Failed startup of context org.mortbay.gwt.GWTJettyPlusLauncher$WebAppContextWithReload@16a799c1{/,C:Usersdparishworkspaceretainwar}
    javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
    at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
    at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(Unknown Source)
    at javax.naming.InitialContext.lookup(Unknown Source)
    at org.mortbay.jetty.plus.webapp.EnvConfiguration.createEnvContext(EnvConfiguration.java:57)
    at org.mortbay.jetty.plus.webapp.EnvConfiguration.configureDefaults(EnvConfiguration.java:101)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1200)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:513)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448)
    at org.mortbay.gwt.GWTJettyPlusLauncher$WebAppContextWithReload.doStart(GWTJettyPlusLauncher.java:476)

    Debugging through the jetty code, it’s failing here:

    compCtx = (Context)context.lookup (“java:comp”);

    • October 2, 2011 at 11:41 pm
      Permalink

      David,

      Check that you have the jetty-naming-6.1-SNAPSHOT.jar and jetty-plus-6.1-SNAPSHOT.jar in your WEB-INF/lib. Note that you can’t put them onto the classpath of the jvm that executes com.google.gwt.dev.DevMode (ie launches the launcher) because the google code makes the boot classloader the parent of jetty’s classloader, so there is no access to jars on the system classpath.

      regards
      Jan

  • October 19, 2011 at 5:41 pm
    Permalink

    I followed the steps but its not working for me. When GWT hosted mod starts, I get a warning and then everything stops

    [WARN] Configuration problem at
    jdbc/myDS
    javax.sql.DataSource
    Container
    java.lang.IllegalStateException: Nothing to bind for name javax.sql.DataSource/default

    at org.mortbay.jetty.plus.webapp.Configuration.bindEntry(Configuration.java:259)
    at org.mortbay.jetty.plus.webapp.Configuration.bindResourceRef(Configuration.java:98) at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initResourceRef(AbstractConfiguration.java:262) at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initWebXmlElement(AbstractConfiguration.java:161) at org.mortbay.jetty.webapp.WebXmlConfiguration.initialize(WebXmlConfiguration.java:289) at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initialize(AbstractConfiguration.java:133) at org.mortbay.jetty.webapp.WebXmlConfiguration.configure(WebXmlConfiguration.java:222) at org.mortbay.jetty.plus.webapp.AbstractConfiguration.configure(AbstractConfiguration.java:113) at org.mortbay.jetty.webapp.WebXmlConfiguration.configureWebApp(WebXmlConfiguration.java:180) at org.mortbay.jetty.plus.webapp.AbstractConfiguration.configureWebApp(AbstractConfiguration.java:96) at org.mortbay.jetty.plus.webapp.Configuration.configureWebApp(Configuration.java:149) at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1217) at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:513) at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448) at org.mortbay.gwt.GWTJettyPlusLauncher$WebAppContextWithReload.doStart(GWTJettyPlusLauncher.java:475)

    • October 19, 2011 at 11:19 pm
      Permalink

      Kiran,

      This means that the name that is configured in the in web.xml cannot be found anywhere in the environment. Are you sure you have defined a Resource in WEB-INF/jetty-env.xml? Compare your project to the one in the HelloJNDI example might help.

      cheers
      Jan

      • December 29, 2012 at 11:22 am
        Permalink

        Hi,

        Thanks for the article, for the JNDI problem i had to add somewhere in the class :
        static {
        // Configure JNDI to use Jetty resolver
        System.setProperty(“java.naming.factory.url.pkgs”,”org.mortbay.naming”);
        System.setProperty(“java.naming.factory.initial”,”org.mortbay.naming.InitialContextFactory”);
        }

        HTH,
        Ludo

  • Pingback:GWT, Jetty, JNDI and Microsoft SQL Server: issue with getConnection | DIGG LINK

Comments are closed.