1

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?

Community
  • 1
  • 1
Thunderforge
  • 19,637
  • 18
  • 83
  • 130

2 Answers2

2

You should move the bundle directory restriction under your maven-ear-plugin build configuration as below:

<build>
<finalName>${project.artifactId}</finalName>  
<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-ear-plugin</artifactId>
    <version>${maven-ear-plugin.version}</version>
    <configuration>
       <modules>
         <jarModule>
           <groupId>${group_id}</groupId>
           <artifactId>${artifact_id}</artifactId>
           <bundleDir>lib</bundleDir>
         </jarModule>
         <webModule>
           ...
         </webModule>
      </modules>
      <defaultLibBundleDir>/lib</defaultLibBundleDir>
    </configuration>
  </plugin>
</plugins>

Hope it helps.

tmarwen
  • 15,750
  • 5
  • 43
  • 62
  • This didn't work. I copied it exactly (and changed the version to a hardcoded version, since I don't have that property), but still get the error `Artifact[jar:*:*] is not a dependency of the project` – Thunderforge Feb 25 '14 at 15:41
  • Have you declared the jar module as a **dependency** of your entreprise project? – tmarwen Feb 25 '14 at 16:00
  • Yes, I have declared them as dependencies. Everything builds if I try to make an EAR without trying to move them into a lib folder. There are no errors or missing dependencies or anything when I run `mvn package`. Indeed, I don't think the results I show in the original question would happen if they weren't dependencies. – Thunderforge Feb 25 '14 at 16:13
-1

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
Thunderforge
  • 19,637
  • 18
  • 83
  • 130
  • So the trick was already mentionned in my answer no? Maybe you can accept it since it helped figuring out the solution, thx. – tmarwen Feb 25 '14 at 21:19
  • @tmarwen Your answer contained the `` tag, which was a necessary component to the correct solution, but the wildcard thing was not correct and ultimately the solution didn't work. It would be misleading to accept that one since it's not a working solution, so I'll be accepting this one as it is working for me and hopefully others as well. – Thunderforge Feb 25 '14 at 21:36
  • Sorry, the wildcard was meant to be replaced with your jar group and artifact IDs not to be put as it is... My trick was to add the `` under the **maven-ear-plugin** configuration. – tmarwen Feb 26 '14 at 08:34
  • Please upvote my answer since it helped solving your issue, Thanks. – tmarwen Feb 27 '14 at 08:41