Search code examples
javamavenear

Move All Dependencies in EAR to Subfolder in Maven


I am currently building an EAR file in Maven. When I build it, I get the following in my target folder:

-target/
    -MyProject.ear
    -MyProject/
        -MainProject.jar
        -Dependency.jar

If I open up MyProject.ear in 7Zip, I see the same file structure that exists in MyProject/

I have been asked to change this so that all dependencies are in a subfolder, like this:

-target/
    -MyProject.ear
    -MyProject/
        -MainProject.jar
        -lib/
            -Dependency.jar

Now I can make this work for the one dependency by making the following change to my pom.xml file:

<build>
    [...]
    <plugins>
        <plugin>
            <artifactId>maven-ear-plugin</artifactId>
            <version>2.9</version>
            <configuration>
                <modules>
                    <jarModule>
                        <groupId>Dependency</groupId>
                        <artifactId>Dependency</artifactId>
                        <bundleDir>lib</bundleDir>
                    </jarModule>
                </modules>
            </configuration>
        </plugin>
    </plugins>
</build>

However in the real project, I have about 30 dependencies. I could manually add a <jarModule> tag for each and every dependency, but ideally I would like for it to automatically move all of the dependencies to a subdirectory (making an exclusion for MainProject.jar).

I had hoped that I could declare <jarModule> once and use wild card characters for the groupId and artifactId, like Maven allows with exclusions:

<!-- Moving all for the time being, add the exclusion if it works -->
<jarModule>
    <groupId>*</groupId>
    <artifactId>*</artifactId>
    <bundleDir>lib</bundleDir>
</jarModule>

I would expect the above to take all artifacts and put them into a lib folder. Unfortunatley, this doesn't seem to work in Maven 3.2.1, providing an error saying that Artifact[jar:*:*] is not a dependency of the project

So how can I move all of my dependencies to a subfolder when building an EAR in Maven?


Solution

  • Thanks to a happy accident of failing to fully clean up my pom file after a test, I discovered how to do this.

    In the <configuration> tag, add <defaultLibBundleDir>/lib</defaultLibBundleDir>. This will put all modules by default in a lib folder in a root of a directory. No wildcards are needed; in fact, Maven doesn't support wild cards in this part, probably because there are no clear bounds (it could be interpreted as "move all artifacts ever"). Wild cards only work for exclusions because there are clear bounds; it's a subset of a clearly defined set of artifacts.

    If you'd like to make an exception, then you specify the module and type in <bundleDir>/</bundleDir>, which will place it back in the root. The full XML looks like this:

    <build>
    [...]
    <plugins>
      <plugin>
           <artifactId>maven-ear-plugin</artifactId>
           <version>2.9</version>
           <!-- All dependencies not otherwise specified are going in /lib -->
           <defaultLibBundleDir>/lib</defaultLibBundleDir>
           <modules>
             <jarModule>
               <!-- An exception to keep the main project in the root -->
               <groupId>MainProject</groupId>
               <artifactId>MainProject</artifactId>
               <bundleDir>/</bundleDir>
             </jarModule>
          </modules>
        </configuration>
      </plugin>
    </plugins>
    

    This results in the original goal of putting all dependencies in a lib folder except for MainProject.jar:

    -target/
        -MyProject.ear
        -MyProject/
            -MainProject.jar
            -lib/
                -Dependency.jar