Top 10 Maven questions by Java developers

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:

mvn test

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:

mvn 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:

Test*
*Test
*TestCase

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>

execute a:

mvn deploy

to deploy your application
then execute a:

mvn verify

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.

 

5) How can I manually install a library  to Maven repository?

Due the binary license, some libraries could not available in public repository. For example, there is no public repository with the Oracle Driver JAR.

So how do you overcome with this issue ? Once you've downloaded the JAR just add it to your computer repository with (note I pulled the groupId, artifactId and version from the POM):

mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 \
     -Dversion=10.2.0.3.0 -Dpackaging=jar -Dfile=ojdbc.jar -DgeneratePom=true

The last parameter for generating a POM will save you from pom.xml warnings

6) Cannot find the web.xml file:

Error assembling WAR: webxml attribute is required
This is a very frequent issue that you could meet when you try to deploy a web application. This happens if you forgot to include the web.xml file in your Web application or that maybe it's not in the location where Maven war plugin expects to find it.
In either case you can fix it by stating explicitely where the web.xml is. For example, here is where Maven will look fr web.xml by default:

 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <webXml>${project.basedir}\src\main\webapp\WEB-INF\web.xml</webXml>
                </configuration>
            </plugin>
        </plugins>
 </build>

7) How to run a Java class using Maven ?

Executing a Java class can be done in a few ways. If you do not want to add anything to your configuration, you could use the maven-exec-plugin and adding parameters on the command line. Example:

mvn exec:java -Dexec.mainClass="com.example.Main"

This will run your class in the JVM.

If you're doing this regularly, you can add the parameters into the pom.xml as well:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.2.1</version>
  <executions>
    <execution>
      <goals>
        <goal>java</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <mainClass>com.example.Main</mainClass>
    <arguments>
      <argument>foo</argument>
      <argument>bar</argument>
    </arguments>
  </configuration>
</plugin>

8) How do I remove unused dependencies in your project?

The simplest and recommended way to find the used and unused dependencies in your project is by running the Maven dependency:analyze goal. The dependency:analyze analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared.

[WARNING] Used undeclared dependencies found:
[WARNING]    javax.inject:javax.inject:jar:1:compile
[WARNING] Unused declared dependencies found:
[WARNING]    org.jboss.spec.javax.ejb:jboss-ejb-api_3.2_spec:jar:1.0.0.Final:pro
vided
[WARNING]    javax.validation:validation-api:jar:1.0.0.GA:compile
[WARNING]    javax.enterprise:cdi-api:jar:1.1:provided

9) How to change the Java version used by Maven to compile ?

By default Maven will use JAVA_HOME to determine which Java version to use. You can check the actual Maven configuration by issuing:

mvn clean --debug

Apache Maven 3.2.1 (ea8b2b07643dbb1b84b6d16e1f08391b666bc1e9; 2014-02-14T18:37:52+01:00)
Maven home: C:\apache-maven-3.2.1\bin\..
Java version: 1.7.0_51, vendor: Oracle Corporation
Java home: C:\Java\jdk1.7.0_51\jre

You should as well include in your maven compiler plugin a version which matches with the value for your Java version:

    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.0</version>
        <configuration>
            <source>1.7</source>
            <target>1.7</target>
        </configuration>
    </plugin>

10) How to include a dependency from a file system path (instead of Maven repository) ?

Althoug Maven is built around the concept of Repository, you can have occasionally the need to reference libraries which are contained in a standard file system. In order to do that, include the systemPath element in your dependency as in the following example:

<dependency>
      <groupId>samexampleple</groupId>  
       <artifactId>com.example.lib</artifactId>  
       <version>1.0</version>
      <scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/mylib.jar</systemPath>
</dependency>

References: http://stackoverflow.com/questions/1074869/find-oracle-jdbc-driver-in-maven-repository
http://stackoverflow.com/questions/5901378/what-exactly-is-a-maven-snapshot-and-why-do-we-need-it
http://stackoverflow.com/questions/6178583/maven-does-not-find-junit-tests-to-run
http://stackoverflow.com/questions/9846046/run-main-class-of-maven-project
http://stackoverflow.com/questions/7456006/maven-packaging-without-test-skip-tests

 

Francesco Google+