Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Maven is running tests again, when JAR is already there?

Tags:

java

maven-2

I install my maven project:

mvn clean install

Everything works fine, JAR file is created in /target directory. Now I run it again:

mvn install

Maven executes unit tests and static code analysis again. I didn't make any changes to the .java files and JAR is there, so why running tests again? Am I doing something wrong or is it how maven is designed?

like image 432
yegor256 Avatar asked Dec 17 '22 20:12

yegor256


2 Answers

Now I run it again (...) Maven executes unit tests and static code analysis again

Because that's simply what you're asking Maven to do.

When you call a build phase, Maven will execute not only that build phase, but also every build phase prior to the called build phase. Thus, invoking:

mvn install

will run every build phase preceding install (validate, compile, test, package, etc), before executing install and also the plugins you bound to these phases.

And while Maven does support incremental compilation of Java sources, other plugins are not that smart and will be fired again.

Now, some remarks/suggestions:

  • what's the point of running install if you didn't change anything?
  • if you don't want to run static code analysis at each build, use a special profile.

A multi-module project, with extensive testing and static code analysis. I run mvn clean install, then I change one single java file in one module. Then I run mvn install and expect maven to test/analyze only this particular module, which was changed. Unfortunately, it re-tests and re-analyzes all modules.

Indeed, if you run mvn install as part of a reactor build, will run mvn install on all modules and tests and analysis will go again on all modules. That's maybe not what you expect, but that's what you'll get (AFAIK, static analysis plugin are not aware of changes - I'm not able to explain why things aren't better).

It takes so much time.

I suggest to use the advanced reactor options to only build a subset of the modules. These options are:

-rf, --resume-from
        Resume reactor from specified project
-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
-amd, --also-make-dependents
        If project list is specified, also build projects that depend on projects on the list 

So in your case, you could run something like (assuming you touched module-foo):

mvn -pl module-foo,my-packaged-app install

or, to rebuild all projects that depend on module-foo:

mvn -pl module-foo -amd install
like image 98
Pascal Thivent Avatar answered Dec 27 '22 09:12

Pascal Thivent


Unfortunately, this is how the maven install plugin is designed. It enforces best practices, like always running tests before doing an install, because other environmental factors may have changed even if your code hasn't.

If you only want to compile incrementally (i.e. only those files that have changed since the last build), then you should use the compiler plugin by invoking mvn compile and then to build the jar use mvn jar:jar.

To skip tests: mvn -Dmaven.test.skip=true install.

like image 40
dogbane Avatar answered Dec 27 '22 10:12

dogbane