Java 9 — Part 2: Compiling and Running Che

Florent Benoit
Eclipse Che Blog
Published in
5 min readDec 13, 2017
Photo by Chester Alvarez

In the first post, I described what needed to be done to make Che workspaces run Java 9 (which means getting the Che server to run Java 9 too).

Now I want to explain what had to be done so contributors to the Che project could compile and run with Java 9.

The latest Eclipse Che stable release (v5) was designed and built on top of Java 8. So when a new version of the JDK, Java 9, was released we had to ensure that Eclipse Che could be built and run on top of Java 9 as well.

Eclipse Che uses many dependencies and in order to be compliant with Java 9 all dependencies need to be compliant as well. So making Eclipse Che compliant with Java 9 required a lot of updates.

Compiling Eclipse Che with Java 9

Maven and Java 9

We had numerous failures when we first tried to build Eclipse Che with Java 9. Eclipse Che uses maven to build the project but when trying to build it most of the existing maven plugins were not ready to use Java 9 so we had to wait for those plugins to be updated.

Plus, as an Eclipse project when we update a component we have to file a CQ (Contribution Questionnaire) for each one. With 20+ plugins to update it meant getting approval for each one.

After those plugins were updated, we still had issues around some Java components. Most of the failures were linked to the fact that in Java 9 the system class loader is no longer a URLClassLoader and many components assumed that and performed a cast to URLClassLoader …which would fail.

JDK Reflection / Internal Classes

The easiest problem to solve was with JDK reflection. We had some methods that performed internal introspection of JDK classes but these methods were not used anymore so instead of trying to fix them we simply removed them!

JDK and tools.jar

Until Java 9, when you required classes provided by tools.jar you had to add a system dependency in your pom.xml by using the path to the tools.jar file:

<dependency>
<groupId>sun.jdt</groupId>
<artifactId>tools</artifactId>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath
</dependency>

With Java 9, tools.jar is no longer there (modularity!) and classes are available with the JVM so we instead added this dependency in a maven profile that is only enabled if the Java version is lower than Java 9.

<profile>
<id>java8-tools</id>
<activation>
<jdk>(,1.9)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>sun.jdt</groupId>
<artifactId>tools</artifactId>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
</profile>

Compiling?

At that point when we tried to compile Eclipse Che by disabling all unit tests and checks it almost worked. All the modules were marked “build success” until the last module that tried to build GWT app which…failed…oh no!

GWT and Java9

This meant we had to upgrade to GWT 2.8.2 to get Java 9 compliance. Note that you still have to use Java 8 language features, but GWT 2.8.2 allows you to use a Java 9 runtime.

After all these compiling dependencies updates it was finally possible to build Eclipse Che with Java9!

But we really wanted to have unit tests working as well! ;-)

Che and Unit Tests with Java9

We were using Mockito 1.x in Eclipse Che but to get Java 9 support we needed Mockito 2.10. This meant converting all existing tests to Mockito 2.x. This was quite a bit of work because some of classes which were deprecated in 1.x were removed in 2.x while other methods (like any()) handle null differently.

Last but not least, we were using a maven artifact named mockito-all and this artifact is no longer supported on 2.x so we had to remove it everywhere it was used (many, many places…).

Now tests could be launched but some failures were still reported on EclipseLink and Apache Lucene — the versions that we were using of those were not compliant with Java 9.

After upgrading EclipseLink to 2.7.0, and Lucene to 7.0.1 the issues were solved. For Lucene we’d previously used version 5.2.1 so it was a big update to move to 7.0.1.

GWT Mockito
As before the last unit tests that needed fixing were related to the GWT Mockito tests. Specifically, there was an issue with classloaders

Caused by: java.lang.IllegalAccessError: class jdk.internal.reflect.ConstructorAccessorImpl loaded by com/google/gwtmockito/GwtMockitoTestRunner$GwtMockitoClassLoader cannot access jdk/internal/reflect superclass jdk.internal.reflect.MagicAccessorImpl
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1007)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:868)
at javassist.Loader.findClass(Loader.java:377)
at com.google.gwtmockito.GwtMockitoTestRunner$GwtMockitoClassLoader.findClass(GwtMockitoTestRunner.java:421)

A pull request was merged but we have not yet released.

With all the updates and patches we finally had Eclipse Che compiling with all unit tests when using Java 9 (my tests were with Oracle JDK on macOS)

java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)

Running

OK great — Eclipse Che was compiling, tests were working, but could we launch Che with Java 9?

Quick answer…no :-(

Eclipse Che uses APIs provided in the javax namespace (javax.activation and javax.xml.bind). With Java 9, all packages that are not in thejava namespace are not exposed by default.

So we had to enable extra modules when using Java 9 or higher:

JAVA_OPTS="$JAVA_OPTS --add-modules java.activation --add-modules java.xml.bind"

You may notice that the name of the modules are just java.xxx not javax.xxx — that’s not a typo, java.activation provides the javax.activation package at runtime.

With that flag Eclipse Che was finally able to start!

But there was a big stack trace in Tomcat saying that the logging.properties file was not found. This file was found in java.home/lib folder previously but in Java 9 it’s moved to the conf folder.

So we needed a Tomcat version change that included that fix.

By using Tomcat 8.5.23 we could move forward.

Finally!

Eclipse Che is Now Compiling and Running with Java 9!

As always please let us know your thoughts by connecting with us on twitter @eclipse_che or by filing issues in the Che GitHub repo at https://github.com/eclipse/che

--

--

Florent Benoit
Eclipse Che Blog

Working on Eclipse Che and Red Hat Code Ready Workspaces Twitter: @florentbenoit