NELKINDA SOFTWARE CRAFT

Running Cucumber with Maven on Java 9

Running Cucumber with Maven on Java 9 is interesting. You can use new features like Java modules or the new HTTP client. But the setup is not that straight-forward. TL;DR: Use Maven 3.5.0, Cucumber 1.2.5, and add the necessary --add-opens command line options.

Author:
Christian Hujer, Software Crafter and CEO / CTO of Nelkinda Software Craft Private Limited
First Published:
by NNelkinda Software Craft Private Limited
Last Modified:
by Christian Hujer
Approximate reading time:

1 Why using Java 9 now?

Java 9 has a lot of interesting new features. The biggest change is Jigsaw, which helps with decoupling in larger code bases. Another highlight is the new HTTP client. A full list of new features is beyond the scope of this blog article.

Oracle will release Java 9 in 2017. When starting a new project, I recommend to at least try starting with Java 9. In the beginning, do not use many of its new features so that you could go back to Java 8 any time. There might be incompatibilities between third party libraries and Java 9. Dealing with these incompatibilities might be too difficult. The fewer features of Java 9 you use, the easier you can switch back to Java 8.

After some time you will know whether Java 9 already works for you. If Java 9 works for you, then it's time to cash-in on the new features and start using them.

2 The Problems

Figure 2-1: Failed cucumber run due to missing Java 9 setup

When trying to use Cucumber with Java 9, there are a couple of obstacles:

3 The Steps

3.1 Install JDK 1.9

This step is system-specific. I'll give the instructions for Ubuntu. In case you haven't setup the repositories for Java, you might first need to add the Java repositories. You can do so with sudo add-apt-repository ppa:webupd8team/java ; sudo apt-get update. On Ubuntu, run sudo apt-get install oracle-java9-installer. In case you do not want to make JDK 9 the default, instead run sudo apt-get install --no-install-recommends oracle-java9-installer.

A more detailed description can be found at [Java9Ubuntu].

3.2 Install Maven 3.5.0 (or newer)

The first element to use Java 9 is to make Maven actually use Java 9. Earlier versions of Maven might not start on Java 9.

christian.hujer@nelkinda-Blade-Stealth-1:~/...$ echo $JAVA_HOME
/usr/lib/jvm/java-9-oracle/
christian.hujer@nelkinda-Blade-Stealth-1:~/...$ mvn --version
Apache Maven 3.3.9
Maven home: /usr/share/maven
Java version: 9-ea, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-9-oracle
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.10.0-22-generic", arch: "amd64", family: "unix"
christian.hujer@nelkinda-Blade-Stealth-1:~/...$ mvn clean install
[ERROR] Error executing Maven.
[ERROR] java.lang.IllegalStateException: Unable to load cache item
[ERROR] Caused by: Unable to load cache item
[ERROR] Caused by: Could not initialize class com.google.inject.internal.cglib.core.$ReflectUtils
Listing 3-1: Error message when trying to use Maven 3.3.9 with Java 9

The most convenient way to chose a Maven version is to use Maven Wrapper. The following command sequence will

You may have to change some paths to match your system setup.

export JAVA_HOME=/usr/lib/jvm/java-8-oracle/
mvn -N io.takari:maven:wrapper
export JAVA_HOME=/usr/lib/jvm/java-9-oracle/
./mvnw clean install
Listing 3-2: Using Maven Wrapper to install and use the latest version of Maven on JDK 9

A more detailed description can be found at [MavenWrapper]

3.3 pom.xml: Use Java 9 for Compilation

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.9</source>
                    <target>1.9</target>
                </configuration>
            </plugin>
Listing 3-3: pom.xml configuration to compile with Java 9.

3.4 pom.xml: Configure the VM Options for the Surefire Plugin

Cucumber will initially cause errors when running on Java 9. A few modules need to be opened for access. This is because some libraries are breaching the module rules from Jigsaw. We can expect that third parties will update their libraries and remove those breaches. So, these problems will eventually go away.

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <argLine>
                        -ea
                        --add-opens java.base/java.util=ALL-UNNAMED
                        --add-opens java.base/java.lang.reflect=ALL-UNNAMED
                        --add-opens java.base/java.text=ALL-UNNAMED
                        --add-opens java.desktop/java.awt.font=ALL-UNNAMED
                    </argLine>
                </configuration>
            </plugin>
Listing 3-4: pom.xml Configuration for Surefire to run Cucumber on Java 9.

For more information on the --add-opens command line option, refer to [JDK9java]. For more information on the Maven Surefire Plugin, refer to [Surefire]