436

I have a multi-module Maven project with a parent project P and three sub-modules A, B, and C. Both B and C are war projects and both depend on A.

I can type mvn compile in P and have all of the sub-modules properly compiled. The problem comes when I want to do operations for specific modules.

I'd like to be able to package a war for project B, but when I run the package command from B's directory, it complains that it can't find the dependencies for A.

I understand from this question: Maven and dependent modules that perhaps Maven isn't really designed for this type of dependency resolution, but that begs the question of how do I package B?

  1. Do I have to run mvn package for the entire project hierarchy when I really just want B?

  2. Do I have to install snapshots of A into my local repository every time I want to package B?

This second scenario isn't much fun when A is still under active development.

Any best practices here?

Community
  • 1
  • 1
Brian Ferris
  • 6,222
  • 5
  • 23
  • 27

6 Answers6

777

Any best practices here?

Use the Maven advanced reactor options, more specifically:

-pl, --projects
        Build specified reactor projects instead of all projects
-am, --also-make
        If project list is specified, also build projects required by the list

So just cd into the parent P directory and run:

mvn install -pl B -am

And this will build B and the modules required by B.

Note that you need to use a colon if you are referencing an artifactId which differs from the directory name:

mvn install -pl :B -am

As described here: https://stackoverflow.com/a/26439938/480894

Roland
  • 6,452
  • 9
  • 52
  • 104
Pascal Thivent
  • 535,937
  • 127
  • 1,027
  • 1,106
  • 16
    For anyone hitting this page in 2011, this is the better answer. There's now better support for multi-modules within maven itself (Maven 2.1 and above), you don't need to use the reactor plugin. – Spedge May 20 '11 at 09:39
  • 19
    Another very useful option is "-amd, --also-make-dependents", which builds all modules dependent on projects in the reactor list. – deterb May 22 '11 at 01:13
  • 2
    What about building a grandchild module ? – Bax Sep 16 '16 at 19:23
  • 13
    @Bax, use `mvn install -pl .,parent/child,parent/child/grandchild ` Use comma to separate multiple projects and . for parent pom – Neo Jan 21 '17 at 02:35
  • 1
    Are the two terms "module" and "project" used for the same thing in the documentation that you cite, and in Maven in general? – Lii Aug 27 '18 at 11:21
  • I find it a bit surprising that the parent pom isn't considered a dependent, for purposes of `-am`. Is there a way to indicate the parent should also be built? – Jeff Evans Jul 17 '20 at 22:25
43

Say Parent pom.xml contains 6 modules and you want to run A, B and F.

<modules>
        <module>A</module>
        <module>B</module>
        <module>C</module>
        <module>D</module>
        <module>E</module>
        <module>F</module>
  </modules>

1- cd into parent project

 mvn --projects A,B,F --also-make clean install

OR

mvn -pl A,B,F -am clean install

OR

mvn -pl A,B,F -amd clean install

Note: When you specify a project with the -am option, Maven will build all of the projects that the specified project depends upon (either directly or indirectly). Maven will examine the list of projects and walk down the dependency tree, finding all of the projects that it needs to build.

While the -am command makes all of the projects required by a particular project in a multi-module build, the -amd or --also-make-dependents option configures Maven to build a project and any project that depends on that project. When using --also-make-dependents, Maven will examine all of the projects in our reactor to find projects that depend on a particular project. It will automatically build those projects and nothing else.

Waqas Ahmed
  • 1,126
  • 1
  • 12
  • 13
10

Maven absolutely was designed for this type of dependency.

mvn package won't install anything in your local repository it just packages the project and leaves it in the target folder.

Do mvn install in parent project (A), with this all the sub-modules will be installed in your computer's Maven repository, if there are no changes you just need to compile/package the sub-module (B) and Maven will take the already packaged and installed dependencies just right.

You just need to a mvn install in the parent project if you updated some portion of the code.

victor hugo
  • 34,018
  • 12
  • 65
  • 76
  • 5
    It would be a nightmare during the development, image that once you make a fix in the sub module, you will have install it, and then you start the servlet container. Life is short :( – hguser Nov 25 '15 at 08:20
9

If you have previously run mvn install on project B it will have been installed to your local repository, so when you build package A Maven can resolve the dependency. So as long as you install project B each time you change it your builds for project A will be up to date.

You can define a multi-module project with an aggregator pom to build a set of projects.

It's also worthwhile mentioning m2eclipse, it integrates Maven into Eclipse and allows you to (optionally) resolve dependencies from the workspace. So if you are hacking away on multiple projects, the workspace content will be used for compilation. Once you are happy with your changes, run mvn install (on each project in turn, or using an aggregator) to put them in your local repository.

Anirudh Ramanathan
  • 43,868
  • 20
  • 121
  • 177
Rich Seller
  • 79,705
  • 22
  • 167
  • 173
  • 2
    Is there an easy way to guarantee that all the dependent projects for my target project have been installed? The hierarchy I have is actually much more complex than the one described here, so try to remember if I've run mvn install for each dependent project since I've last made code changes could be tricky. – Brian Ferris Jul 11 '09 at 16:28
  • Yes, using modules to build the set of projects, see the link added to the original answer. – Rich Seller Jul 11 '09 at 16:36
5

Take a look at my answer Maven and dependent modules.

The Maven Reactor plugin is designed to deal with building part of a project.

The particular goal you'll want to use it reactor:make.

Community
  • 1
  • 1
deterb
  • 3,878
  • 1
  • 24
  • 33
  • 5
    This used to be the right answer, but with Maven 2.1 you no longer need to use the reactor plugin. Look at Pascal's answer in this thread relating to "Advanced Reactor Options" – Spedge May 20 '11 at 09:40
4

You say you "really just want B", but this is false. You want B, but you also want an updated A if there have been any changes to it ("active development").

So, sometimes you want to work with A, B, and C. For this case you have aggregator project P. For the case where you want to work with A and B (but do not want C), you should create aggregator project Q.

Edit 2016: The above information was perhaps relevant in 2009. As of 2016, I highly recommend ignoring this in most cases, and simply using the -am or -pl command-line flags as described in the accepted answer. If you're using a version of maven from before v2.1, change that first :)

Zac Thompson
  • 11,645
  • 40
  • 55