views:

502

answers:

3

I'm in the process of porting several J2EE projects from Ant to Maven2. All of these projects contain 1 EJB and 1 web module, and use the recommended "skinny" EAR packaging method. This means that the JARs that the EJB and/or web modules depend on are all just put in the root of the EAR. Both EJB and web modules have Class-Path entries in their respective manifests to reference the specific JARs, plus the web module Class-Path will also reference the EJB jar.

I was horrified (is that too strong? :)) to find that Maven doesn't support this very well. I read the official page on handling skinny WARs, but that meant I had to duplicate the WAR dependencies in the EAR pom and, even worse, also the transitive dependencies. It seems pointless to adopt Maven if you have to manually handle dependencies anywhere!

I then starting Googling and found a variety of workarounds - obviously, I'm not the first person to (a) want to do a skinny EAR and (b) don't like the Maven suggested approach (which is itself a workaround).

I tried some of these approaches, but none of them worked for me. I also found some issues that looked like Maven bugs, e.g. the WAR plugin 'packagingExcludes' directive excludes only the direct dependencies, not any transitive ones! Not very confidence inspiring. I found a JIRA issue for this specific one, but it's still open.

I then found that my command-line Maven 2.2.1 does things differently to my m2eclipse embedded Maven (Embedder v. 3.0). Our developers would definitely want to drive Maven from Eclipse, so relying on the latest command-line version was not an option.

So, my question is: right now, and for the forseeable future, is it worth migrating to Maven if we do all our development in Eclipse, and work mostly on skinny EAR projects? Is there anything in Maven's future that would make it handle EARs in a more robust and integrated way?

A: 

I was horrified (is that too strong? :)) to find that Maven doesn't support this very well (...)

Indeed, Maven doesn't support skinny WARs (see also the Solving the Skinny Wars problem wiki page) very well because this was just not planned from the start and Maven assumes fat WARs. So the way to build skinny WARs and skinny EARs is indeed more a workarounds built on top of existing plugins. And, yes, this is error prone.

(...) I then found that my command-line Maven 2.2.1 does things differently to my m2eclipse embedded Maven (Embedder v. 3.0).

Note that you can configure m2eclipse to use an external Maven instead of the embedded Maven. This is actually what I do, I want exactly the same version that the CI engine uses.

So, my question is: right now, and for the forseeable future, is it worth migrating to Maven if we do all our development in Eclipse, and work mostly on skinny EAR projects?

My advice is simple: if Maven doesn't support the way you want to build software (legitimate or not, that's not the question), don't use it.

Pascal Thivent
Thanks Pascal. For the first EAR project, I've worked around the problem by marking the WAR-to-EJB dependency as 'provided', not 'runtime'. This avoids any JARs being placed into the WAR's web-inf/lib, but unfortunately (but obviously) also produces no Class-Path entry in the WAR's manifest. I got 'round this by manually inserting a manifest entry for it (hack, I know) specifying the Class-Path containing only the EJB jar reference.Regarding m2eclipse, I'm using 0.9.9, which can only use Maven Embedder 3.0.0 (see http://old.nabble.com/M2Eclipse-0.9.9-and-Maven-2.X-td26886557.html).
Cornel Masson
+1  A: 

So, my question is: right now, and for the forseeable future, is it worth migrating to Maven if we do all our development in Eclipse, and work mostly on skinny EAR projects? Is there anything in Maven's future that would make it handle EARs in a more robust and integrated way?

Short story: No, not while M2Eclipse remains broken.

Long story:

Currently, I would recommend against it, at least in Eclipse. At the time of writing the M2Eclipse plugin has and always has had a very nasty bug where it generates its own version of the application.xml descriptor file rather than use the one Maven would otherwise create.

Unfortunately, this custom-created application.xml is downright wrong: it ignores finalNames, has an apparently hardcoded "lib/" prefix and assigns EJB JARs the extension ".ejb" for some reason. What's worse, you cannot remove it to be replaced with Maven's version as it keeps getting regenerated by M2Eclipse.

Maven will only generate application.xml if it's not already in place. Because the WTP/M2Eclipse-generated application.xml keeps getting regenerated, the Maven application.xml doesn't get a chance.

There is a workaround for this problem, however: you can tell Maven to ignore the application.xml during packaging so that it thinks application.xml is not there, in which case it will still generate its own version. That way, the wrongly-generated application.xml file wouldn't matter. For future reference:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-ear-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <version>5</version>
        <earSourceExcludes>**/application.xml</earSourceExcludes>
        <generateApplicationXml>true</generateApplicationXml>
    </configuration>
</plugin>

One major problem though is that the Ant script used for deployment to GlassFish in Eclipse generates its own separate EAR for deployment, and uses the M2Eclipse-generated application.xml for doing so. That means the EARs it generates will always be wrong as long as the M2Eclipse plugin remains broken. There are bug reports for this on the codehaus JIRA, can't access them right now though.

YMMV for other application servers, but be prepared for heavy fiddling with application.xml.

voetsjoeba
A: 

Unfortunately, this custom-created application.xml is downright wrong: it ignores finalNames, has an apparently hardcoded "lib/" prefix and assigns EJB JARs the extension ".ejb" for some reason. What's worse, you cannot remove it to be replaced with Maven's version as it keeps getting regenerated by M2Eclipse.

Are you really sure it's m2eclipse doing this? I'm using JBoss Tools 3.1 which includes m2eclipse integration and get exactly the problem you're stating. However, I don't see the rationale for m2eclipse to care at all about the source application.xml.

My suspicion is that JBoss Tools injects information into the application.xml. Please prove I'm wrong, I'd stop using m2eclipse forever fi it changed anything that's not under /target.

//GG

Gunnar Gustavsson