Java Moods

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg
Showing posts with label JBoss. Show all posts
Showing posts with label JBoss. Show all posts

Saturday, 2 January 2010

Cargo Maven Plugin: Not Made for JBoss

Posted on 09:24 by Unknown

Again...

Well, actually this blog was supposed to be about Java in general and all the ups and downs I experience during my daily work. However, I've not been doing much other than Maven configuration and build management lately, so here is another Maven related post. Sorry folks.

As already shown in this post, I have been doing integration tests with JBoss by using the Cargo Maven plugin to start the JBoss locally and deploy the application to it. This all works quite as soon as you have figured out how to configure Cargo for JBoss.

But Remotely Now!

Now, the next step is to deploy our EAR file which is generated during nightly build to a running JBoss instance on a separate computer. This is different because no JBoss configuration has to be created locally and no JBoss has to be started. Instead, the EAR file must be transferred to a remote server where JBoss is already running, and JBoss must be persuaded to deploy this file.

That sounds feasible, and I've done exactly this before for other servers like Tomcat, so I did not expect any issue here. However, I was wrong.

Itch #1

First trouble was caused by my lack of knowledge regarding JBoss. With standard installation, you are not able to connect to the server remotely and all the services are bound to localhost only (see here or here). This is intentionally, to prevent unprotected installations appearing all over the net. You have to pass the option -b 0.0.0.0 when starting JBoss to allow remote connections to the services, but take care to secure your JBoss accordingly!

Itch #2

Okay, after this has been configured, I tried to use Cargo to deploy my EAR file to JBoss. This is the configuration I ended up with:

<!-- *** Cargo plugin: deploy the application to running JBoss *** -->
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<configuration>
<wait>false</wait>
<!-- Container configuration -->
<container>
<containerId>jboss5x</containerId>
<type>remote</type>
</container>
<!-- Configuration to use with the Container -->
<configuration>
<type>runtime</type>
<properties>
<cargo.hostname>...</cargo.hostname>
<cargo.servlet.port>8080</cargo.servlet.port>
</properties>
</configuration>
<!-- Deployer configuration -->
<deployer>
<type>remote</type>
<deployables>
<deployable>
<location>...</location>
</deployable>
</deployables>
</deployer>
</configuration>

<executions>
<execution>
<id>deploy</id>
<phase>deploy</phase>
<goals>
<goal>deployer-redeploy</goal>
</goals>
</execution>
</executions>
</plugin>

However, I always got this error message:

[INFO] Failed to deploy to [http://...]
Server returned HTTP response code: 500 for URL: ...

The configuration seems to be correct, so what is the problem?

After asking Google, I realized that Cargo is not able to transfer a file to JBoss! Instead, it requires the deployable to be deployed to be present on the server filesystem (see here). This is obviously caused by the JBoss JMX deployer which is used by Cargo, but actually you don't care who is to blame – you just want it to work. The name "Cargo" implies the parcel is transferred to its destination, right? Also note that this issue is dated from Sep 2006, so there has been some time to fix it in either way.

What Can We Do?

Well, there are probably not many options. Since current version of Cargo is not able to transfer the file to the server, you'd have to do this on your own. The location given in our Cargo configuration above actually is the path on the JBoss server. So, when the file exists locally on the JBoss server, Cargo should be able to deploy it successfully.

For transferring the file to JBoss server, we could use the maven-dependency-plugin, a quite useful plugin for all kind of analyzing, copying or unpacking artifacts. We configure it to run in pre-integration-test phase and to copy the EAR file (produced by this POM) to some temp directory on the JBoss server:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>install</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
<destFileName>test.ear</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>${publish.tempdir}</outputDirectory>
<overWrite>true</overWrite>
</configuration>
</execution>
</executions>
</plugin>

The property ${publish.tempdir} can be anything on the JBoss server (which must be available in the network!) and is exactly what has to be used for the value of location element in Cargo configuration.

Another option would be to use the hot-deploy directory of JBoss as outputDirectory for the dependency plugin, and hence rely on hot deployment of JBoss instead of Cargo and JBoss JMX deployer. This way, we could get rid of Cargo configuration and cleanup the POM a bit, but in the end it seemed a bit less clean to me... your mileage may vary.

So, as always, in the end we got it to work, but not without unforeseen pain. When will Cargo be fixed to get the EAR file to JBoss server? Who knows.

Updates

2010/01/22: Note that the dependency plugin must be bound after the install phase so that the artifact has been copied at least to your local Maven repository. As a consequence, the Cargo plugin must be run in deploy phase, which is actually a good choice anyways. I have changed this in my code above.

Read More
Posted in Cargo, JBoss, Maven, Testing | No comments

Friday, 27 November 2009

Integration test with Maven, Cargo and JBoss

Posted on 08:22 by Unknown

It's Friday...

... and I thought it would be a good idea to setup an integration test of some EJBs we are creating in a new project. Actually, it was not, since it nearly ruined my evening. But eventually I got it to work, and here is how.

To test the EJBs, I need to create an EAR file, deploy that to the application server (JBoss 5.1.0 in our case) and run JUnit test cases against this server. For Maven, I have setup a separate integration-test module for executing the integration test for the following reasons:

  • to better separate unit tests (with JUnit) from integration tests (also with JUnit), which simplifies Maven configuration a bit.
  • to be able to run this module outside of the normal CI (continuous integration) build due to its lack of performance.

Cargo Maven Plugin

For automatically starting the container, deploying the EAR file and stopping the container when the tests are finished, I use the Cargo Maven plugin. I did this several times before (with Tomcat, though) – so I thought that'd be easy...

Well, when using JBoss, there are some tricks you have to know. Before going into the details, some more information on Cargo.

A Container is the base concept in Cargo. It represents an existing application server runtime, and Cargo hides all the details of the actual server implementation for you. There are two types of containers:

  • Local Container: this is executing on the machine where Cargo runs. This can either be an Installed Container which is, well, installed on the local machine and is run in a separate VM, or an Embedded Container that is executing in the same JVM where Cargo is running (currently only supported for Jetty).
  • Remote Container: a container that is already running anywhere (local or remote). It's not under Cargo's control and can't be started or stopped by Cargo.

You use a Configuration to specify how the container is configured (logging, data sources, location where to put the deployables, etc). The available configuration depends on the container type:

  • Local Configuration: for local containers. There are two local configuration types: Standalone Local Configuration which configures the container from scratch in a directory of your choice, and Existing Local Configuration that re-uses an existing container installation already residing on your hard drive.
  • Runtime Configuration: You use a runtime configuration when you want to access your container as a black box through a remote protocol (JMX, etc). This is perfect for remote containers.

In my case, I wanted to use a Local Installed Container with a Standalone Local Configuration, to eliminate dependencies from other deployments.

JBoss with Cargo

Well, and here are the pitfalls when using JBoss in this setting:

  1. Experimental: JBoss 5.x is still an experimental container for Cargo. This is a bit strange given the fact that this version is now out for a while, but fortunately not really an issue.
  2. Extensive Logging: When Cargo builds the JBoss configuration – remember, I use Standalone Local Configuration so Cargo creates one from scratch – it uses a logging setup (independantly from what is used with your JBoss installation!) that is way too chatty. The console scrolls forever, and things are slowing down in a way that you think everything is stuck in an infinite loop.
    Thus, you have to tell Cargo to use another logging configuration file, which is a bit tricky and not documented very well (see this issue).
  3. Shutdown Port: Now the container starts up, the tests are run, but after that JBoss AS is not shutting down. It's telling me javax.naming.CommunicationException: Could not obtain connection to any of these urls: localhost:1299, which means the wrong port is used for shutdown. Standard shutdown port is 1099, so we have to tell Cargo to use that port number.

All in all, the configuration now looks like this. Mentioned settings are highlighted. Perhaps this is useful for someone else...


<!-- *** Cargo plugin: start/stop JBoss application server and deploy the ear
file before/after integration tests *** -->
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<configuration>
<wait>false</wait>
<!-- Container configuration -->
<container>
<containerId>jboss5x</containerId>
<type>installed</type>
<home>${it.jboss5x.home}</home>
<timeout>300000</timeout>
</container>
<!-- Configuration to use with the Container -->
<configuration>
<type>standalone</type>
<home>${project.build.directory}/jboss5x</home>
<properties>
<cargo.jboss.configuration>default</cargo.jboss.configuration>
<cargo.servlet.port>${it.jboss5x.port}</cargo.servlet.port>
<cargo.rmi.port>1099</cargo.rmi.port>
<cargo.jvmargs>-Xmx512m</cargo.jvmargs>
</properties>
<deployables>
<deployable>
<groupId>com.fja.ipl</groupId>
<artifactId>ipl-lc-ear</artifactId>
<type>ear</type>
</deployable>
</deployables>
<!-- Override logging created by Cargo (which is way to chatty) with default
file from JBoss (see http://jira.codehaus.org/browse/CARGO-585) -->
<configfiles>
<configfile>
<file>src/test/resources/jboss-log4j.xml</file>
<todir>conf</todir>
</configfile>
</configfiles>
</configuration>
</configuration>

<executions>
<!-- before integration tests are run: start server -->
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<!-- after integration tests are run: stop server -->
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<properties>
<it.jboss5x.home>${basedir}/../../../tools/bin/jboss-5.1.0.GA</it.jboss5x.home>
<it.jboss5x.port>8080</it.jboss5x.port>
</properties>
Read More
Posted in Cargo, JBoss, Maven, Testing | No comments

Thursday, 19 November 2009

JBoss and Maven

Posted on 00:47 by Unknown

The Challenge

During the last days I was busy trying to build and deploy a JEE application on JBoss – using Maven, of course. One interesting task was to run integration tests, i.e. JUnit tests that are testing a service bean deployed on JBoss application server. Integration tests with Maven are an interesting issue, worth its own blog entry probably. But this post is all about JBoss.

Well, this task doesn't sound hard for a Maven expert, but unexpectedly it was not that easy. Our test code (calling the EJB) was depending on JBoss artifacts, which might be questionable in itself but that's how it's currently done. Hence, during runtime the code needs the jbossall-client.jar from JBoss' client directory in the classpath.

The Eclipse Way

We are using JBoss 5.x, and in this version the jbossall-client.jar is rather small since it only references all required jar files in the Manifest's Class-Path element:

Manifest-Version: 1.0
Specification-Title: JBossAS
Specification-Version: 5.0.0.GA
...
Implementation-Vendor: JBoss.org
Implementation-Vendor-Id: http://www.jboss.org/
Class-Path: commons-logging.jar concurrent.jar ejb3-persistence.jar hi
bernate-annotations.jar jboss-aop-client.jar jboss-appclient.jar jbos
s-aspect-jdk50-client.jar jboss-client.jar jboss-common-core.jar jbos
s-deployers-client-spi.jar jboss-deployers-client.jar jboss-deployers
-core-spi.jar jboss-deployers-core.jar jboss-deployment.jar jboss-ejb
3-common-client.jar jboss-ejb3-core-client.jar jboss-ejb3-ext-api.jar
jboss-ejb3-proxy-clustered-client.jar jboss-ejb3-proxy-impl-client.j
ar jboss-ejb3-proxy-spi-client.jar jboss-ejb3-security-client.jar jbo
ss-ha-client.jar jboss-ha-legacy-client.jar jboss-iiop-client.jar jbo
ss-integration.jar jboss-j2se.jar jboss-javaee.jar jboss-jsr77-client
.jar jboss-logging-jdk.jar jboss-logging-log4j.jar jboss-logging-spi.
jar jboss-main-client.jar jboss-mdr.jar jboss-messaging-client.jar jb
oss-remoting.jar jboss-security-spi.jar jboss-serialization.jar jboss
-srp-client.jar jboss-system-client.jar jboss-system-jmx-client.jar j
bosscx-client.jar jbossjts-integration.jar jbossjts.jar jbosssx-as-cl
ient.jar jbosssx-client.jar jmx-client.jar jmx-invoker-adaptor-client
.jar jnp-client.jar slf4j-api.jar slf4j-jboss-logging.jar xmlsec.jar

This list is impressive... and the approach is working with current Eclipse. The equivalent for the Maven world would be a POM that references all other required libraries as normal dependencies (see this discussion).

The Maven Way

And yes, such a POM org.jboss.jbossas:jboss-as-client is available on JBoss Maven repository (note: it's not org.jboss.client:jbossall-client which is the reference-by-manifest's-class-path version!).


However, this approach involves two issues:

  • By following the dependencies defined in this org.jboss.client:jbossall-client transitively, Maven will download a vast number of JBoss and JEE libraries which you actually don't want to be used and packaged in your client. This includes things like org.jboss.jbossas:jboss-as-server:jar:5.1.0.GA and jacorb:jacorb:jar:2.3.0jboss.patch6-brew. Does not sound confidence-building, does it? Seems like JBoss should exclude transitive dependencies at the right places.
  • Moreover, some of the dependencies can't be found on any of the Maven repositories we configured to proxy in our Nexus. This includes Maven Central, JBoss of course, and a couple of others, so I do not know what else to add to provide the missing jars. Maybe it's just that the reference itself is wrong (version number?).

Instead of excluding everything we do not use currently, next idea is to just include those dependencies to the JBoss jar files that the client actually requires. But... it's quite hard to find out the corresponding Maven coordinates. This includes guessing the groupd and artifact id, but also the version – and unfortunately the version information given in the jar's manifest file is not useful since it notes the JBoss AS version instead of the version of the library which is required for Maven.

Lost in Space?

So, I ended up re-packaging a jar that holds the content of the required client jars and putting this on our Nexus...

I honestly wonder how everybody else is using JBoss 5.x with Maven on the client side???

Read More
Posted in JBoss, JEE, Maven | No comments
Older Posts Home
Subscribe to: Posts (Atom)

Popular Posts

  • Eclipse: User Operation is Waiting, and Waiting, ...
    I am using Eclipse since quite a long time, sometimes around 2002. That was version 2.0, if I remember correctly. Since then, I have always ...
  • Maven Plugins: Current Versions
    Upgrading Maven Plugins In preparation for a later switch to Maven 3 (which is already knocking on the door ) as well as to get rid of some ...
  • Maven Plugin Releases: Do it yourself!
    In my previous post , I have complained about Maven plugins that do not release new versions although there are blocking issues that are rep...
  • Maven 3 and Plugin Mysteries
    You probably know that Maven 3 has landed . Before testing it with our projects, I was curious about the plugins that are defined in the Mav...
  • Integration test with Maven, Cargo and JBoss
    It's Friday... ... and I thought it would be a good idea to setup an integration test of some EJBs we are creating in a new project. Act...
  • Maven Setting for Using a Single Repo Manager
    In a previous post I have tried to explain why it's a good idea to define your Maven repository in your settings.xml file instead of t...
  • Maven Profiles: Activation... or not
    I love Maven. Really, I do. I should say that since this is my first post in my own blog (I know, I'm probably the last man on the plane...
  • DocBook with Maven Issue
    We are using DocBook for writing technical documentation for all our projects and in-house frameworks. We are actually quite happy with thi...
  • Having Fun with Encoding!
    Compiler Plugin Recently, I edited our main company root POM to upgrade some plugins to new versions. Of course, we are following best pract...
  • Maven Documentation: The Missing List
    A rather weak talent of Maven is probably its documentation. This is my personal opinion, but it seem to match what other people think . Y...

Categories

  • BestPractices
  • Cargo
  • Checkstyle
  • Eclipse
  • Google
  • Hudson
  • Java
  • JBoss
  • JEE
  • Jenkins
  • JUnit
  • Maven
  • Nexus
  • oAW
  • Optimization
  • OSGi
  • Performance
  • Profiles
  • QA
  • Size
  • Spring
  • Testing
  • Tools
  • WebApp
  • Windows

Blog Archive

  • ▼  2011 (5)
    • ▼  May (1)
      • The Butler Dispute, Round 2
    • ►  April (1)
    • ►  March (2)
    • ►  February (1)
  • ►  2010 (11)
    • ►  October (2)
    • ►  September (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (4)
    • ►  January (2)
  • ►  2009 (30)
    • ►  December (3)
    • ►  November (4)
    • ►  October (2)
    • ►  September (3)
    • ►  June (4)
    • ►  May (5)
    • ►  April (4)
    • ►  March (5)
Powered by Blogger.

About Me

Unknown
View my complete profile