<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>The Server Labs Blog</title>
	<atom:link href="http://www.theserverlabs.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.theserverlabs.com/blog</link>
	<description>The team blog of The Server Labs</description>
	<pubDate>Mon, 15 Dec 2008 08:32:12 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.1</generator>
	<language>en</language>
			<item>
		<title>Thoughts on Devoxx</title>
		<link>http://www.theserverlabs.com/blog/2008/12/15/thoughts-on-devoxx/</link>
		<comments>http://www.theserverlabs.com/blog/2008/12/15/thoughts-on-devoxx/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 08:32:12 +0000</pubDate>
		<dc:creator>Kevin McCormack</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[events]]></category>

		<guid isPermaLink="false">http://www.theserverlabs.com/blog/?p=182</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/12/15/thoughts-on-devoxx/";</script>Wow! What an intense 3 days Devoxx is. Between the conference and the traveling and (of course!) those famous Belgian beers, it was an action-packed trip. 
We enjoyed the conference a lot. It was professionally organised, had good speakers and had great food too. They even managed to keep the wireless network more-or-less functional with [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/12/15/thoughts-on-devoxx/";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>Wow! What an intense 3 days Devoxx is. Between the conference and the traveling and (of course!) those famous Belgian beers, it was an action-packed trip. </p>
<p>We enjoyed the conference a lot. It was professionally organised, had good speakers and had great food too. They even managed to keep the wireless network more-or-less functional with over 3000 bandwidth-hungry developers trying to use it all at once. </p>
<p>Unsurprisingly, the talks reflected the current themes in the Java world. There was a large focus on RIA (Rich Internet Application) technologies, dynamic languages and modularization. </p>
<p>JavaFX and Flex grabbed all the attention in the RIA category at the expense of some of the more traditional UI Technologies (JSF 2.0 and Dojo/DWR). I personally was quite disappointed with the standard of the JavaFX presentations, especially since it was one of the topics I was most interested in learning about. Inevitably JavaFX as a technology is going to be compared against Flex but I feel I didn&#8217;t even see enough code or information to make a comparison. The Flex presentations were of a considerably higher standard. </p>
<p>The second day opened with a keynote from Mark Reinhold about Java 7 in general and, more specifically, the project to modularize the JDK - Project Jigsaw. Later Alex Buckley gave us more details on the possible Java language changes to support modularization. Modularization was also heavily in evidence in the Springsource DM Server presentations that we attended. It&#8217;s been obvious for a while now that this is the way forward for Java. </p>
<p>Talk of the conference probably went to Joshua Bloch who gave an interesting and dynamic keynote on Effective Java that taught us a thing or two that we didn&#8217;t know about Java. The man was just a bundle of enthusiasm and energy on the stage. </p>
<p>Other talks that caught our attention were ones on Scala, REST and JAX-RS. Scala because we&#8217;d not had a chance to take a look at the language and the REST/JAX-RS talks because they summed up the technologies in such a way that they became clearer and easier to understand. </p>
<p>Finally, we&#8217;d like to mention the talk given by Ari Zilka on Terracotta as a great example, based on their Examinator web reference application, of a presentation on the usage of a technology in the real world - something that is sadly lacking sometimes at conferences such as these which are, understandably, focussed on promoting new technologies via simple &#8216;hello world&#8217; examples. </p>
<p>That&#8217;s all for now. In the coming days, we&#8217;ll write in more detail about some of the more interesting things that we saw&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theserverlabs.com/blog/2008/12/15/thoughts-on-devoxx/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hello from Devoxx</title>
		<link>http://www.theserverlabs.com/blog/2008/12/10/hello-from-devoxx/</link>
		<comments>http://www.theserverlabs.com/blog/2008/12/10/hello-from-devoxx/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 09:12:51 +0000</pubDate>
		<dc:creator>Kevin McCormack</dc:creator>
		
		<category><![CDATA[events]]></category>

		<category><![CDATA[devoxx event]]></category>

		<guid isPermaLink="false">http://www.theserverlabs.com/blog/?p=176</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/12/10/hello-from-devoxx/";</script>This week, some The Server Labs employees are at the Java Devoxx conference in Antwerp, Belgium.
We&#8217;ve just had a human beat box guy warming the crowd up and he was great - some of the speakers are gonna have a problem to follow him!
We&#8217;ve taken a look at the schedule for today and it looks [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/12/10/hello-from-devoxx/";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>This week, some The Server Labs employees are at the <a href=" http://www.devoxx.com">Java Devoxx conference</a> in Antwerp, Belgium.</p>
<p>We&#8217;ve just had a human beat box guy warming the crowd up and he was great - some of the speakers are gonna have a problem to follow him!</p>
<p>We&#8217;ve taken a look at the schedule for today and it looks like we&#8217;re gonna see some really cool presentations on Spring, Security/Hacking, Performance/Concurrency and lots of rich internet apps - they&#8217;re giving the JavaFX keynote as I write this - lots of Adobe Flex and Air talks and even a Microsoft Silverlight talk.</p>
<p>We&#8217;ll try and give you some updates later on some of the more interesting talks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theserverlabs.com/blog/2008/12/10/hello-from-devoxx/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Distributed JUnit testing with GridGain</title>
		<link>http://www.theserverlabs.com/blog/2008/11/24/distributed-junit-testing-with-gridgain/</link>
		<comments>http://www.theserverlabs.com/blog/2008/11/24/distributed-junit-testing-with-gridgain/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 14:36:23 +0000</pubDate>
		<dc:creator>Alfonso Olias</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[Continuous Integration]]></category>

		<category><![CDATA[GRID]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Java EE]]></category>

		<category><![CDATA[SOA]]></category>

		<category><![CDATA[Software Engineering]]></category>

		<category><![CDATA[Testing]]></category>

		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.theserverlabs.com/blog/?p=167</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/11/24/distributed-junit-testing-with-gridgain/";</script>Recently we have been running some problems while testing distributed applications with JUnit. The main problem was that we were running the client and the server within the same host. Although the test passed because the application logic was correct. Running the application distributed failed due to some errors related with the naming of the [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/11/24/distributed-junit-testing-with-gridgain/";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>Recently we have been running some problems while testing distributed applications with <a href="http://www.junit.org/">JUnit</a>. The main problem was that we were running the client and the server within the same host. Although the test passed because the application logic was correct. Running the application distributed failed due to some errors related with the naming of the processes that were related to localhost.</p>
<p>How to test distributed applications with JUnit?. The only product that can do that is <a href="http://www.gridgain.com/">GridGain</a>.  GridGain is an open source framework for distributed computing. It also provides a way of running tests distributed across many nodes. This means that we can parallelize our JUnit tests on different nodes and improve the overall time to get them done. But what it is more important for us. How to test distributed applications that require client server interaction.</p>
<p><strong>Configuration</strong><br />
GridGain is easy to set up. Once you have downloaded and uncompressed the zip file. You only have to set up two environment variables<strong> <em>JAVA_HOME</em></strong> and<em> <strong>GRIDGAIN_HOME</strong></em>.  Now you are ready to launch your remote execution node by executing the following script <strong><em>./gridgain-junit.sh</em></strong></p>
<p><strong>Let&#8217;s make a JUnit test</strong></p>
<p>I am using eclipse, but you can use your preferred java builder.  Once you have created a project you only have to import the jar files included in the <em>libs</em> folder and also the gridgain-2.0.3.jar file. And you will be ready to implement you unit tests.</p>
<ul>
<li><em>ServerTest class:</em> This test just runs a server socket waiting for incoming calls. Reads a Date object instance sent by the client and prints it out.</li>
</ul>
<pre style="border: 1px dashed #999999; padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: #000000; background-color: #eeeeee; font-size: 12px; line-height: 14px; width: 100%;"><code>import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ServerTest {
    /**
     * Set up logic.
     * @throws Exception Thrown in case of any error.
     */
    @Before
    public void beforeTest() throws Exception {
        System.out.println("Preparing for test execution: " + getClass().getSimpleName());
    }

    /**
     * Tear down logic.
     * @throws Exception Thrown in case of any error.
     */
    @After
    public void afterTest() throws Exception {
        System.out.println("Tearing down test execution: " + getClass().getSimpleName());
    }

    /**
     * Example test method.
     */
    @Test
    public void testServer() {
      boolean stop = false;
      ServerSocket serverSocket = null;
      final String hostName = "gaiawl06.net4.lan";
      try {
          InetAddress addr = InetAddress.getLocalHost();

          // Get IP Address
          byte[] ipAddr = addr.getAddress();
          // Get hostname
          if (hostName.compareTo(addr.getHostName())==0){
              serverSocket = new ServerSocket(4000);
              while (!stop){
                  Socket client =  serverSocket.accept();
                  System.out.println(getClass().getSimpleName() +" Incomming DATA! " + client.getInetAddress());
                  ObjectInputStream in = new ObjectInputStream(client.getInputStream());
                  ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
                  final Date date  = (Date)in.readObject();
                  System.out.println(getClass().getSimpleName() +" Socket read Object from client " + date);
                  in.close();
                  out.close();
                  stop = true;
              }
          }
      } catch (UnknownHostException e) {

          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      } catch (ClassNotFoundException e) {
          e.printStackTrace();
      }finally{
          try {
              if(serverSocket != null){
                  serverSocket.close();
              }
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
      System.out.println(getClass().getSimpleName() + "Output from TestC.testMethod1().");
    }
}
</code></pre>
<ul>
<li><em>ClientTest class:</em> This test just opens a socket to the remote server and sends  a Date object instance to the remote server.</li>
</ul>
<pre style="border: 1px dashed #999999; padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: #000000; background-color: #eeeeee; font-size: 12px; line-height: 14px; width: 100%;"><code>import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Date;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ClientTest {
    /**
     * Set up logic.
     * @throws Exception Thrown in case of any error.
     */
    @Before
    public void beforeTest() throws Exception {
        System.out.println("Preparing for test execution: " + getClass().getSimpleName());
    }

    /**
     * Tear down logic.
     * @throws Exception Thrown in case of any error.
     */
    @After
    public void afterTest() throws Exception {
        System.out.println("Tearing down test execution: " + getClass().getSimpleName());
    }

    @Test
    public void testClient() {
        try {
             System.out.println(getClass().getSimpleName() +" Wait 5 seconds server to start ");
             Thread.sleep(5000);
             final String hostName = "xxxxxxxxxxx";
             // open a socket connection
             Socket socket = new Socket(hostName, 4000);
             // open I/O streams for objects
             ObjectOutputStream ou = new ObjectOutputStream(socket.getOutputStream());
             ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
             ou.writeObject(new Date());
             ou.flush();
             ou.close();
             in.close();
           } catch(Exception e) {
             System.out.println(e.getMessage());
          }
    }
}
</code></pre>
<p>You have to bear in mind that the ServerTest has to run at the remote host were the GridGain daemon is running. Just if you want the client to be able to connect the remote server.</p>
<p>Now is were the magic comes.  We have to ensure that the ServerTest runs on the remote host and the ClientTest runs on the local host (my computer).  In order to get this working we need three more classes:</p>
<ol>
<li>RemoteTestSuite</li>
<li>LocalTestSuite</li>
<li>DistributedTestSuite</li>
</ol>
<ul>
<li><em>RemoteTestSuite class</em>: It is used to set up the tests we want to run distributed. We only have to add the <strong><em>@GridifyTest</em></strong> annotation and we will enable this suite to run in our GridGain grid. This does not prevent the test to run locally, so if we want to enforce the test to run on the remote host we have to add the following JVM parameter <strong><em> -DGRID_ROUTER_PREFER_REMOTE=true</em></strong></li>
</ul>
<pre style="border: 1px dashed #999999; padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: #000000; background-color: #eeeeee; font-size: 12px; line-height: 14px; width: 100%;"><code>import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import org.gridgain.grid.test.GridifyTest;

@RunWith(Suite.class)
@SuiteClasses(ServerTest.class)
@GridifyTest
public class RemoteTestSuite {
}
</code></pre>
<ul>
<li><em>LocalTestSuite class:</em> is used to run the client test locally. We only have to add the <em>@RunWith(GridJunit4LocalSuite.class)</em> annotation to enforce this test to run locally.</li>
</ul>
<pre style="border: 1px dashed #999999; padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: #000000; background-color: #eeeeee; font-size: 12px; line-height: 14px; width: 100%;"><code>import org.gridgain.grid.test.junit4.GridJunit4LocalSuite;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(GridJunit4LocalSuite.class) // Specify local suite to run tests.
@SuiteClasses(ClientTest.class)
public class LocalTestSuite {
}
</code></pre>
<ul>
<li><em>DistributedTestSuite class</em>: is used to configure the distributed test we want to run. In our case is composed of two tests that will run in parallel and distributed. You will have to add the following  annotation <em>@RunWith(GridJunit4Suite.class)</em> if you want GridGain to run the test.</li>
</ul>
<p>This class is the one you have to run in your eclipse project and before running it you have to set up the JVM with the parameter I mentioned before.</p>
<pre style="border: 1px dashed #999999; padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: #000000; background-color: #eeeeee; font-size: 12px; line-height: 14px; width: 100%;"><code>import org.gridgain.grid.test.junit4.GridJunit4Suite;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(GridJunit4Suite.class)
@SuiteClasses({
    RemoteTestSuite.class,
    LocalTestSuite.class, // Local suite that will execute its test locally.
})
public class DistributedTestSuite {
}
</code></pre>
<p><strong>Conclusions</strong><br />
GridGain is based on JGroups  so be sure that  the agents are  on the same network If they do not see one each other you will not  be able to send your  tests to the remote node. It is pretty easy to set up and make it run. Even  getting your Junit tests being executed distributed, it is very easy.<br />
This product fills the gap for testing distributed applications with JUnit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theserverlabs.com/blog/2008/11/24/distributed-junit-testing-with-gridgain/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Database storage in TIBCO EMS 5.0</title>
		<link>http://www.theserverlabs.com/blog/2008/10/10/database-storage-in-tibco-ems-50/</link>
		<comments>http://www.theserverlabs.com/blog/2008/10/10/database-storage-in-tibco-ems-50/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 17:31:59 +0000</pubDate>
		<dc:creator>Haritza Zubillaga</dc:creator>
		
		<category><![CDATA[EAI]]></category>

		<category><![CDATA[TIBCO]]></category>

		<category><![CDATA[EMS]]></category>

		<category><![CDATA[JMS]]></category>

		<guid isPermaLink="false">http://www.theserverlabs.com/blog/?p=142</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/10/10/database-storage-in-tibco-ems-50/";</script>Earlier this year TIBCO released a new version of their particular implementation of the JMS standard. TIBCO Enterprise Message Service 5.0 which, among others, includes some features which I personally consider very interesting.
One of them is the possibility to store persistent messages in a database. In previous versions, the only possibility was to use file [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/10/10/database-storage-in-tibco-ems-50/";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>Earlier this year <a title="TIBCO" href="http://www.tibco.com" target="_blank">TIBCO</a> released a new version of their particular implementation of the <a title="JMS" href="http://java.sun.com/products/jms/" target="_blank">JMS</a> standard. TIBCO <a title="TIBCO EMS" href="http://www.tibco.com/software/messaging/enterprise_messaging_service/default.jsp" target="_blank">Enterprise Message Service</a> 5.0 which, among others, includes some features which I personally consider very interesting.</p>
<p>One of them is the possibility to store persistent messages in a database. In previous versions, the only possibility was to use file based storage. In case you wanted to use fault tolerant groups of servers, this caused some difficulties as having both the messages and the shared state information in files required them to be in a shared storage device, either via hardware (<a title="SAN" href="http://en.wikipedia.org/wiki/Storage_area_network" target="_blank">SCSI and SAN</a>, <a title="NAS" href="http://en.wikipedia.org/wiki/Network_attached_storage" target="_blank">NAS </a>or NAS with <a title="NFS" href="http://en.wikipedia.org/wiki/Network_File_System_(protocol)" target="_blank">NFS</a>) or software (Cluster Server or Clustered File System). These solutions are expensive and hard to maintain while using a database eases the configuration and leaves the hard work on the DBMS. You can even combine file and database based storage depending on the queue or topic.</p>
<p>Database storage is based in <a title="Hibernate" href="http://www.hibernate.org/" target="_blank">Hibernate</a>, so any database server supported by Hibernate could be used to store the data. To use it, first we will need to enable it, setting the following parameters in the <em>tibemsd.conf </em>file:</p>
<ul>
<li><code>dbstore_classpath:</code> pointing to the hibernate and DB driver jar files.</li>
<li><code>dbstore_driver_name:</code> specifies the jdbc driver.</li>
<li><code>dbstore_driver_dialect:</code> specifies the hibernate driver dialect.<em> </em></li>
<li><code>jre_library:</code> associated JVM libraries.</li>
</ul>
<p>Second, we will have to create the stores in the <em>stores.conf</em> file, for example:</p>
<p style="padding-left: 30px;"><code>[TSLstore]<br />
type=dbstore<br />
dbstore_driver_url=jdbc:mysql:thin:localhost:3306:TSLDB<br />
dbstore_driver_username=anonymous<br />
dbstore_driver_password=anonymous</code></p>
<p>Third, link the destinations with the appropriate store, either in the <em>topics.conf</em> and <em>queues.conf</em> files or using the command line administration tool with the <em>setprop </em>command, e.g.
</p>
<p style="padding-left: 30px;"><code>setprop topic my.topic store=dbstore</code></p>
<p>Finally, we will need to export the EMS database tables using the EMS Schema export tool provided with EMS:</p>
<p style="padding-left: 30px;"><code>java -jar &lt;EMS_home&gt;/bin/tibemsd_util.jar -tibemsdconf &lt;route_to_tibemds.conf&gt;/tibemsd.conf -createall -export</code></p>
<p>As a postscript, let me recommend you not to install EMS as <em>root</em>, at least in a <a title="Solaris Operating System" href="http://en.wikipedia.org/wiki/Solaris_(operating_system)" target="_blank">Solaris</a> machine. With EMS 5.0 version it will not work unless you change the owner after the installation. This happens because once installed, if we try to run in as root, Solaris, due to security reasons, will execute the process with the user <em>nobody4 </em>but the folder which will contain the datastore files (if we choose file-based storage) will have write permissions set only for <em>root </em>user. As EMS will not be able to create the datastores, it will automatically shutdown. Moreover, even if we change the rights of that folder we will have the same problem with the configuration files, they will only have write permissions for <em>root </em>user which will return errors if we try to change the configuration using the command line administration tool.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theserverlabs.com/blog/2008/10/10/database-storage-in-tibco-ems-50/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Google Developer Day Madrid 2008</title>
		<link>http://www.theserverlabs.com/blog/2008/09/26/google-developer-day-madrid-2008/</link>
		<comments>http://www.theserverlabs.com/blog/2008/09/26/google-developer-day-madrid-2008/#comments</comments>
		<pubDate>Fri, 26 Sep 2008 10:18:23 +0000</pubDate>
		<dc:creator>Diego Parrilla</dc:creator>
		
		<category><![CDATA[Company Culture]]></category>

		<category><![CDATA[events]]></category>

		<guid isPermaLink="false">http://www.theserverlabs.com/blog/?p=130</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/09/26/google-developer-day-madrid-2008/";</script>Yesterday I went to the Google Developer Day in Madrid. I was lucky because some colleagues filled the request form but they were not accepted by Google. A pity because the event was very interesting. 

The event took place in the Parque de Atracciones de Madrid, which is a popular amusement park.  Some might think that this [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/09/26/google-developer-day-madrid-2008/";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>Yesterday I went to the <a href="http://code.google.com/intl/es_ALL/events/developerday/2008/home.html" target="_blank">Google Developer Day</a> in Madrid. I was lucky because some colleagues filled the request form but they were not accepted by Google. A pity because the event was very interesting. </p>
<p><a href="http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/25092008006.jpg"><img class="aligncenter size-medium wp-image-136" title="Google Pin" src="http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/25092008006-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>The event took place in the Parque de Atracciones de Madrid, which is a popular amusement park.  Some might think that this kind of place is not very appropriate for a technical event, but I think the main auditorium and the small conference rooms were good enough. I saw some people on the rides in the park but I don&#8217;t know if they were people attending to the event or not.</p>
<p>The event started at 10.00AM and began with an introduction by <a href="http://www.lalistawip.com/personaje/Javier+Rodr%EDguez+Zapatero_12049902/" target="_blank">Javier Rodriguez Zapatero</a>, the CEO of Google in Spain. He gave a short introduction about how proud he was to be working in Google (he was a former Yahoo Employee) , how he admires engineers and how hard his team has been working to set up the event. He left the stage to <a href="http://en.wikipedia.org/wiki/Chris_DiBona" target="_blank">Chris DiBona</a>, a editor of <a href="http://www.slashdot.org">slashdot.org</a> and open source evangelist and guru. Chris promotes several projects in code.google.com and he also manages the Google Summer of Code. Just like all the speakers he gave an excellent speech of why Google supports open source and will support open source more and more in the future. The argument he gave was: &#8220;Google has grown to what it is thanks to a vast amount of opensource code, so Google wants to give back to the community part of their success opening the code of projects and offering open platforms&#8221;. He also mentioned that the bigger the internet, the better for Google. He also introduced the people from Chrome, Android and AppEngine.</p>
<p>Note: I was surprised that more than 50% of the people did not need a translator from English to Spanish to understand the conferences. And this is really, really good for us Spaniards.</p>
<p>I decided to attend to the AppEngine Workshop in the morning, and &#8216;Startups mentoring&#8217;, &#8216;App Engine&#8217;, &#8216;Android&#8217;, and &#8216;Future of Webapps&#8217; in the afternoon. The AppEngine Workshop was a three hour workshop called &#8216;The Hackaton&#8217; where we try to develop something using the AppEngine. I have never developed with Python before, so this Hackaton was like a crash course for me in Python and AppEngine technology. The AppEngine is a development framework for python and a runtime environment that can scale <em>&#8216;a-la-google&#8217;</em> because it uses what makes Google a scalability beast: Big Table and other technologies. If you are familiar with any MVC framework you will get how to develop the web applications with it (because you can only develop web applications: so forget about running your batch processes here!). The access to Big Table is wrapped with a direct mapping of Python database model classes. It&#8217;s possible to create 1:1, 1:N and N:M relationships, and all relationships are bi-directional by default. As <a href="http://www.flickr.com/photos/aallan/2861702619/" target="_blank">Mano Marks</a> told me, forget about ORM, there is no relational database underneath, just plain access to Big Table. As a Java Enterprise architect most of the time I&#8217;m tied to one or more relational databases in my projects, so it sounded to me like something risky (explosive growth of objects in ORM is quite normal) but he told me it was not a problem. Well, until I can test it in details this is will be a question of faith in the Google Engineers.</p>
<p>After the workshop came the lunch and then I realized how big the event was: hundreds of hungry developers fighting for french fries and meat like it was the first time they had eaten in days. Probably next year it would be a good idea to schedule several groups for lunch time. BTW, less than 40&#8242; of lunch time in Spain? Imposible! And without an expresso afterwards? No way!</p>
<p>My first event in the afternoon was the &#8216;Startups Mentoring&#8217; performed by <a href="http://www.eduardomanchon.com/" target="_self">Eduardo Manchón</a>, co-founder of <a href="http://www.panoramio.com/" target="_blank">Panoramio</a>. The room was incredibly crowded and I had to stand up at the back of the room. The conference talk was focused on how to make your web site or community to become a successful product. The goal is &#8216;let people use your site to create a community, don&#8217;t try to drive them, they will drive you&#8217;. And believe me that Eduardo is one of the most incredible Spaniard speakers I have met in years (the conference was in spanish and english). He said that there is room for &#8216;micro-companies&#8217; of two or three people that can live thanks to adsense.</p>
<p>Later on I went back to the main auditorium to listen to the AppEngine speech by <a href="http://www.flickr.com/photos/aallan/2861702619/" target="_blank">Mano Marks</a>. The speech focused on the capabilities of the AppEngine and the future. Google will charge a small fee for more processing power, storage and hits therefor allowing successful projects to grow. As I mentioned, AppEngine currently only supports Python and people kept asking Mano which languages would be supported in the future – the Spanish members of the audience were especially interested in Java. He did not say which languages will be supported, but he said that there is a language that it will be not supported: COBOL <img src='http://www.theserverlabs.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/25092008.jpg"><img class="aligncenter size-medium wp-image-138" title="Mano Marks on Stage" src="http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/25092008-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>The next talk was performed by Mike Jennings and was about Google Android. The first part of the speech was about the architecture of Android. Android is a Linux based platform for smartphones that implements a Java Virtual Machine named <a href="http://en.wikipedia.org/wiki/Dalvik_virtual_machine" target="_blank">Dalvik</a> which allows the execution of vast set of applications in &#8216;User mode&#8217; on any device. It comes to fix the problem of fragmentation of operating systems and JVM implementations of the mobile market. The platform is opensource and it is given for free to any device manufacturer. The second part of the speech he showed a demo of the SDK (1.0 was released this week).  If you are familiar with Java and Eclipse developing for this device looks really easy, specially compared with the nightmare of Java ME development.</p>
<p>And finally in my opinion the jewel of the crown, the best presentation so far: The future of Webapps by <a href="http://almaer.com" target="_blank">Dion Almaer</a>. Dion Almaer is one of the gurus of web development and founder of the site of reference <a href="http://www.ajaxian.com">Ajaxian</a>. He said a lot of interesting things, but he emphasized on how interactivity and visual design come hand in hand, and you have to consider both to have a successful project. If you are a developer you should delegate the visual design and interactivity to experts and focus on the technicall stuff. He also talked about the evolution of the browsers and how their improvements will bring a new age to the web after ten years of darkness. He also gave an overview of some of the key JavaScript libraries.</p>
<p style="text-align: center;"><a href="http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/25092008001.jpg"><img class="size-medium wp-image-139 aligncenter" title="Dion Almaer on Stage" src="http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/25092008001-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>There was a party later on but I could not attend: a pity because everything everybody was in a hurry during all day and looked like the perfect place for networking. Did you go the party?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theserverlabs.com/blog/2008/09/26/google-developer-day-madrid-2008/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Developing Custom Hudson Plugins: integrate with your own applications</title>
		<link>http://www.theserverlabs.com/blog/2008/09/24/developing-custom-hudson-plugins-integrate-with-your-own-applications/</link>
		<comments>http://www.theserverlabs.com/blog/2008/09/24/developing-custom-hudson-plugins-integrate-with-your-own-applications/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 14:32:26 +0000</pubDate>
		<dc:creator>Diego Parrilla</dc:creator>
		
		<category><![CDATA[Continuous Integration]]></category>

		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.theserverlabs.com/blog/?p=113</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/09/24/developing-custom-hudson-plugins-integrate-with-your-own-applications/";</script>Hudson is a very good Continuous Integration (CI) tool. Though such tools are not new, it clearly sets a higher standard in terms of quality and extensibility compared to first generation CI tools like Cruise-Control. And it&#8217;s open-source. (If you are reading this and you don&#8217;t know what Continuous Integration is, read this paper written by Martin Fowler [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/09/24/developing-custom-hudson-plugins-integrate-with-your-own-applications/";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><div><a id="gidk" title="Hudson" href="http://hudson.dev.java.net/">Hudson</a> is a very good Continuous Integration (CI) tool. Though such tools are not new, it clearly sets a higher standard in terms of quality and extensibility compared to first generation CI tools like <a id="g6.x" title="CruiseControl" href="http://cruisecontrol.sourceforge.net/">Cruise-Control</a>. And it&#8217;s open-source. (If you are reading this and you don&#8217;t know what Continuous Integration is, read <a id="p19t" title="this paper" href="http://martinfowler.com/articles/continuousIntegration.html">this paper</a> written by <a id="zpcd" title="Martin Fowler" href="http://martinfowler.com/aboutMe.html">Martin Fowler</a> for more information).</div>
<p></p>
<div>One of best features of Hudson is how easy is to extend it. As result there are many plug-ins developed by third parties that can perform a lot of tasks related to the activity of a development team. You can find the list of plug-ins available <a id="gnps" title="here" href="http://hudson.gotdns.com/wiki/display/HUDSON/Plugins">here</a>. It&#8217;s a long list, but it does not mean they will cover everyone&#8217;s needs. If there is no plugin that covers your requirements then this blog post for you!</div>
<p></p>
<div>The development of a custom Hudson plug-in is not a daunting task. There are some tutorials out there that can help you to quick-start the development. The best ones are <a id="x_sd" title="this" href="http://hudson.gotdns.com/wiki/display/HUDSON/Plugin+tutorial">this</a> and <a id="u19q" title="this" href="http://javaadventure.blogspot.com/2008/01/writing-hudson-plug-in-part-1.html">this</a> in my humble opinion. You need some background in Maven and Web development to start. Using Maven you will be able to create the basic infrastructure in minutes, and you will be able to start coding and testing the plug-in inside Jetty.</div>
<p></p>
<div>On a recent project, we had to integrate Hudson with a Requirements Management and Bug Fixing application which our customer had developed in-house. The application satisfied their needs and it was out of the scope to change to another like Bugzilla or JIRA, which integrate almost seamlessly with Hudson.</div>
<p></p>
<div>Our customer wanted to change the status of some requirements and bug fixes when a Nightly Build and all the set of automatic unit, integration and acceptance tests were executed successfully. On success, Hudson should execute a stored procedure in the database that the application used, thereby triggering actions like measuring metrics of performance, reporting to quality assurance teams and others.</div>
<p></p>
<div>
We didn&#8217;t want to reinvent the wheel, so in writing our plugin,we took the approach taken by others tools – when the user commits code to the SCM, they must write comments in a certain format which contain information for the relevant requirement/bug information (bug or requirement ID etc).  On a successful build, the Hudson plugin retrieves the relevant information from all code comments and passes it to the requirement/bug system via the stored procedure.</div>
<p></p>
<div>Maven can create for you the default structure of directories and files thanks to the Hudson plug-in (see <a id="vlkf" title="this" href="http://hudson.gotdns.com/wiki/display/HUDSON/Plugin+tutorial">this</a>). And the plug-in structure created by Maven is:</div>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">+ src
    + main
        + java
             +  full.package.name
                    +- MyClassPublisher.java
                    +- PluginImpl.java
                +  full.package.name
                                +- config.jelly
                                +- global.jelly
                +- index.jelly
        + webapp
            +- help-globalConfig.html
            +- help-projectConfig.html
+ src
    + <span style="color: #7a0874; font-weight: bold;">test</span>
        + java
        + resources
        +  full.package.name</pre></div></div>

<div>We can identify here several key files and classes:</div>
<h2><span style="font-family: Courier New;">PluginImpl.java</span></h2>
<div>
is a class generated automatically by Maven, and it&#8217;s the class that registers the action to perform by the plug-in. The default type of action is of the class <a id="dxje" title="Builder" href="https://hudson.dev.java.net/nonav/javadoc/?hudson/tasks/Builder.html">Builder</a>, but we are more interested in performing an action when the building process is successful: so we use the type <a id="b68v" title="Publisher" href="https://hudson.dev.java.net/nonav/javadoc/?hudson/tasks/Builder.html">Publisher</a>. We need to change the code in the method start to look like this:</div>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> start<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// plugins normally extend Hudson by providing custom implementations</span>
        <span style="color: #666666; font-style: italic;">// of ‘extension points’. In this example, we’ll add one builder.</span>
<span style="color: #666666; font-style: italic;">//        BuildStep.BUILDERS.add(HelloWorldBuilder.DESCRIPTOR);</span>
        Publisher.<span style="color: #006633;">PUBLISHERS</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>TSLPublisher.<span style="color: #006633;">DESCRIPTOR</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span></pre></div></div>

<div>
Do not modify the class, Hudson detects your plug-in (via its <tt>@plugin</tt> javadoc annotation), creates an instance, and invokes methods.</div>
<div>
<h2 style="font-family: Courier New;">TSLPublisher.java</h2>
<p>is a class that extends the Publisher class and it&#8217;s main purpose is to perform an action once the build process has been completed successfully. An example of Publishers are report generation tools or email sending. This class should look like this:</p></div>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> TSLPublisher <span style="color: #000000; font-weight: bold;">extends</span> Publisher <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> Logger logger <span style="color: #339933;">=</span> Logger.<span style="color: #006633;">getLogger</span><span style="color: #009900;">&#40;</span>TSLPublisher.<span style="color: #000000; font-weight: bold;">class</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Boolean</span> enable;
&nbsp;
    @DataBoundConstructor
    <span style="color: #000000; font-weight: bold;">public</span> TSLPublisher<span style="color: #009900;">&#40;</span><span style="color: #003399;">Boolean</span> enable<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">enable</span> <span style="color: #339933;">=</span> enable;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * We’ll use this from the &lt;tt&gt;config.jelly&lt;/tt&gt;.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Boolean</span> getEnable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> enable;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> needsToRunAfterFinalized<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span>;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * This method should have the logic of the plugin. Access the configuration
     * and execute the the actions.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> perform<span style="color: #009900;">&#40;</span>Build build, Launcher launcher, BuildListener listener<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        logger.<span style="color: #006633;">info</span><span style="color: #009900;">&#40;</span>”Performing update…”<span style="color: #009900;">&#41;</span>;
        <span style="color: #666666; font-style: italic;">// TODO: WRITE THE LOGIC OF YOUR PLUGIN HERE!!!!</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span>;
    <span style="color: #009900;">&#125;</span>
&nbsp;
     <span style="color: #000000; font-weight: bold;">public</span> Descriptor<span style="color: #339933;">&lt;</span>publisher<span style="color: #339933;">&gt;</span> getDescriptor<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #000000; font-weight: bold;">return</span> DESCRIPTOR;
     <span style="color: #009900;">&#125;</span>
&nbsp;
     <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Action</span> getProjectAction<span style="color: #009900;">&#40;</span>AbstractProject<span style="color: #339933;">&lt;</span> <span style="color: #339933;">?</span>, <span style="color: #339933;">?&gt;</span> project<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span>;
     <span style="color: #009900;">&#125;</span>
&nbsp;
     <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * Descriptor should be singleton.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> DescriptorImpl DESCRIPTOR <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DescriptorImpl<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * Descriptor for {@link TSLPublisher}. Used as a singleton.
     * The class is marked as public so that it can be accessed from views.
     *
     * &lt;p&gt;
     * See &lt;tt&gt;global.jelly&lt;/tt&gt;
     * for the actual HTML fragment for the configuration screen.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">class</span> DescriptorImpl <span style="color: #000000; font-weight: bold;">extends</span> Descriptor<span style="color: #339933;">&lt;</span>publisher<span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #008000; font-style: italic; font-weight: bold;">/**
         * To persist global configuration information,
         * simply store it in a field and call save().
         *
         * &lt;p&gt;
         * If you don’t want fields to be persisted, use &lt;tt&gt;transient&lt;/tt&gt;.
         */</span>
        <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> field;
&nbsp;
        <span style="color: #000000; font-weight: bold;">protected</span> DescriptorImpl<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>TSLPublisher.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>;
            load<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #008000; font-style: italic; font-weight: bold;">/**
         * This human readable name is used in the configuration screen.
         */</span>
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getDisplayName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> “<span style="color: #000000; font-weight: bold;">This</span> is the TSL Sample Plugin”;
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #008000; font-style: italic; font-weight: bold;">/**
         * Get the fields from the configuration form and persist them.
         */</span>
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> configure<span style="color: #009900;">&#40;</span>HttpServletRequest req<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> FormException <span style="color: #009900;">&#123;</span>
            uri <span style="color: #339933;">=</span> req.<span style="color: #006633;">getParameter</span><span style="color: #009900;">&#40;</span>”tsl.<span style="color: #006633;">field</span>”<span style="color: #009900;">&#41;</span>;
            save<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
            logger.<span style="color: #006633;">fine</span><span style="color: #009900;">&#40;</span>”Saved TSL configuration”<span style="color: #009900;">&#41;</span>;
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">configure</span><span style="color: #009900;">&#40;</span>req<span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #008000; font-style: italic; font-weight: bold;">/**
         * Creates a new instance of {@link TSLPublisher} from a submitted form.
         */</span>
        <span style="color: #000000; font-weight: bold;">public</span> TSLPublisher newInstance<span style="color: #009900;">&#40;</span>StaplerRequest req<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> FormException <span style="color: #009900;">&#123;</span>
            logger.<span style="color: #006633;">fine</span><span style="color: #009900;">&#40;</span>”<span style="color: #000000; font-weight: bold;">New</span> instance <span style="color: #000000; font-weight: bold;">for</span> a job”<span style="color: #009900;">&#41;</span>;
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> TSLPublisher<span style="color: #009900;">&#40;</span>req.<span style="color: #006633;">getParameter</span><span style="color: #009900;">&#40;</span>”tsl.<span style="color: #006633;">enable</span>”<span style="color: #009900;">&#41;</span><span style="color: #339933;">!=</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getField<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> field;
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setField<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> field<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">field</span> <span style="color: #339933;">=</span> field;
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>    
<span style="color: #009900;">&#125;</span>
<span style="color: #339933;">&lt;/</span>p<span style="color: #339933;">&gt;&lt;/</span>publisher<span style="color: #339933;">&gt;&lt;/</span>p<span style="color: #339933;">&gt;&lt;/</span>publisher<span style="color: #339933;">&gt;</span></pre></div></div>

<div>
All the information I have found about plug-ins explains how to write a Builder. Publisher is similar. You have to modify:</p>
<ul>
<li>The perform method do the real thing. To get the configuration parameters, use the DESCRIPTOR singleton to access the POJOs.</li>
<li>The inner class DescriptorImpl extends Descritor&lt;Publisher&gt;. It is instantiated once and accessed by a Singleton.
<ul>
<li>The <span style="font-family: Courier New;">configure()</span> method reads the parameters and persists them.</li>
<li>The <span style="font-family: Courier New;">newInstance()</span> should return an instance of the TSLPublisher to perform the action. I have implemented an enable check. When not enabled, there is no instance for this job.</li>
<li>All the fields can persist by default. Use transient if you don&#8217;t want to persist.</li>
</ul>
</li>
</ul>
</div>
<div>
<h2><span style="font-family: Courier New;">global.jelly</span></h2>
<p>is a file generated automatically by Maven, and it&#8217;s the Jelly Script file to produce the global configuration option. It&#8217;s automatically added to the configuration pages of Hudson after deployment. It uses Jelly as scripting language (I think this is a bizarre decision, but it&#8217;s not important), you can find information about Jelly <a id="j.yo" title="here" href="http://commons.apache.org/jelly/">here</a>. In our example the file looks like this:
</div>

<div class="wp_syntax"><div class="code"><pre class="xml xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;j</span> :jelly <span style="color: #000066;">xmlns:j</span>=<span style="color: #ff0000;">&quot;jelly:core&quot;</span> <span style="color: #000066;">xmlns:st</span>=<span style="color: #ff0000;">&quot;jelly:stapler&quot;</span> <span style="color: #000066;">xmlns:d</span>=<span style="color: #ff0000;">&quot;jelly:define&quot;</span> </span>
<span style="color: #009900;">         <span style="color: #000066;">xmlns:l</span>=<span style="color: #ff0000;">&quot;/lib/layout&quot;</span> <span style="color: #000066;">xmlns:t</span>=<span style="color: #ff0000;">&quot;/lib/hudson&quot;</span> <span style="color: #000066;">xmlns:f</span>=<span style="color: #ff0000;">&quot;/lib/form&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;f</span> :section <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;TSL Integration&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/f<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;f</span> :entry <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Field Test&quot;</span> <span style="color: #000066;">help</span>=<span style="color: #ff0000;">&quot;${rootURL}/plugin/tsl/help-globalConfig.html&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;f</span> :textbox <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;tsl.field&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;${descriptor.field}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/f<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/j<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<div>
The values in the form are stored in the <span style="font-family: Courier New;">${descriptor.fieldname}</span>, and the parameters can be referred with a unique name like <span style="font-family: Courier New;">&#8216;tsl.field&#8217;</span>. It&#8217;s also possible to link help files as described in the example. Be sure that you are using the variable &#8216;descriptor&#8217; to access the information.
</div>
<div>
<h2><span style="font-family: Courier New;">config.jelly</span></h2>
<p>is a file generated automatically by Maven, and it&#8217;s the Jelly Script file to produce the configuration option specific for the job. In our example the file looks like this:</p></div>

<div class="wp_syntax"><div class="code"><pre class="xml xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;j</span> :jelly <span style="color: #000066;">xmlns:j</span>=<span style="color: #ff0000;">&quot;jelly:core&quot;</span> <span style="color: #000066;">xmlns:st</span>=<span style="color: #ff0000;">&quot;jelly:stapler&quot;</span> <span style="color: #000066;">xmlns:d</span>=<span style="color: #ff0000;">&quot;jelly:define&quot;</span> </span>
<span style="color: #009900;">         <span style="color: #000066;">xmlns:l</span>=<span style="color: #ff0000;">&quot;/lib/layout&quot;</span> <span style="color: #000066;">xmlns:t</span>=<span style="color: #ff0000;">&quot;/lib/hudson&quot;</span> <span style="color: #000066;">xmlns:f</span>=<span style="color: #ff0000;">&quot;/lib/form&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;f</span> :entry  <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Check to enable this publisher for the job&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;f</span> :checkbox <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;tsl.enable&quot;</span> <span style="color: #000066;">checked</span>=<span style="color: #ff0000;">&quot;${instance.enable}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/f<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/j<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<div>
The values in the form are stored in the <span style="font-family: Courier New;">${instance.fieldname}</span>, and the parameters can be referred with a unique name like <span style="font-family: Courier New;">&#8216;tsl.enabled&#8217;</span>. It&#8217;s also possible to link help files as described in the example of global.jelly. Be sure that you are using the variable &#8216;instance&#8217; to access the information.</p>
<p>And that&#8217;s all you need to develop a Publisher Hudson Plug-in. You can test it <a id="mryf" title="following the instructions in the Hudson wiki" href="http://hudson.gotdns.com/wiki/display/HUDSON/Plugin+tutorial">following the instructions in the Hudson wiki</a>.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.theserverlabs.com/blog/2008/09/24/developing-custom-hudson-plugins-integrate-with-your-own-applications/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Automated integration testing with Selenium, Maven and Jetty</title>
		<link>http://www.theserverlabs.com/blog/2008/09/17/automated-integration-testing-with-selenium-maven-and-jetty/</link>
		<comments>http://www.theserverlabs.com/blog/2008/09/17/automated-integration-testing-with-selenium-maven-and-jetty/#comments</comments>
		<pubDate>Wed, 17 Sep 2008 08:22:18 +0000</pubDate>
		<dc:creator>Kevin McCormack</dc:creator>
		
		<category><![CDATA[Default]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Java EE]]></category>

		<category><![CDATA[Testing]]></category>

		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.theserverlabs.com/blog/?p=95</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/09/17/automated-integration-testing-with-selenium-maven-and-jetty/";</script>Here at The Server Labs we place a high value on automated unit and integration tests and believe that they are fundamental whether you are using an agile methodology or not. 
We use Maven on the vast majority of our projects and we often use Jetty as a web container in plain Java web projects [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/09/17/automated-integration-testing-with-selenium-maven-and-jetty/";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>Here at The Server Labs we place a high value on automated unit and integration tests and believe that they are fundamental whether you are using an agile methodology or not. </p>
<p>We use Maven on the vast majority of our projects and we often use Jetty as a web container in plain Java web projects (i.e. those that don&#8217;t require a full JEE container). Often the deployment environment is not Jetty (it might be Oracle AS or WebLogic for example) but Jetty is so well integrated with Maven that the costs of not developing on the deployment platform are outweighed by the ease-of-development benefits. </p>
<p>Selenium is a common choice for writing integration tests for web application - and one that we have used on various projects in the past. The idea is that you interact with your web application using Firefox and the Selenium IDE plugin records the test. You can then replay this test as part of the &#8216;integration-test&#8217; Maven phase for your application, hence building up a suite of integration tests to run.  </p>
<p>Putting all of this together, we&#8217;d like to share with you the Maven configurations and Java code that we use to accomplish automated one-step Selenium integration testing for a web application running in Jetty using Maven. </p>
<p>For the purposes of this post, we will refer to a Spring-MVC Java web application that keeps track of cars. It has the ability to add/delete/edit/list cars. To keep things simple, it does not use a database but keeps a list of cars in memory. The full code for the application can be downloaded from <a href='http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/integration-testing-post.zip'>here</a>.</p>
<p>Pre-requisites: Maven installed, some understanding of Selenium is helpful. </p>
<h2>Run the web application</h2>
<p>Download the source code (available <a href='http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/integration-testing-post.zip'>here</a>) and unzip it to a folder on your filesystem. Open a console and navigate to the folder with the code in it and execute the following:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">mvn jetty:run</pre></div></div>

<p>In your browser, go to the application homepage: <a href="http://localhost:9080/integration-testing-post">http://localhost:9080/integration-testing-post</a> and you should see the following:</p>
<div id="attachment_99" class="wp-caption alignnone" style="width: 310px"><a href="http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/app-homepage.jpg"><img src="http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/app-homepage-300x202.jpg" alt="Integration Testing Cars Application homepage" title="app-homepage" width="300" height="202" class="size-medium wp-image-99" /></a><p class="wp-caption-text">Integration Testing Cars Application homepage</p></div>
<p>Once you&#8217;ve navigated around the application, stop it by pressing ctrl-C in the console. </p>
<h2>Open the application in Eclipse</h2>
<p>Navigate to the directory to which you downloaded the source code in the console. Run the following to Generate the Eclipse project descriptors:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">mvn eclipse:eclipse</pre></div></div>

<p>Then, open Eclipse and run File > Import and choose Existing Projects Into Workspace. Hit &#8216;next&#8217; and then browse for the directory into which you downloaded the code. Click ok and then Eclipse should find your new project. Double-click on it to import it. You may have to add the M2_REPO classpath variable to your workspace if you&#8217;ve not already done so. See <a href="http://maven.apache.org/guides/mini/guide-ide-eclipse.html#Maven_2_repository">here</a> for more info. </p>
<h2>Create the Selenium Integration Test</h2>
<p>The integration tests are in the  /src/test/java/com/tsl/example/cars/integration/ folder of the project. SeleniumIntegrationTest is the base class for all Selenium tests. It starts up a Selenium client in the setup() method and stops it in the tearDown() method.</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.tsl.example.cars.integration</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">junit.framework.TestCase</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.openqa.selenium.server.SeleniumServer</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.thoughtworks.selenium.DefaultSelenium</span>;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.thoughtworks.selenium.Selenium</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> SeleniumTestCase <span style="color: #000000; font-weight: bold;">extends</span> TestCase <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">protected</span> Selenium selenium;
&nbsp;
	@Override
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">setUp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
        selenium <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DefaultSelenium<span style="color: #009900;">&#40;</span>
        		<span style="color: #0000ff;">&quot;localhost&quot;</span>, 
        		SeleniumServer.<span style="color: #006633;">getDefaultPort</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, 
        		<span style="color: #0000ff;">&quot;*iehta&quot;</span>, 
        		<span style="color: #0000ff;">&quot;http://localhost:9080&quot;</span><span style="color: #009900;">&#41;</span>;
        selenium.<span style="color: #006633;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
	<span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> tearDown<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    	selenium.<span style="color: #006633;">stop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
    	<span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">tearDown</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>For more information on the parameters passed in the constructor of DefaultSelenium, see the Selenium client documentation. The most important is that which specifies the browser that Selenium should use to run the tests. In this case, it is set to <code>"*iehta"</code> which means Internet Explorer. To change to Firefox, use <code>"*firefox"</code>. </p>
<p>CarIntegrationTest is a Selenium Integration Test. It extends SeleniumTestCase. The source code is below:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.tsl.example.cars.integration</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CarIntegrationTest <span style="color: #000000; font-weight: bold;">extends</span> SeleniumTestCase <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testAddCar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
		selenium.<span style="color: #006633;">open</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/integration-testing-post/cars/list.html&quot;</span><span style="color: #009900;">&#41;</span>;
		selenium.<span style="color: #006633;">click</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;link=Add Car&quot;</span><span style="color: #009900;">&#41;</span>;
		selenium.<span style="color: #006633;">waitForPageToLoad</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;30000&quot;</span><span style="color: #009900;">&#41;</span>;
		selenium.<span style="color: #006633;">type</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;make&quot;</span>, <span style="color: #0000ff;">&quot;Mercedes&quot;</span><span style="color: #009900;">&#41;</span>;
		selenium.<span style="color: #006633;">type</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;model&quot;</span>, <span style="color: #0000ff;">&quot;SLK&quot;</span><span style="color: #009900;">&#41;</span>;
		selenium.<span style="color: #006633;">click</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;btnSave&quot;</span><span style="color: #009900;">&#41;</span>;
		selenium.<span style="color: #006633;">waitForPageToLoad</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;30000&quot;</span><span style="color: #009900;">&#41;</span>;
		assertTrue<span style="color: #009900;">&#40;</span>selenium.<span style="color: #006633;">isTextPresent</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Mercedes&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
		assertTrue<span style="color: #009900;">&#40;</span>selenium.<span style="color: #006633;">isTextPresent</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SLK&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The testAddCar() method tests that we can add a car (a Mercedes SLK) using the web application. It assumes that you start at the start page of the application, click on the &#8216;add car&#8217; link, enter the make and model and click save. It waits up to 30secs for the application to save the car and tests that on the resulting page (which is the list of cars), the words &#8216;Mercedes&#8217; and &#8216;SLK&#8217; appear. This allows us to assume that the car was correctly added. </p>
<p>The content of this test method was generated using the Selenium IDE plugin for Firefox: </p>
<div id="attachment_102" class="wp-caption alignnone" style="width: 310px"><a href="http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/firefox-selenium.jpg"><img src="http://www.theserverlabs.com/blog/wp-content/uploads/2008/09/firefox-selenium-300x207.jpg" alt="Selenium IDE plugin in Firefox" title="firefox-selenium" width="300" height="207" class="size-medium wp-image-102" /></a><p class="wp-caption-text">Selenium IDE plugin in Firefox</p></div>
<p>I&#8217;m not going to go into detail here on how to use the Selenium IDE but basically it acts like a Macro recorder - recording your steps as you manually perform the integration test in your browser and then allowing you to play it back. I prefer standard Java syntax for the test instead of the &#8216;Selenese&#8217; default. You can export Java code from a new test case by choosing File > Export Test Case As > Java - Selenium RC. I tend to create a new class manually in Eclipse for the test and then copy over just the testXXX methods from the Java source code that I exported from Selenium IDE. </p>
<h2>Running the integration tests in Jetty using Maven</h2>
<p>Once we have created an integration test we want to run it using Maven. There are a few things we want to happen before the integration test runs though: </p>
<ol>
<li>Start up the web application running in Jetty</li>
<li>Start up the Selenium Server</li>
</ol>
<p>We accomplish this using the following <build> section in the Maven POM file (in the root folder of the downloaded code):</p>

<div class="wp_syntax"><div class="code"><pre class="xml xml" style="font-family:monospace;">   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;build<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugins<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.mortbay.jetty<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>maven-jetty-plugin<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;scanIntervalSeconds<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>5<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/scanIntervalSeconds<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;stopPort<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>9966<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/stopPort<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;stopKey<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>foo<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/stopKey<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;connectors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;connector</span> <span style="color: #000066;">implementation</span>=<span style="color: #ff0000;">&quot;org.mortbay.jetty.nio.SelectChannelConnector&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;port<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>9080<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/port<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;maxIdleTime<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>60000<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/maxIdleTime<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/connector<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/connectors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;executions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>start-jetty<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>pre-integration-test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>run<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;daemon<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>true<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/daemon<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>stop-jetty<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>post-integration-test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>stop<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/executions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.apache.maven.plugins<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>maven-compiler-plugin<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;source<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.5<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/source<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.5<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;encoding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>UTF-8<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/encoding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.codehaus.mojo<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>selenium-maven-plugin<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.0-beta-3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;executions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>start<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>pre-integration-test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>start-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;background<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>true<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/background<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;logOutput<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>true<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/logOutput<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;multiWindow<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>true<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/multiWindow<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>stop<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>post-integration-test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>stop-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/executions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.apache.maven.plugins<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>maven-surefire-plugin<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;excludes<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exclude<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>**/integration/*Test.java
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/exclude<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/excludes<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;executions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>integration-tests<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>integration-test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;skip<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>false<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/skip<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;excludes<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exclude<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>none<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/exclude<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/excludes<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;includes<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;include<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>**/integration/*Test.java
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/include<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/includes<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/executions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugins<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/build<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>I&#8217;m among the first to acknowledge the benefits of Maven, but at times the XML syntax required to configure it can be a bit scary! Here&#8217;s the basic explanation of all this: </p>
<ul>
<li>The Jetty plugin is configured to run Jetty on port 9080 - I prefer to avoid potential conflicts with other applications running on 8080 which is quite commonly used.</li>
<li>In the <code>pre-integration-test</code> Maven phase (executed before the integration tests are run), the run goal of the Maven Jetty plugin is executed. The configuration element allows us to specify that that this is a daemon process</li>
<li>In the <code>post-integration-test</code> phase, we run the stop goal of the Maven Jetty plugin to shut down Jetty. </li>
<li>In the pre-integration-test phase we run the start-server goal of the Maven Selenium Plugin</li>
<li>In the <code>post-integration-test</code> phase, we run the stop-server goal of the Maven Selenium plugin to shut down the Selenium server</li>
<li>The Maven Surefire plugin is configured to not execute the integration tests as part of the normal test phase but instead in the integration-test phase. </li>
</ul>
<h2>Executing the Integration tests</h2>
<p>Although the Maven configuration looks verbose and complicated, it gives great results. Just executing the single command below in the console causes the integration tests to run without interference:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">mvn integration-test</pre></div></div>

<h2>What about Cargo?</h2>
<p>When I was developing this code, I noticed that many people seemed to use the Maven Cargo plugin to start up the relevant application server. I had very mixed results using this with different application servers and it didn&#8217;t seem to work at all with Jetty - lots of Classpath problems if I remember rightly. In the end, the plain old Maven Jetty plugin did the job just fine. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.theserverlabs.com/blog/2008/09/17/automated-integration-testing-with-selenium-maven-and-jetty/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Compile-time architecture enforcement revisited: AspectJ, Maven and Eclipse</title>
		<link>http://www.theserverlabs.com/blog/2008/09/10/compile-time-architecture-enforcement-revisited-aspectj-maven-and-eclipse/</link>
		<comments>http://www.theserverlabs.com/blog/2008/09/10/compile-time-architecture-enforcement-revisited-aspectj-maven-and-eclipse/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 11:14:38 +0000</pubDate>
		<dc:creator>Jacobo Matute</dc:creator>
		
		<category><![CDATA[AOP]]></category>

		<category><![CDATA[Agile &amp; XP]]></category>

		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Methodologies]]></category>

		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://blog.theserverlabs.com/?p=12</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/09/10/compile-time-architecture-enforcement-revisited-aspectj-maven-and-eclipse/";</script>It has been a while since we first heard about compile-time checks with AspectJ at the Java Server Symposium in 2007. Since then we have been using and experimenting with this feature of AOP and AspectJ, and more recently we have used this technology to implement architecture enforcment rules for some of our clients.
In this [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://www.theserverlabs.com/blog/2008/09/10/compile-time-architecture-enforcement-revisited-aspectj-maven-and-eclipse/";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>It has been a while since we first heard about compile-time checks with AspectJ at the <a href="http://www.theserverlabs.com/blog/?p=6">Java Server Symposium in 2007</a>. Since then we have been using and experimenting with this feature of AOP and AspectJ, and more recently we have used this technology to implement architecture enforcment rules for some of our clients.</p>
<p>In this more technical post we revisit the concepts, how to create Aspects, and more importantly, how we integrate the aspect libraries with Maven and Eclipse via AspectJTools, creating an easy to maintain and usable environment.</p>
<p>We apply an agile approach in most of our projects, so what we describe here allow us to automate and integrate the architecture enforcement rules into our continuous integration environment using maven, meaning that we can fail a build that does not meet our architecture rules.</p>
<p>Depending on project&#8217;s nature, the enforcement rules may vary but they normally fall into some or all of these categories:</p>
<ul>
<li>Rules to enforce application architecture and layering</li>
<li>Rules to enforce good practices like:
<ul>
<li>Usage of utility libraries against direct data manipulations</li>
<li>Exception handling</li>
<li>Proper logging against dumps to console</li>
<li>&#8230;</li>
</ul>
</li>
</ul>
<ul>
<li>Avoid usage of already know problematic libraries</li>
</ul>
<ul>
<li> &#8230;</li>
</ul>
<p>The ideal way to put all of this to work is to organise the defined rules in different libraries, so we can reuse them based on the type of project we are currently working on. Moreover, how can we setup maven projects/archetypes and Eclipse to use the configured environment automatically?</p>
<p><strong>Preparing the rules libraries: </strong></p>
<ol>
<li>Creation of maven project and codification of the rules in AspectJ aspects.</li>
<li>Compile and archive the rules libraries.</li>
</ol>
<p><strong>Setup of the development environment:</strong></p>
<ol>
<li>Configuring maven projects or archetypes that make use of the rules libraries.</li>
<li>Automatically configure AspectJ Tools for Eclipse.</li>
</ol>
<p>Let’s start on how we can create AspectJ aspects libraries to code the enforcing rules.</p>
<p><strong>Preparing the rules libraries:</strong></p>
<ul>
<li>Create a maven project using a standard archetype:</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #007800;">$mvn</span> archetype:create –<span style="color: #007800;">DgroupId</span>=com.tsl.common –<span style="color: #007800;">DartifactId</span>=lib-aoprules-enforce</pre></div></div>

<p>We need to add the following the dependencies for AspectJ libraries and the aspectj-maven-plugin to the generated pom.xml in order to enable the compilation of AspectJ aspects. Te final pom.xml is given below:</p>

<div class="wp_syntax"><div class="code"><pre class="xml xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;project</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://maven.apache.org/POM/4.0.0&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns:xsi</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xsi:schemaLocation</span>=<span style="color: #ff0000;">&quot;http://maven.apache.org/POM/4.0.0 </span>
<span style="color: #009900;">                                   http://maven.apache.org/maven-v4_0_0.xsd&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;modelVersion<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>4.0.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/modelVersion<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.tsl.common<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>lib-aoprules-enforce<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;packaging<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>jar<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/packaging<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.0-SNAPSHOT<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>lib-aoprules-enforce<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://maven.apache.org<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependencies<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.aspectj<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>aspectjrt<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.5.4<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependencies<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;build<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugins<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.apache.maven.plugins<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>maven-eclipse-plugin<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2.6-SNAPSHOT<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.codehaus.mojo<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>aspectj-maven-plugin<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;executions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
					<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>compile<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/executions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugins<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/build<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pluginRepositories<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pluginRepository<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>apache.snapshots<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Apache Snapshot Repository<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			http://people.apache.org/maven-snapshot-repository
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;snapshots<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;enabled<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>true<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/enabled<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/snapshots<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;releases<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;enabled<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>false<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/enabled<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/releases<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pluginRepository<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pluginRepositories<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/project<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Additionally, we have added another specific entry for the <strong><em>maven-eclipse-plugin</em></strong>. Why? Well, the current version of maven-eclipse-plugin (2.5.1) does not generate any configuration parameters to configure AspectJTools for Eclipse, i.e. project nature in “.project” file and AspectJ classpath in “.classpath” file.</p>
<p>A few days ago, the <a href="http://jira.codehaus.org/browse/MECLIPSE-200">enhancement</a> was added to the 2.6 snapshot version and works perfectly.</p>
<p>This allows us to use the maven-eclipse-plugin goal <strong><em>eclipse:eclipse</em></strong> to generate all necessary aspectj tools classpath variables and project natures.<br />
You can download the snapshot from the <a href="http://people.apache.org/maven-snapshot-repository">apache repository</a> and include it into your maven repo (see the plugin-repository definition in pom.xml).</p>
<p>So, let´s execute <em><strong>mvn eclipse:eclipse</strong></em> in the project directory and import the project into Eclipse (I´m asumming the M2_REPO classpath variable is already configured in your Eclipse environment and the AspectJTools pluging for Eclipse has been installed). Note how the AspectJ nature is already enabled. Later, when we want to make use of the libraries, we will see that the enhancement has another feature to make life easier.</p>
<p>Now, we can create a new aspect called “<em>EnforceLogging.aj</em>” in Eclipse. This aspect codifies a rule that will detect and generate a compilation warning of all calls that print to console outside TestCase classes, considering that our unit test framework is Junit:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.tsl.enforcement.aspects</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">junit.framework.*</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> aspect EnforceLogging <span style="color: #009900;">&#123;</span>
&nbsp;
	pointcut scope<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
		within<span style="color: #009900;">&#40;</span>com.<span style="color: #006633;">tsl</span>..<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>within<span style="color: #009900;">&#40;</span>TestCase<span style="color: #339933;">+</span><span style="color: #009900;">&#41;</span>;
&nbsp;
	pointcut printing<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> 
		get<span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span><span style="color: #009900;">&#41;</span> || get<span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">err</span><span style="color: #009900;">&#41;</span> || call<span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span> printStackTrace<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
	declare warning
		<span style="color: #339933;">:</span> scope<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> printing<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;Don't print to Console, use logger&quot;</span>;
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As we are using Junit libraries in our aspects we need to add it as a dependency to the maven pom.</p>
<p>With this configuration, we can easily build now our first rules library and deploy it in our repository with <em><strong>mvn install</strong></em>.</p>
<p><strong>Setup of development environment:</strong></p>
<p>Let’s see how a new project will be created and how it will use those rules libraries.<br />
As we use maven, the integration is pretty simple and will ensure that our continuous integration system will detect builds that break the configured rules.</p>
<p>In the past, we would have to manually configure the AspectJTools plugin in Eclipse to work with our project - which can be very annoying.</p>
<p>As mentioned previously, now with the 2.6 version of the maven-eclipse-plugin, we can integrate everything in a transparent way to the developer, so they can start coding in Eclipse without worrying about AspectJ details.</p>
<p>We normally have a maven archetype defined with the required configuration to enable aspectj and the libraries we want to be included, so the development team will create a new project with all the desired enforcement rules straight away.</p>
<p>For this example, a project pom.xml from which the archetype could be generated should include at least:</p>

<div class="wp_syntax"><div class="code"><pre class="xml xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;project</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://maven.apache.org/POM/4.0.0&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns:xsi</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xsi:schemaLocation</span>=<span style="color: #ff0000;">&quot;http://maven.apache.org/POM/4.0.0 </span>
<span style="color: #009900;">				http://maven.apache.org/maven-v4_0_0.xsd&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;modelVersion<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>4.0.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/modelVersion<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.tsl.common<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>enforcement-test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;packaging<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>jar<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/packaging<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.0-SNAPSHOT<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>enforcement-test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://maven.apache.org<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependencies<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #00