A Handy Reference of Maven Parameters

I cannot count the times I have looked up the following through Google. Thus I decided to put together a few handy parameters (or properties or whatever is the correct term) for Maven builds.

All the below are given with the goal install but they can safely be used with any other Maven goal as well.

Skip Tests

mvn install -DskipTests

Build Only From Specified Project

This is only relevant in a multi pom.

mvn install -rf :[artifactId]

Don’t Compile JavaDoc

-Dmaven.javadoc.skip=true

Don’t Compile GWT

-Dgwt.compiler.skip=true

 

Generate md5 Hash for Maven

Maven creates and checks MD5 checksums at various times. For instance, when downloading an artifact from a repository, Maven checks whether the checksum of the downloaded files (e.g. POM, JAR) is correct.

I am uploading Maven artifacts manually to a very simple, file-based repository. This requires me to calculate the Maven checksum for artifacts manually.

What sounds like a simple problem at first actually turned out to be quite tricky (as it often does with Maven? Well, I guess it’s still better than regular expressions!).

After digging around in the project checksum-maven-plugin, I finally figured out how to generate MD5 checksum files in a way that Maven will accept. The key here was to use the Hex class from Bouncy Castle to turn the MD5 digest into a String.

Following the rough-cut code to create a hash file for Maven (extracted from the maven-tools project, class WriteHashes):

public static void writeMd5(final Path baseFile) throws NoSuchAlgorithmException, IOException {
        final FileInputStream fis = new FileInputStream(baseFile.toFile());

        final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.reset();
        final byte[] buffer = new byte[1024];
        int size = fis.read(buffer, 0, 1024);
        while (size >= 0) {
            messageDigest.update(buffer, 0, size);
            size = fis.read(buffer, 0, 1024);
        }

        final String result = new String(Hex.encode(messageDigest.digest()));

        fis.close();

        final Path md5File = baseFile.getFileSystem().getPath(baseFile.toString() + ".md5");

        FilesJre.wrap(md5File.toFile()).setText(result);
    }

Setting Up Xtend with Maven and eclipse (Luna)

Xtend is currently my favourite alternative language for the JVM (closely followed by Kotlin). Unfortunately, I did not find a good guide of how to set up a Maven project within eclipse (Luna) which uses Xtend.

Specifically the following guide will allow you to allow you to write test cases in Xtend for your existing Java projects. A great way to get started with Xtend I suppose.

The following describes the necessary steps.

  • Install the Xtend plugin for eclipse as described here.
  • Add the xtend-maven-plugin to your pom.xml as follows:
<plugin>
    <groupId>org.eclipse.xtend</groupId>
    <artifactId>xtend-maven-plugin</artifactId>
    <version>2.7.1</version>
    <executions>
        <execution>
            <goals>
                <goal>testCompile</goal>
            </goals>

            <configuration>
                <testOutputDirectory>${basedir}/src/test/java</testOutputDirectory>
            </configuration>

        </execution>
    </executions>
</plugin> 
  • Also add a dependency to the Xtend runtime libraries
<dependency>
    <groupId>org.eclipse.xtend</groupId>
    <artifactId>org.eclipse.xtend.lib</artifactId>
    <version>2.7.1</version>
    <scope>test</scope>
</dependency>
  • Right click the project and select Maven / Update Project … and update the project.
  • Right clock the project and select Properties
  • Go to the Xtend / Compiler page
  • Set as the ouput director src/test/java

  • Go to the folder src/test/xtend. If the folder does not exist, create it.
  • Right clock the folder src/test/xtend and select Build Path / Use As Source Folder
  • Create a package in the new src/test/xtend folder and right click the package. Select New / Xtend class and define a class such as the following:
package de.mxro.async.map.tests
 

import org.junit.Assert
import org.junit.Test
 

class TestThatNumbersAreEqual {
    
    @Test
    def void test() {
        Assert.assertTrue(3 == 3)
    }
    
    
}
  • Immediately after you save the class a translated class should be created in the folder src/test/java

Now, have fun writing tests using Xtend’s concise syntax – while not affecting any step of your build and development workflow!

To see an example configuration in a complete project, also check out async-map on GitHub.

Force Android Studio to Update Maven Snapshot Dependencies

Problem

You are using Gradle to build your Android Studio project and you have linked Maven SNAPSHOT modules.

When you build your project, Gradle/Android Studio does not grab the latest version of the SNAPSHOT module but instead uses a cached version.

Solution

Add the following to your build.gradle:

configurations.all {

resolutionStrategy {

cacheChangingModulesFor 0, ‘seconds’

}

}

References

Gradle DSL Documentation – Resolution Strategy

Gradle Documentation Chapter 50, Section 50.9.22 Refresh

Gradle Forum – Use latest version of changing module

Setting Up eclipse Luna with Maven for Android

As of August 2014, don’t even try this.

Officially, the Google Eclipse plugin supports Eclipse 4.4 (Luna) at present. However, in order to be able to create projects which are both Maven projects and Android projects you will need to install the m2e-android plugin. This currently does not support eclipse Luna. Probably, if you create a new Android project based on the archetype suggested by the m2e-android plugin, you might get errors such as:

  • …R cannot be resolved to a variable
  • Plugin execution not covered by lifecycle configuration: com.jayway.maven.plugins.android.generation2:android-maven-plugin:3.8.2:generate-sources (execution: default-generate-sources, phase: generate-sources)
  • Project configurator “me.gladwell.eclipse.m2e.android.androidDevelopmentToolsProjectConfigurator” is not available. To enable full functionality, install the project configurator and run Maven->Update Project Configuration.
  • Plugin execution not covered by lifecycle configuration: com.jayway.maven.plugins.android.generation2:android-maven-plugin:3.8.2:proguard (execution: default-proguard, phase: process-classes)

My recommendation is to use Android Studio.

You can easily add Maven dependencies to projects in Android Studio. Just locate the ‘build.gradle’ file in your application directory and add a compile dependency.

Jenkins StackOverflow Exception during JUnit Test

Problem

The build of a Maven job in Jenkins fails due to a StackOverflowException or a OutOfMemoryException during a JUnit test.

Analysis

Most likely, there is a bug in your application, which leads to infinite recursion or an infinite allocation in resources. So first try to run your test in a different environment (for instance in eclipse, directly through Maven or as plain Java application).

However, sometimes, as in my case, the application works correctly and just requires more memory/stack size than is provided by the JVM during default settings. In this case, you will need to adjust the JVM settings in order to allow for more memory/stack size.

Solution

The JVM parameters, which allow to allocate more memory or stack size to a JVM are:

1. 

-Xss(x)m

where x is the size of the stack you would like to use. For instance: -Xss4m for a 4 MB stack size.

2.

-Xmx(x)m

where x is the size of the Java heap space (=memory) you would like to use. For instance: -Xmx1024m for a 1024 MB heap space.

Unfortunately, there are multiple places in which these parameters can be configured. Essentially, if the increased heap space requirement is in your application, you will need to adjust the parameters for the JUnit test runner in Maven:


<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-surefire-plugin</artifactId>
 <version>2.12.4</version>
 <configuration>
 <argLine>-Xss18m</argLine>
 </configuration>
 </plugin>

However, if the adjusted parameters are required for building your application, you might have to adjust them for the Maven Build Process.

This can be done by adding the parameters to MAVEN_OPTS either:

  • for your job: [Your Job] / Configure / Build / Advanced / MAVEN_OPTS
  • or for the Jenkins instance: Jenkins / Manage Jenkins / Configure System / Maven Project Configuration / Global MAVEN_OPTS

The last possible culprit might be the Jenkins server itself.

You can set the JVM parameters for Jenkins either by specifying them when:

  • starting Jenkins through java [your JVM parameters here] -jar jenkins.war or
  • by editing the jenkins.xml in your JENKINS_HOME folder.

Resources

Increasing Memory of junit Testcases

Stackoverflow – Jenkins build fails after running Cucumber tests on Java heap space exception

Increase heap size in java

Stackoverflow – How to give Jenkins more heap space when it´s started as a service under Windows?