November 19, 2009

JBoss and Maven

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???

10 comments:

  1. Thanks for the tip to use the jboss-as-client POM. I managed to get all dependencies resolved using the repositories configured out-of-the-box for Artifactory 2.2.1. Just had to change the includes pattern for the jboss repository to **/*.

    ReplyDelete
  2. One question:
    How did you get Maven to work with the client dependency? Since there's no physical jar available Maven keeps on complaining about it:

    Missing artifact org.jboss.jbossas:jboss-as-client:jar:5.1.0.GA:runtime

    ReplyDelete
  3. Well, this is just a POM (org.jboss.jbossas:jboss-as-client:pom:5.1.0.GA) that contains dependencies to the actual jar files, see here: http://repository.jboss.com/maven2/org/jboss/jbossas/jboss-as-client/5.1.0.GA/jboss-as-client-5.1.0.GA.pom. That is, there is no JAR with that group and artifact id (at least not that I'm aware of).

    I don't remember exactly, but I think I used a dependency to this POM in my own code with a type of, well, POM: <type>pom</type>. As I said, we are actually not using this approach due to the huge number of transitive dependencies.

    ReplyDelete
  4. Thanks, Christoph!

    pom did the trick. It is some kind of strange because I tried this already before. But after a Clean now everything seems to work fine.

    Danke nach Köln (oder so) aus Aachen

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. I meant: <type>pom</type> did the trick.

    ReplyDelete
  7. The other option for running unit tests is to have maven point to you local jboss client lib directory using "system" scope:

    <dependency>
    <groupId>jboss</groupId>
    <artifactId>jbossall-client</artifactId>
    <version>${jboss.version}</version>
    <scope>system</scope>
    <systemPath>${jboss.home}/client/jbossall-client.jar</systemPath>
    </dependency>

    ReplyDelete
  8. Hi, to develop it's ok, but what can we do for deploying te app?
    Does someone know exactly the depndencies for comunicate a client with EJBs?

    TIA
    Juanje

    ReplyDelete
  9. This pom don't exists anymore:
    http://repository.jboss.com/maven2/org/jboss/jbossas/jboss-as-client/5.1.0.GA/jboss-as-client-5.1.0.GA.pom
    Actually the whole repository is gone:
    http://repository.jboss.com/maven2

    ReplyDelete
  10. Well, the JBoss artifacts have been moved some time ago when the JBoss team switched to Nexus (see https://community.jboss.org/en/build/blog/2010/04/20/announcement--new-maven-repository-infrastructure). So the current start URL to search for artifacts would be https://repository.jboss.org/nexus.

    Moreover, as far as I can tell most of the JBoss artifacts are also available on Maven Central (see http://search.maven.org/).

    ReplyDelete