views:

507

answers:

6

In our company, we have a number different modules constructed as separate wars. Each client can pick and choose module he wishes to buy. Since all modules share same session, security context etc, it makes sense to merge them into a single war.

Is it possible to automate this process? For example, it should merge web.xml, calculate each wars dependencies, copy files like .jsp and .class etc. By the way, we are using Maven, but were not able to find a solution to this problem.

+1  A: 

It's clearly possible to do this, but I think that you would be better off working on a single WAR in the first place. Late "pick-and-mix" of WAR contents sounbds like a support nightmare to me.

djna
If the client doesn't buy the module, then I do not want to distribute the module to client (and resort to hiding it..) . Also, such war would be huge - that would be highly impractical for development purposes etc.
Dan
Joke: Better hope that no customer wants to buy the lot then! I understand why you want to do this. I don't know of any easy way to achieve waht you want though some of the links here are interesting.
djna
A: 

Generally speaking - no, it's not possible. What if you have duplicate JSP names? Servlet names / mappings? Same context listeners loading with different parameters (common if you're using Spring / Struts / etc...)? You get the point.

In your particular case it may or may not be possible depending on your specific circumstances. Extracting war and copying JSP / classes / libraries over is easy; merging web.xml is a bit more complex as you have to maintain the element order - it may be easier to manually define a "merged" web.xml.

ChssPly76
I'd be happy enough to have the tool that aborts if any of such conflicts are discovered.
Dan
A: 

You might be able to get something working with One-Jar.

http://one-jar.sourceforge.net/

It probably doesn't do everything you want.

Nate
One-jar will not work with wars.
Thorbjørn Ravn Andersen
+2  A: 

I recall that the cargo-maven2-plugin has an uberwar mojo. I've not used it but I understand it is intended to merge wars, though you need to be careful to avoid conflicts.

A quick scan of the source indicates you define a merge descriptor to determine how to merge the wars. Unfortunately the documentation site has gone missing so I can't give you any more details.

You can check out the Codehaus Jira site for an understanding of its current status.

To use the plugin you'd specify the configuration something like this:

<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.cargo</groupId>
      <artifactId>cargo-maven2-plugin</artifactId>
      <version>1.0</version>
      <extensions>true</extensions>
      <configuration>
      <descriptor>merge.xml</descriptor>
      </configuration>
    </plugin>
  </plugins>
</build>
<dependencies>
  <dependency>
    <groupId>project1.groupId</groupId>
    <artifactId>project1</artifactId>
    <type>war</type>
    <version>1.0.0</version>
  </dependency>
  <dependency>
    <groupId>project2.groupId</groupId>
    <artifactId>project2</artifactId>
    <type>war</type>
    <version>1.2.0</version>
  </dependency>
</dependencies>

(still looking for a merge.xml example)

Rich Seller
@Pascal I tend to agree, but if there is no option to refactor, this provides a workaround
Rich Seller
@Rich Sure, that's true and I gave you my +1. I removed my previous comment as it can be misinterpreted.
Pascal Thivent
See http://cargo.codehaus.org/Merging+WAR+files
Pascal Thivent
+1  A: 

Granted the risks mentioned by djna and ChssPly76, you may be able to achieve this by using overlays with the Maven WAR plugin. This will require you to separate out servlet mappings to ensure you don't have any URL collisions and the like, but it might do the trick.

Basically, you create a module with multiple WAR dependencies and use the plugin to merge them into a new one.

Steve Reed
A: 

EARs are designed to hold multiple things. Would this be a possibility for you?


Edit: First of all, lets assume that there is no duplicate resources (which one should go in the final jar?) and that all jars are compatible (you only have one version of each library etc.).

You should be able to just copy the content of WEB-INF/ on top of each other, except the various XML files which need to be carefully merged. The easiest way to do this is probably by using a XSLT style sheet which allow you to hold two XML documents and merge them (if I recall correctly this is the tag). you will need one for each xml file in order to be CERTAIN that you do this correctly - just think about JSF navigation.

So, my suggetsion is a simple copy of resources and a hand crafted XSLT style sheet pr xml configuration file.

Thorbjørn Ravn Andersen
It is an option (that would limit the number of web servers) but in that case I still need to share session and security context between wars. Some app servers permit sharing of the http session between wars, but this does not seem to be the standard feature.
Dan