5

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?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
yegor256
  • 102,010
  • 123
  • 446
  • 597

3 Answers3

6

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
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • @Pascal This is just an example. In a real-life project I see a bit more complex situation, when I make a one single change in one file, and then I want to re-install (read "re-deploy to glassfish") the entire project. I don't want all JAR/WAR files to recompile, just the affected ones.. Unfortunately maven re-builds all modules.. Very ineffective, don't you agree? – yegor256 Nov 02 '10 at 12:16
  • @Vincenzo: What is your use case exactly? – Pascal Thivent Nov 02 '10 at 14:37
  • @Pascal 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. It takes so much time.. – yegor256 Nov 02 '10 at 15:04
  • @Vincenzo if you are really interested in that functionality look at maven-reactor-plugin – John Vint Nov 02 '10 at 15:36
  • @John There is no need for the maven-reactor-plugin, all features are available in the native maven client. – Pascal Thivent Nov 02 '10 at 15:43
  • I deleted my comment after I noticed it – John Vint Nov 02 '10 at 15:45
  • @Pascal Thanks for the explanation. I used to `make`, which understands dependencies between files, and always build incrementally. Sorry to hear that `maven` is designed differently.. I can't actually understand why.. – yegor256 Nov 02 '10 at 17:56
  • @Vincenzo You could open a bunch of Jira issues and see what developers say. – Pascal Thivent Nov 02 '10 at 18:38
  • @Pascal I explained it at [MNG-4885](http://jira.codehaus.org/browse/MNG-4885), will see what they say.. – yegor256 Nov 02 '10 at 19:17
  • @PascalThivent Even maven core doesn't actually supports it. We need `incremental-build-plugin` to get this functionality. [REFERENCE](http://harshana05.blogspot.com/2011/05/apache-maven-incremental-build-support.html). Also that plugin doesn't support `Incremental-Testing`. – raksja Jul 12 '12 at 22:20
4

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.

dogbane
  • 266,786
  • 75
  • 396
  • 414
  • 1
    Actually, `install` is a phase, not a plugin. And no, you should not use `jar:jar` but the `package` phase instead (that's the whole point of having a build lifecycle made of phases). – Pascal Thivent Nov 02 '10 at 11:18
  • 1
    yes, "install" is a phase during which the Install Plugin runs. Similarly, the Compiler plugin is used during the "compile" phase. – dogbane Nov 02 '10 at 12:00
  • My point was that 1. plugins don't enforce anything, the build life cycle does (the install plugin doesn't trigger e.g. tests). 2. you usually invoke phases, not plugins. – Pascal Thivent Nov 02 '10 at 15:50
2

'test'is default phase in 'build' life cycle. If you want to skip tests during install add this to pom.xml,

<build>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
        <skipTests>true</skipTests>
        </configuration>
    </plugin>
   </build> 

And then create a profile say 'test' which will contain test configuration. If you want to execute tests, do mvn -Ptest test.

As dogbane already answered you can not skip in any other way.

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
Adisesha
  • 5,200
  • 1
  • 32
  • 43
  • Tests are the least time-consuming operation, how about static code analysis? I should do these tricks in every plugin? :( – yegor256 Nov 02 '10 at 10:52
  • Yes you are right. But as far as I know there is no other way.Let us know if you find another way other than I mentioned. – Adisesha Nov 02 '10 at 11:25
  • @Adi I wanted something like this. Although I don't know how to write separate profiles and setting which one to work when. So I just added it until writing more code, and will remove/comment it when got 2 test. – coding_idiot Jan 25 '13 at 11:54