This article discusses about the most common issues when using Maven from a Java EE perspecitve and how to solve them.
1) My Maven test are not running. How Test in Maven are executed ?
Unit test are executed as part of a well defined phase of Maven. Maven has the following lifecycle phases:
validate – validate the project is correct and all necessary information is available
compile – compile the source code of the project
test – test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
package – take the compiled code and package it in its distributable format, such as a JAR.
integration-test – process and deploy the package if necessary into an environment where integration tests can be run
verify – run any checks to verify the package is valid and meets quality criteria
install – install the package into the local repository, for use as a dependency in other projects locally
deploy – done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.
So by default, in order to execute your test classes, you need to launch a:
These build phases are executed sequentially to complete the default lifecycle. Therefore to do all those, you only need to call the last build phase to be executed, in this case, deploy:
That being said, the maven-surefire-plugin requires to follow a precise naming convention, which is however configurable. So a class to be eligible as unit test needs to be named with these patterns:
If your test class doesn’t follow these conventions, you should rename it or configure Maven Surefire Plugin to use another pattern for test classes. Example:
<project> [...] <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.17</version> <configuration> <includes> <include>Sample.java</include> </includes> </configuration> </plugin> </plugins> </build> [...] </project>
2) How do I execute tests after the application has been deployed ?
You probably want to execute integration tests, which means a kind of tests which require a system configured and ready to execute tests.The Maven build lifecycle now includes the “integration-test” phase for running integration tests, which are run separately from the unit tests run during the “test” phase. It runs after “package”, so if you run “mvn verify”, “mvn install”, or “mvn deploy”, integration tests will be run along the way.
By default, integration-test runs test classes named **/IT*.java, **/*IT.java, and **/*ITCase.java, but this can be configured.
So follow these steps:
- Rename your unit tests to use the pattern mentioned (e.g. *IT.java)
- Include failsafe plugin and bind it to the executions of the integration-test and verify phase
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>failsafe-maven-plugin</artifactId> <version>2.4.3-alpha-1</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin>
to deploy your application
then execute a:
to execute your Integration tests
3) How do I skip test execution in Maven?
You can skip test execution by executing:
mvn package -DskipTests
If you are doing it on a regular basic, then you can insert in your pom.xml file
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>true</skipTests> </configuration> </plugin>
4) Maven does not updates libraries. How do I force it ?
Maybe you have already come through this error message which says:
Failure to transfer [artifact] from http://repo1.maven.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced.
So what happened ? you should be aware of how libraries are loaded by Maven. Suppose that you need a sample-1.0-SNAPSHOT.jar library. Maven will know that this version is not stable and is subject to changes. So, even if the version of this library is found on the local repository, Maven will try to find a newer version in the remote repositories. However, this check is made only once per day. That means that if you have a foo-1.0-20110506.110000-1.jar (i.e. this library has been generated on 2011/05/06 at 11:00:00) in your local repository, and if you run the Maven build again the same day, Maven will not check the repositories for a newer version.
You can change this behaviour in two ways:
Just once: issue a
mvn clean install -U
where -U means force update of dependencies.
If you want to change this update policy in your repository definition:
<repository> <id>foo-repository</id> <url>...</url> <snapshots> <enabled>true</enabled> <updatePolicy>XXX</updatePolicy> </snapshots> </repository>
where XXX can be:
always: Maven will check for a newer version on every build;
daily: the default value;
interval:XXX: an interval in minutes (XXX)
never: Maven will never try to retrieve another version. It will do that only if it doesn’t exist locally. With the configuration: SNAPSHOT version will be handled as the stable libraries.