Jetty configuration to deploy multiple wars in integration testing

Hi reader,

I recently ran into a situation :  at work, I had to build a POC about REST architectures.

I tried to be as close to the real architecture as possible. Here is the big picture :
– a buisiness remotely exposed in webservices thanks to Apache CXF (1rst webapp)
– a web layer wich exposes REST Url and consumes the webservice (2nd webapp)

Everything was fine until I tried a black-box testing. To do so I needed my 2 webapps up and running. Believe me or not but I could not find a working solution.

I tried both 4 integration testing techniques recommanded by sonatype :
– dedicated project for testing : runs tests during the test lifecycle (read this)
– tweak surfire : name your integration tests classes with “IT” prefix or “IT” suffix and tell fail-safe to run those tests during the integration-test lifecycle (read this)
– use profiles to avoid systematic run of those test as they really are time-consuming (read this).
– use fail-safe plugin (read this)

None of those solutions was useful to me because my problem was completely different. I took the wrong path. What happened was simple : the first webapp jetty instance was attached to the module’s lifecycle. The consequence of this is simple : jetty was stopped long before the second jetty instance started thus generating java.net.ConnectException (which makes perfect sens once you figure it out).
I thought that because I launched the root project, the Threads (jetty Threads) related to the sub-projects would last until the end of the build : false. They just lasted during the build they’re attached to.

I also also tried many Jetty configurations. ContextHandler configuration is meant for these kind of use cases but I wasn’t successful.

I told myself “Crap I guess this time I will have to dive into Jetty inners”. I won’t lie to you : I struggled and after many trials and failures I found a solution. Not sure it is the best but It definitely does the job for my use case.
The idea is simple :
– use a dedicated project
– use a profile
– programmatically create Jetty server, deploy webapps into that server, run the server, start the webapps.

Excerpt of the code thats does the trick

   private static Server server;

   /**
    * @throws Throwable
    */
   @BeforeClass
   public static void beforeClass() throws Throwable {

      server = new Server();

      QueuedThreadPool threadPool = new QueuedThreadPool();
      threadPool.setMaxThreads(100);
      server.setThreadPool(threadPool);

      SelectChannelConnector connector = new SelectChannelConnector();
      connector.setPort(Integer.valueOf(JETTY_PORT));
      connector.setMaxIdleTime(30000);
      connector.setConfidentialPort(8443);
      server.setConnectors(new Connector[] {connector});

      WebAppContext jerseyPocClientWebApp = new WebAppContext();
      jerseyPocClientWebApp.setWar("../jersey-poc-client-jaxrs/target/jersey-poc-client-jaxrs.war");
      jerseyPocClientWebApp.setContextPath("/" + CLIENT_MODULE_CONTEXT);
      server.addHandler(jerseyPocClientWebApp);

      WebAppContext jerseyPocServerWebApp = new WebAppContext();
      jerseyPocServerWebApp.setWar("../jersey-poc-server/target/jersey-poc-server.war");
      jerseyPocServerWebApp.setContextPath("/" + SERVER_MODULE_CONTEXT);
      server.addHandler(jerseyPocServerWebApp);

      server.start();

      server.setStopAtShutdown(true);

      server.setSendServerVersion(true);
   }

   /**
    * @throws Throwable
    */
   @AfterClass
   public static void afterClass() throws Throwable {

      server.stop();
      server.join();

   }

You can download the full example here. It’s a multi-module including :
– a core : entities, exceptions, business interface. the layer shared by everyone
– a server : business implementations and webservice expositions
– a server-test : tests the server’s output (CXF proxy)
– a client : REST layer, consumes the webservice
– a client-test : tests the client with HttpClient

If you want to test the server output just run “mvn clean install -Pserver-tests”
If you want to test the full stack run “mvn clean install -Pjaxrs-black-box-tests”

Hope this will be useful to anyone looking for a simple working solution.

Advertisements

3 thoughts on “Jetty configuration to deploy multiple wars in integration testing

  1. Hi,

    Thanks for the examples– this is a good learning tool for me on developing a REST front-end that communicates to a SOA backend. I’ve not really looked at the Jetty portion of the project, as that is not of interest to me, but I have a few questions. I’m deploying both wars in glassfish after building through Netbeans. The web service works fine as tested by SoapUI. Deploying the REST front-end however, results in a 404 at the localhost:8080/jersey-poc-client-jaxrs/ URL, however if I manually navigate to a jax-rs mapped URL, it seems to be working– any insight there?

    Secondly, I noticed that in the provided index.jsp (which I am unable to get to) it seems to be calling ajax on URLs with the jersey-poc-server/ root– straight to the backend and not using URLs mapped by the jax-rs class– is this in error or am I missing something?

    Thanks again for any reply and for your wonderful blog.

    1. Hi chris,
      I’m glad if the article helped.

      For your 1rst question I guess the default path “/” is not mapped because the webapp is not meant for humans but for programms.
      In REST architecture you often don’t get html content but rather “xml” or “json”. So there is no view. I guess that’s why you get the 404.

      If I provided jsp pages don’t use them. At first I wanted a full article with jsp calling json and xml and rendering it with jquery. I endend up struggling with the server side part and I gave up the UI part. My bad … But thanks for pointing this out, I’ll correct it whenever I have time.
      The point of the article was a working configuration for jetty. If you want working UI you’d rather read this or this article.

      Hope this helps.

      Louis

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s