2011-05-25

Hot deploy in Jetty a war file built by Jenkins

We use Jenkins to build our application as a war file and we wanted to deploy it in a Jetty server to provide a manual testing environment.
So, we installed Jetty on our Ubuntu machine using 'sudo apt-get jetty libjetty-extra'
By default, when you copy a war file to Jetty webapps directory, nothing happens because Jetty scans this directory only at startup. So, we could stop/start Jetty daemon but it requires granting some privileges to the user running Jenkins and also we may want to deploy more than one application without stoppîng the ones that are already running.

Another solution is to use Jetty's ContextDeployer hot deploy.

This means editing /etc/jetty/jetty.xml and setting the scanInterval of ContextDeployer to lowest possible value: 1 second and then restart Jetty.


<Call name="addLifeCycle">
<Arg>
<New class="org.mortbay.jetty.deployer.ContextDeployer">
<Set name="contexts"><Ref id="Contexts"/></Set>
<Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
<Set name="scanInterval">1</Set>
</New>
</Arg>
</Call>

Now we must create a context file for our war file in /etc/jetty/contexts directory. Let's call it myapp.xml and let's point it to the location of the war file from last successful build in Jenkins.

<?xml version="1.0"  encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
<Set name="contextPath">/myapp</Set>
<Set name="war">/var/lib/jenkins/jobs/MyProject/lastSuccessful/archive/trunk/myapp/target/myapp-0.0.1-SNAPSHOT.war</Set>
</Configure>

In order to deploy we just have to update our context file which can be easily done by executing 'touch /etc/jetty/contexts/myapp.xml'. We can then add it as a step in our main job in Jenkins if we want want continuous deployment or we can create a separate job if we want to control when we deploy a new version.

2011-04-27

GWT testing using Maven and Eclipse

When developing an application using Google Web Toolkit, it's a good practice to have both unit tests which do not require GWT and GWT tests for custom widgets or integration.
If you use Maven, you should apply the default naming convention of the Maven GWT plugin : *Test.java for standard unit tests and GwtTest*.java for GWT test cases. This way you have nothing to configure in your pom.xml.

Then you'll get errors from the GWT compiler because your unit tests are located in same java packages as your GWT application code but in a different source directory (e.g. src/test/java) and the compiler cannot find their source files. While these errors are not fatal and could be ignored, they are annoying. You can get rid of them by excluding your unit test classes by file pattern in your .gwt.xml file like below:


<source path='client' excludes="**/*Test.java,**/Mock*.java" />
<source path='shared' excludes="**/*Test.java" />

When you will run your GWT application, you may see error messages like:
[ERROR] [MyApp] - Line 13: No source code is available for type com.google.gwt.junit.client.GWTTestCase; did you forget to inherit a required module?

It does not prevent your application from running but they are annoying.
You can get rid of them by moving your GWT test cases to a dedicated source directory that you will exclude from the classpath of your Eclipse run configuration.
Finally, you'll put your standard unit tests under "src/test/java" and your GWT tests under "src/gwt-test/java". In your pom.xml, you have to use the build-helper-plugin to add this extra test directory.


<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/gwt-test/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>


If you want to speed up your GWT tests, you can launch them from a GWT test suite but then you must configure the Maven plugin for running only your test suite otherwise you'd end up running same test twice. My naming convention is Gwt*Suite.java which works well with the two other conventions.



<plugin>
<groupid>org.codehaus.mojo</groupid>
<artifactid>gwt-maven-plugin</artifactid>
<version>2.2.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- Run only test suites not individual test cases. -->
<includes>**/Gwt*Suite.java</includes>
</configuration>
</plugin>