0

Can mvn compile be expected to work with multi-module Maven reactor builds?

I am trying to work on a project that uses a reactor/multi-module Maven build. When mvn compile failed*, I was told by persons familiar with the project that mvn install is needed, and not mvn compile, because it is a reactor build.

While mvn install indeed works because Maven can then pull the build dependency out of the local repository, it seems wrong to me that I must publish to the repository since doing so can create problems, especially in CI environments.

However, nearly every example I can find surrounding a multi-module project uses mvn clean install, including Maven by Example. I have found no examples of mvn compile that I can attribute to multi-module projects, making me inclined to think there is a Maven limitation/requirement here.

I note that mvn compile did work for me with the example provided in Maven by Example, but that is a relatively simple project so I know I cannot take that to mean it should work in general.

* It failed because it could not find one of the dependencies that was built successfully earlier in the reactor build.

vossad01
  • 11,552
  • 8
  • 56
  • 109
  • which version of maven are you using? – SkyWalker Dec 08 '17 at 17:54
  • Apache Maven 3.5.2 – vossad01 Dec 08 '17 at 18:00
  • As far as I know, maven needs to put built artifact into local repo in order to be able to find it if it is used as dependency for other project even for multy module projects. I am not sure why you dont want the artifact to be in the local repo? – tsolakp Dec 08 '17 at 20:21
  • @tsolakp Consider a CI Server, machine-local means global to all the builds on that server. By doing an `install` the compilation artifacts of one build become visible to another build. This means a mis-configured build could wrongly succeed because it could pull dependencies from the local repo. Or another build could fail when it should have passed because of differences between the local repo copy from a build and the remotely-published dependency that was expected. – vossad01 Dec 08 '17 at 21:39
  • Honestly I have never needed to worry about use case like yours. Usually maven snapshots and versioning help to avoid situation like this. One thing you can do is run `mvn versions:set -DnewVersion=` before running "mvn install` so as to never impact other projects. – tsolakp Dec 08 '17 at 21:45
  • 1
    A multi module project is usually being built by using `mvn clean package`. The install is only necessary if any other project (unrelated to the modules in the reactor) will use one or more of the built projects as dependencies... – khmarbaise Dec 09 '17 at 10:46

4 Answers4

0

You can use --also-make-dependents option. It configures Maven to build the project and its dependents. Actually, the command examines all of the projects in reactor to find projects that depend on a particular project. It will automatically build those projects and nothing else.

$ mvn --projects your-sample-project --also-make-dependents install

Resource Link: Maven Tips and Tricks: Advanced Reactor Options

SkyWalker
  • 28,384
  • 14
  • 74
  • 132
  • That still uses `install` and not `compile`, so I am not sure what is gained – vossad01 Dec 08 '17 at 18:11
  • From documentation, `mvn install` - This command executes each default life cycle phase in order (validate, compile, package, etc.), before executing install. – SkyWalker Dec 08 '17 at 18:20
  • The point of my question is that I don't want to execute install. – vossad01 Dec 08 '17 at 18:22
  • Actually you are mixing normal maven project and multi module project. . And in reactor[The Reactor takes care of ordering components to ensure that interdependent modules are compiled and installed in the proper order.] Please go through: [Guide to Working with Multiple Modules](https://maven.apache.org/guides/mini/guide-multiple-modules.html) – SkyWalker Dec 08 '17 at 18:32
  • Are you saying that something is configured, making it a mixed build, therefore `compile` does not work and otherwise it would? Unless I am missing navigation the guide you linked is just a single page that does not appear to answer the question. – vossad01 Dec 08 '17 at 20:09
0

If your multi-module project has interdependencies on each other it is actually quite logical that you need to at least install these dependencies to your local repository before others are compile-able.

Ivonet
  • 2,492
  • 2
  • 15
  • 28
  • Would it not also be logical for Maven to recognize it just built a component and use the just built version? – vossad01 Dec 08 '17 at 19:50
  • Not really. Maven Separates concerns. Therefore if a module (A) has a dependency on another module (B). This other module (B) needs to be available for module (A) to compile... – Ivonet Dec 08 '17 at 19:58
  • Which is why the reactor figures out that that B needs to be built first and builds it before A. – vossad01 Dec 08 '17 at 20:00
  • 1
    An install is for a multi module built not needed. Only `mvn clean package`. If it is really needed than your multi module build is broken (missing inter module dependencies)... – khmarbaise Dec 09 '17 at 10:47
0

As indicated in @khmarbaise's comment and demonstrated by the fact it works with the Maven By Example example. mvn compile and mvn test can work with reactor builds.

However, not all plugins work well with this approach. For example, making test-jar's work can require changing the phase.

Using mvn package as suggested by @khmarbaise is likely to give far fewer of these issues while also avoiding the problems caused by using mvn install or mvn deploy.

vossad01
  • 11,552
  • 8
  • 56
  • 109
0

I have run into this issue for multi-module projects. For example, I'll have a module called base that every other module depends on, for both normal scope as well as test scope. The test scope dependency is there so I can share common unit test classes and utilities.

The mvn compile will fail with on the test-scoped deps with a message like Could not resolve dependencies for project com.example:zydeco:jar:0.0.1: Failure to find com.example:base:jar:tests:0.0.1

However using mvn test -Dmaven.test.skip.exec=true, which is in spirit the same as compile, and it will find resolve all intra-project test dependencies just fine.

If I run something like mvn dependency:tree, it will fail for regular dependencies with a message like Could not resolve dependencies for project com.example:zydeco:jar:0.0.1: Failure to find com.example:base:jar:0.0.1

I agree with other folks that avoiding package and install is desirable - to avoid having stale code lying around. In the past, I've actually written scripts which create empty/fake jar files so that commands like mvn dependency:build-classpath can work.

I'm not sure there is away around this with maven. It's on my list to look at sbt and gradle.

Doug Donohoe
  • 367
  • 1
  • 3
  • 11