Steven Verborgh

Just another weblog

Configuring a datasource for the embedded-glassfish maven plugin

Jan 29, 2010

Maven is can be a magnificent tool, that allows you to get real work done. Recently with the release of the embedded Glassfish API and a Maven plugin to control an embedded instance, rubyesque ./script/server workflow are no longer impossible for Java Developers. Being able to send colleague developers a project they can just run from maven, no setup involved is a great step forward.

There are several resources on the internet that explain how to add the plugin to you maven project. But only one mentions the use of a datasource in his project an even then the solution is an ugly hack that leads to places where developers cry behind the corner. In this small intro I'll you how to get started with one of the weld artifacts, because it provides a basic JPA project.

The first thing we are going to do is make sure we have access to the weld maven archetypes. The official documentation can be found here. As described, we are going to checkout the sources. I'm using the trunk but your millage may vary:

~$ mkdir sc
~$ cd sc/
~/sc$ svn co http://anonsvn.jboss.org/repos/weld/archetypes/trunk weld-archetypes
~/sc$ cd weld-archetypes/
~/sc/weld-archetypes$ mvn install

What this does, is install three weld project archetypes in our local maven repository. We are going to use these to create a basic weld project. We are using weld-jsf-jee archetype, this will give us a basic project containing dependencies for JSF 2, CDI, EJB 3 and JPA. It also gives us some demo code and a template persistence.xml.

~/sc/weld-archetypes$ cd ..
~/sc$ mvn archetype:generate -DinteractiveMode=n \
	-DarchetypeArtifactId=weld-jsf-jee \
	-DarchetypeGroupId=org.jboss.weld.archetypes \
	-DgroupId=be.verborgh -DartifactId=demo1
~/sc$ cd demo1

One of the nice thing is also the following xml that is included by standard by the JBoss developers that configures the Glassfish Maven repository that contains the embedded-glassfish-maven plugin.

<pluginRepositories>
   <!-- GlassFish repository required for embedded-glassfish plugin -->
   <pluginRepository>
      <id>glassfish</id>
      <name>GlassFish Maven 2 Repository</name>
      <url>http://download.java.net/maven/glassfish</url>
   </pluginRepository>
</pluginRepositories>

To enable the Embedded Glassfish plugin, add the following snippet to your pom.xml file. This gives us a few new targets like embedded-glassfish:run.

...
<build>
   <finalName>${artifactId}</finalName>
   <plugins>
		...
      <!-- Configure the Embedded GlassFish Maven plugin -->
      <plugin>
         <groupId>org.glassfish</groupId>
         <artifactId>maven-embedded-glassfish-plugin</artifactId>
         <version>3.0</version>
         <configuration>
            <serverID>server</serverID>
            <name>server</name>
            <app>${project.build.directory}/${build.finalName}.war</app>
            <port>8080</port>
            <instanceRoot>${project.build.directory}/gfe-${maven.build.timestamp}</instanceRoot>
            <autoDelete>true</autoDelete>
            <configFile>${basedir}/domain.xml</configFile>
         </configuration>
      </plugin>
		...
	<plugins>
</build>
...

The XML is relatively straightforward, the only parameter here of importance is the configFile parameter where we specify we want to use a custom domain.xml file. If you don't specify it, a default one gets used. Because the entire goal of this article is to show you how to add a custom JDBC resource, we start from the one used by default:

~/sc/demo1$ wget --http-user=<your java.net username> --http-password='<your java.net password>' https://svn.dev.java.net/svn/glassfish-svn/trunk/v3/core/kernel/src/main/resources/org/glassfish/embed/domain.xml

Once you know this trick, it is actually quiet easy to find out how to continue from here. Lets just get the default weld project working. To do this I replaced the connection pool for jdbc/__default by an embedded Derby instance, this to avoid having to start a Derby network server:

--- old
-    <jdbc-connection-pool is-isolation-level-guaranteed="false" name="DerbyPool" datasource-classname="org.apache.derby.jdbc.ClientDataSource" res-type="javax.sql.DataSource">
-      <property value="1527" name="PortNumber" />
-      <property value="APP" name="Password" />
-      <property value="APP" name="User" />
-      <property value="localhost" name="serverName" />
-      <property value="sun-appserv-samples" name="DatabaseName" />
-     </jdbc-connection-pool>
--- new
+     <jdbc-connection-pool name="DerbyPool" datasource-classname="org.apache.derby.jdbc.EmbeddedXADataSource" res-type="javax.sql.XADataSource">
+      <property value="${com.sun.aas.instanceRoot}/lib/databases/default" name="databaseName" />
+       <property value=";create=true" name="connectionAttributes" />
+     </jdbc-connection-pool>

All that is left now is configure the correct datasource in the persistence.xml. This is as simple as moving some comments:

       <!-- Use this data source name for JBoss AS -->
+      <!--
       <jta-data-source>java:/DefaultDS</jta-data-source>
+      -->
       <!-- Use this data source name for Glassfish -->
-      <!--
       <jta-data-source>jdbc/__default</jta-data-source>
-      -->

To run the entire project you can use the following command and open http://localhost:8080/<context> in your browser.

~/sc/demo1$ mvn clean package embedded-glassfish:run

I hope this helps those that are also looking for information on how to create a custom datasource for the embedded-glassfish maven plugin. I also hope you stay the f*ck out of my timerpool :)