Piotr Gwiazda
Piotr Gwiazda

Reputation: 12212

How to avoid duplication of derived dependencies in EAR/WAR with Maven?

To make the example as simple as possible, let's say I have classic Java EE 5 application.
Let's say I use x-lib in EAR module, and x-lib uses commons-io.
Also I use y-lib in WAR module, and y-lib uses commons-io too. The EAR is set as provided in WAR.

The result I get is:

- app.ear
    /lib
       x-lib.jar
       commons-io.jar
    /app.war
       /WEB-INF
          /lib
             y-lib.jar
             commons-io.jar

I don't want commons-io to be packaged in app.war/WEB-INF/lib once it is packaged already in app.ear/lib.

In my war's pom.xml I have:

<dependency>
   <groupId>my.group</groupId>
   <artifactId>app</artifactId>
   <type>ejb</artifact>
   <scope>provided</scope>  
   <version>${project.version}</version>
</dependency>

<dependency>
   <groupId>some.other.group</groupId>
   <artifactId>y-lib</artifactId> <!-- This loads commons-io as compile dependency -->
   <version>1.2.3</version>
</dependency>

Is there a way to tell maven that I want everything that is provided along with app ejb dependency should be set to provided and not included in WAR?

I do not want to track all those duplicated JARs and set them as provided or exclude explicitly one by one.

EDIT

I am aware of skinny-war solution. However I don't like the drwaback of duplicating dependencies in WAR and EAR. Maybe you know how to overcome this.

Upvotes: 3

Views: 5925

Answers (4)

Andrea Colleoni
Andrea Colleoni

Reputation: 6021

From the version 2.7 of the maven-ear-plugin, you can use SkinnyWars.
See here for specs: https://maven.apache.org/plugins/maven-ear-plugin/examples/skinny-wars.html

Basically, you can add the skinnyWars tag to your plugin configuration:

<plugin>
  <artifactId>maven-ear-plugin</artifactId>
  <version>2.10.1</version>
  <configuration>
    <defaultLibBundleDir>lib/</defaultLibBundleDir>
    <skinnyWars>true</skinnyWars>
  </configuration>
</plugin>

Upvotes: 1

carlspring
carlspring

Reputation: 32607

You need to add an exclusion like this:

<dependency>
   <groupId>some.other.group</groupId>
   <artifactId>y-lib</artifactId>
   <version>1.2.3</version>
   <exclusions>
      <exclusion>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
      </exclusion>
   </exclusions>
</dependency>

Upvotes: 0

marciopd
marciopd

Reputation: 130

Is there a way to tell maven that I want everything that is provided along with app ejb dependency should be set to provided and not included in WAR?

In this case a think the best option by now is to use wilcards in dependency exclusion. It is only supported in maven 3.

Below is an example of how to declare the ejbmodule dependency from a war project:

    <dependency>
        <groupId>ejbModuleGroupId</groupId>
        <artifactId>ejbModuleArtifactId</artifactId>
        <scope>provided</scope>
        <type>ejb</type>
        <exclusions>
          <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>                
          </exclusion>
        </exclusions>
    </dependency>

You can use this same strategy when declaring a dependency to a ejb-client.

Depending on your maven 3 version, you'll get a nasty warning, but in newer versions it must be fine.

Upvotes: 0

Gimby
Gimby

Reputation: 5284

That SHOULD be automatic if you add the EJB module as a provided dependency to your war module and let all the dependencies of that EJB come transitively. So don't add the overlapping dependencies to your war pom, just let Maven deal with it.

Upvotes: 0

Related Questions