Do Maven Multi-Module and EAR play well together? - maven-2

Today, I've been looking at Maven Multi-Module and EAR projects and they seem quite similar in that both seem to define an assembly of a collection of other projects - it almost seems like an EAR project should just be an alternate packaging for a multi-module project.
Have I misunderstood something? Or do these types of project work together?
Following Pascal's answer:
Updated to clarify the question, hopefully that will help if it's not easy to understand; sorry it's maybe not phrased very well, the ear stuff is kinda new to me...
So say I have two projects, one producing a war and the other a utility jar. The war depends on the jar and I need to package them up into an ear for deployment. Should I use a project with a pom packaging type? I guess I have to use a project with an ear packaging type somewhere to produce the final artifact, so am I best using just a project with ear packaging, or projects with both pom and ear? If both, how?

EAR projects work just fine as part of a larger aggregated project. In those cases when you do not want to have the EAR be a separate project; you could always create the file via an assembly.
This approach makes sense in some cases. Usually where you have to create multiple versions of the EAR or when you would like to create the deploy a large EAR file but have no need to keep the artifact once created.
I've used this approach to deal with a corporate standard that requires all deployable to be EAR files, even when the app is a single WAR file. An assembly can create the EAR with its single WAR file and deployment descriptors.

Have I misunderstood something? Or do these types of project work together?
I'm not sure I understood the question but I'm tempted to answer that they work together:
Aggregating modules allow to, well, aggregate modules and they must have a pom packaging (and only pom modules can have nested projects).
An EAR module is just a module with an ear packaging (and has specific bindings) and can be part of a multi-module project.
Both have different purposes. But they work together.

Related

How to stop Maven renaming installed jars

I am installing to Maven repository our internal files using mvn install:install command. All Jars installed in such way have version name added automatically as a suffix. Since we have many batch scripts with the Jars names it is very inconvenient for us. How this auto-renaming can be switched off?
You can't. Dependency resolution in Maven works because Maven has conventions and the naming of artifacts is one of them. So you can't turn off the way maven install artifacts (and you actually don't want to).
The common way to handle scripts (bat/sh) is to put them in your source tree (e.g. in src/main/bin) and to create a distribution of your project with the assembly plugin. When building your assembly, you can rename artifacts, filter distribution files, etc. That would be the right place to do such kind of things.
it's tempting to want to remove the version number, but I'd recommend keeping it on if at all possible.
Instead of removing the version numbers, maybe you could use Maven's resource filtering capability to manage your batch scripts? Maven can manage your batch scripts by replacing placeholders such as ${project.version} inside the bat script with the current version number from the pom.xml. That way you can ensure that the batch script is running the correct (expected) version of the code.
You could probably force maven to deploy a jar without a version, but if you do so, you lose some of the main benefits of having Maven manage your build in the first place, imo. For example, just yesterday I was asked to maintain a java project not managed by maven with a bunch of non-versioned jar files inside a lib directory. There's no way to know where any of the jars came from.
It might be a little bit of a headache up front, but if you're using maven, you might as well jump in 100% (again, from my experience).

Maven not worth it (yet) for EAR deployment? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
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?
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.
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
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.

How do I add 3rd-party OSGi bundles to a deployment package with Maven?

I'm building my application to run in an OSGi container. I use Maven and the Maven Bundle Plugin from Apache Felix to set up the OSGi manifests for my own modules and that works great.
Now, I'm deploying my bundles into an OSGi container together with several 3rd party libraries. Some of these are already OSGi-fied when I get them from the Maven repos, others, I want to convert into OSGi-compatible jars. I want to set up a Maven project that collects all dependencies, and puts each in its own OSGi jar. The ultimate goal is to collect these jars and my own into an assembly that I can use as a standalone deployment package.
I know how to convert standard jars to OSGi jars, and I have a (somewhat hackish) approach to merge multiple OSGi bundles, even if I probably shouldn't. But if I have a dependency that's already fine as it is, and I just want to copy it from the repo into my assembly, what part of Maven do I use? The bundle plugin is wrong, it messes up the manifests if a dependency is already OSGi-compatible. Do I use the dependency-plugin, the assembly plugin or something else?
I have the feeling I'm overlooking something very simple here.
Did you have a look at the PAX tools? In particular Pax-Runner and
pax-construct... They do not only give you a nice template to start with, but also solve most the problems you mentioned for free.
We use many libraries which are not OSGified by the vendor and which are not available on the Spring bundle repository. We also have many of these and want to deploy them all together hassle free. For this we have created a 2-layer maven setup:
Individual maven projects that either download or contain (as 'system' scope depends) the 3rd party lib in question, and OSGify these using the Apache Felix bundle plugin
One container project that has a dependency on all of these small projects and makes an assembly of them using the core assembly maven plugin. This POM also uses the copy-dependencies goal of maven to make sure everything is in place.
Once it is turned into an assembly (ours is a tar file) we deploy this to our servers. We have gone one step further and used this assembly of 3rd party libraries as the Target Platform for our Eclipse build environment. But this may be irrelevant for you.
You can get OSGi friendly versions of many common artifacts from the Spring bundle repository. So you may not have to do it yourself.
See details of how to configure the bundle repository for Maven.
(will update with some ideas for those that aren't available as bundles already)

How do I combine library code and a maven plugin in same project?

Can I make a single maven project that can be included as a dependency (to reference Java classes inside) and executed as a plugin?
I'm working on a library to help with hosting GWT on a LAMP stack. For someone to use this, they need to extend some Java classes (so it must be a dependency) and they need to invoke a maven plugin (so it needs to be a plugin). The plugin code references the same Java classes, so if they are seperate projects, the plugin one must depend on the library one.
As is, I have the library as a normal maven project, and the plugin as a maven plugin that depends on the library. This means that to do a release, I have to release two different artifacts, and the dependent project must update both version numbers for both artifacts. It'd be nice to have a single project.
You'd be better of by doing the following
project for the jar, Foo:Foo.jar
project that uses Foo:Foo.jar as a
dependency that builds the plugin
Maven parent project that
builds 1&2
The directory structure would look like this
\project\pom.xml
\project\foo\pom.xml
\project\foo\src\main\java\foo.java
\project\plugin\pom.xml
\project\plugin\src\main\resources
\project\plugin\src\main\java
From \project you can do a mvn clean package to build \project\foo\target\foo.jar and \project\plugin\target\plugin.jar
Hope this helps.
If you create a maven plugin it still has a artifactId/groupId/version. There's no reason it can't be references both in your section and in your section. On the other hand, if thats ugly, why not just make a library with the common code that both your main project and your maven plugin project depend on?
EDIT:
Sorry, wasn't clear on the second part. Look into composite maven projects, where there is a top level pom that defines a number of child modules. In this case, the maven plugin and the common library code could be separate children producing separate artifacts, but you only need one version number and one release command executed from the top level. I haven't done this but there are any number of open source projects that do. its often used as an idiom to put testing code into a single module that can be referenced by all the others, without having it go out in any distributable jar.
The best practice is to not do what you're suggesting. Examples of this include PMD, BND, JUnit/TestNG, and so on - no serious projects seem to package the maven plugin with the library proper.
One way to get both alternatives is to use maven assemblies to have two seperate maven projects for each the library proper and the plugin and then a separate packaging as a jar containing the classes from both.

Is this the right approach for structuring codebase?

We have a Java codebase that is currently one Web-based Netbeans project. As our organization and codebase grows it seems obvious that we should partition the various independent pieces of our system into individual jars. So one Jar library for the data access layer, one for a general lib, one for a specialized knowledge access, etc. Then we'd have a separate project for the web application, and could have one for a command line tools app, another web app eventually, etc.
What is the recommended practice for doing and managing this? Is it Maven? Can it all be effectively done with just Netbeans alone by simply creating individual projects and setting the dependecies of one project on the jar files of the others?
I'd agree with SteveG above on using Maven2 to help you modularise your code base, but I'd use Nexus as the local repository for Maven instead of Archiva. The guys at Sonatype also have an excellent (free html/pdf) book on how to use Maven, Nexus, and integrate it into IDEs.
Be careful on how you decide to partition up your projects, though. There's no sense in over-complicating your dependencies just for the sake of it.
I would definitely say check Maven(2) out. It is very good for doing this sort of thing. You can define individual models and version then very easily. Netbeans also does a decent job of integrating with.
Also I suggest you set up Archiva which will let you be dependent upon binaries of other artifacts that your company generates internally. This also acts as a proxy and will keep a local copy of any external dependencies your projects might have so its very quick to get the new versions internally.
I would create ant scripts to build the pieces and for deployment. Then you are not depending on your IDE for build/deployment.
It sounds like your code is getting to the point where you're graduating from the WAR approach and have entered into the EAR level.
An EAR is just another archive that contains all the other JARs and WARs that get combined to create an application. There are four types of modules that can reside inside it, Web, EJB, Connectors and Utilities. Most people only use Web and Utilities so they go with using the WEB-INF/lib approach.
But if you're starting to get a lot of interdependencies what you do create an EAR project and make your web project a child of it. Each Utility JAR which is just straight Java code used by other modules also becomes a child of the EAR. Finally in each of your projects there should be a META-INF/manifest.mf file that just has the name of the JARs that JAR/WAR depends on.
I'm an eclipse guy and most of this gets taken care of for you in eclipse, but I'm sure netbeans has very similar functionality.
Now the only problem is that you have to use a full Java EE server to deploy an EAR so I don't think you can use Tomcat if that's what you're currently using.