J'ai un peu galéré à faire fonctionner JNDI en mode dev via Maven 2 car google tombe sur un tas de forums où les solutions ne fonctionnent pas. Peut etre que ca vient de l'évolution des versions. Néanmoins j'ai fini par trouver et j'en profite donc pour partager ca avec vous.

Résolution des problèmes étape par étape

Le fichier de conf JNDI

Pour commencer il faut connaitre le fichier qui contiendra les infos de connexion à notre base de donnée. J'ai mis du temps à trouver car le nom de ce fichier n'est pas celui décrit par la doc de Jetty http://docs.codehaus.org/display/JETTY/JNDI ... et non quelqu'un à brouillé les pistes. Il faut nommer ce fichier src/main/webapp/WEB-INF/jetty-web.xml, ce fichier contiendra la structure suivante :

  <Configure class="org.mortbay.jetty.webapp.WebAppContext">
	<New id="myappli" class="org.mortbay.jetty.plus.naming.Resource">
		<Arg></Arg>
		<Arg>jdbc/mybase</Arg>
		<Arg>
			<New class="org.postgresql.ds.PGSimpleDataSource">
				<Set name="User">myuser</Set>
				<Set name="Password">mypasswd</Set>
				<Set name="DatabaseName">mybase</Set>
				<Set name="ServerName">localhost</Set>
				<Set name="PortNumber">5432</Set>
			</New>
		</Arg>
	</New>
  </Configure>

NoInitialContextException

Quand vous lancez une appli basée sur JNDI en mode dev, vous devez tomber en premier lieu sur l'exception suivante :

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

Pour résoudre ce problème il faut ajouter un argument à la JVM avec la conf suivante :

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>gwt-maven-plugin</artifactId>
    <version>1.3.2.google</version>
    <configuration>
      <gwtVersion>${gwt.version}</gwtVersion>
      <module>my.paquage.Application</module>
      <runTarget>my.paquage.Application/Application.html</runTarget>


      <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
      <copyWebapp>true</copyWebapp>
      <extraJvmArgs>-Djava.naming.factory.initial=org.mortbay.naming.InitialContextFactory</extraJvmArgs>
      <soyc>false</soyc>
    </configuration>
    <executions>
	<execution>
		<goals>
			<goal>compile</goal>
			<goal>test</goal>
		</goals>
	</execution>
    </executions>
  </plugin>

Cet argument précise quelle classe utiliser pour charger la conf JNDI. Etant donné que c'est jetty qui est utilisé par maven pour lancer le mode dev on précise donc le chargeur de jetty.

ClassNotFoundException

Ensuite on tombe sur un problème que je n'ai pas bien compris. Jetty est utilisé comme conteneur de servlet, mais lorsqu'on cherche à utiliser son chargeur JNDI le classloader ne le trouve pas. Pas de soucis j'ai contourné le problème en ajoutant les deux jars utiles en dépendance à mon projet comme suit :

  <dependency>
	<groupId>org.mortbay.jetty</groupId>
  	<artifactId>jetty-naming</artifactId>
	<version>6.1.26</version>
  </dependency>
  <dependency>
	<groupId>org.mortbay.jetty</groupId>
  	<artifactId>jetty-plus<>
	<version>6.1.26</version>
  </dependency>

Je n'ai pas trouvé les versions du jetty utilisé par Maven alors j'ai spécifié la derniere version de Jetty à ce jour et ca marche.

On nettoie le tout pour la PROD

On se retrouve donc avec des jar de jetty dans le classpath, ceux du drivers aussi et le fichier jetty-web.xml. Ces fichiers sotn utiles uniquement pour le mode dev de GWT. Il ne faut donc pas qu'ils se retrouve dans le war que vous allez généré pour les différentes plateformes.

Pour régler ce dernier problème il faut configurer maven-war-plugin comme suit :

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-war-plugin</artifactId>
	<dependencies>
		<dependency>
			<groupId>com.thoughtworks.xstream</groupId>
			<artifactId>xstream</artifactId>
			<version>1.3.1</version>
		</dependency>
	</dependencies>
	<configuration>
		<packagingExcludes>WEB-INF/lib/jetty-*-6.1.26.jar,WEB-INF/jetty-web.xml</packagingExcludes>
		<webResources>
			<webResource>
				<directory>src/main/webapp/WEB-INF</directory>
				<includes>
					<include>web.xml</include>
				</includes>
				<targetPath>WEB-INF</targetPath>
				<filtering>true</filtering>
			</webResource>
		</webResources>
	</configuration>
</plugin>

J'avais un problème de dépendance transitive avec xstream que j'ai fixé ici. Et je filtre le web.xml avec des variables maven. A part ca c'est la conf standard.

Maintenant vous savez tout sur l'utilsiation du JNDI avec GWT 2.1 et le mode dev.

Enjoy