Eclipse Compiler Fails On Java 9

CodeFX Weekly #57 — 23rd of February 2018

Nicolai Parlog
nipafx news
Published in
4 min readFeb 27, 2018

--

Hi everyone,

not much going one this week. With all the technical content for the book drafted (and currently out for review), I focused on finishing the many, many, so many diagrams. I even added one of them to my post about java -Xlog:

I also found some time to do all the small things that I left lying around in recent weeks. I found out there are a quite a few ways to leave notes for myself:

  • Workflowy
  • unread emails
  • liked Tweets
  • pieces of paper

Hell, since January I didn’t even bother filing interesting material away, I just opened tabs and left them there — even on mobile for Christ’s sake! I went through all of these and consolidated them into my notes or Pocket account. During the next weeks I plan to go through them as well as the old ones to reacquaint myself with the ideas and plans that I ignored for about six months now.

I also finally did my taxes for 2016. Next up: 2017!

I got one technical thing for you, though, and its about the Eclipse compiler on Java 9.

I send this newsletter out every Friday. Yes, as an actual email. Subscribe!

Tycho / JDT on Java 9

One of the projects I migrated to Java 9 is rather large with about 1.5 million lines of code. Because the Eclipse compiler, part of the Eclipse Java Development Tools (JDT), has considerably better performance than javac, we’ve configured our build to use it instead. After getting everything to work on javac 9, I tried to switch the Java 9 build back to JDT, but contrary to how I understood the documentation (particularly #457413), that didn’t go well…

Compiling with Eclipse

In case you’ve never done it, using JDT for your Maven build is quite easy:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<compilerId>jdt</compilerId>
</configuration>
<dependencies>
<dependency>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-jdt</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.tycho</groupId>
<artifactId>org.eclipse.jdt.core</artifactId>
<version>3.14.0.v20171206-0802</version>
</dependency>
</dependencies>
</plugin>

And there you go. Give it a try and you might be surprised how much that speeds things up.

One caveat, though: JDT and javac don’t always agree on each edge case, particularly if generics and type inference are involved — one might give you a compile error, where the other doesn’t. If you decide to rely on JDT, I recommend to set up a nightly build with javac that makes sure you’re not writing code that only compiles in one compiler. We actually and inadvertently were in that situation prior to making the update to javac 9, so I had to put in a few hours to move from JDT to javac 8.

Last note: You can use JDT in IntelliJ, but I’m too lazy to look it up. 😊

Now let’s get to the problem — finally.

Unresolved Java EE Modules

In Java 9, Java EE modules are not resolved by default and they will be removed in Java 11. The best way to handle this is to use a third-party dependency, but JDT trips over its own feet when I do that.

To distill the problem, I created a provisional module for java9.wtf (but it’s not on the site yet). The demo project uses a JAXB class, javax.xml.bind.JAXBContext, which can be found in the Jave EE module java.xml.bind and in the artifact javax.xml.bind:jaxb-api. Adding the artifact as a dependency leads to the following error when the build is executed on Java 9:

[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-compiler-plugin:3.7.0:
compile (default-compile) on project tycho-jdt:
Compilation failure
[ERROR] .../java-9-wtf/tycho-jdt/src/main/java/wtf/java9/tycho_jdt/ImportJAXBType.java:
[ERROR] package wtf.java9.tycho_jdt;
[ERROR] ^
[ERROR] Internal compiler error: java.lang.NullPointerException
at BinaryModuleBinding.create(BinaryModuleBinding.java:64)
[ERROR] java.lang.NullPointerException
[ERROR] at BinaryModuleBinding.create
[ERROR] at LookupEnvironment.getModuleFromAnswer
[ERROR] at LookupEnvironment.askForTypeFromModules
[ERROR] at LookupEnvironment.askForType
[ERROR] at UnresolvedReferenceBinding.resolve
[ERROR] at BinaryTypeBinding.resolveType
[ERROR] at BinaryTypeBinding.resolveTypesFor
[ERROR] at BinaryTypeBinding.getExactMethod
[ERROR] at Scope.findExactMethod
[ERROR] at Scope.getMethod
[ERROR] at MessageSend.findMethodBinding
[ERROR] at MessageSend.resolveType
[ERROR] at LocalDeclaration.resolve
[ERROR] at AbstractMethodDeclaration.resolveStatements
[ERROR] at MethodDeclaration.resolveStatements
[ERROR] at AbstractMethodDeclaration.resolve
[ERROR] at TypeDeclaration.resolve
[ERROR] at TypeDeclaration.resolve
[ERROR] at CompilationUnitDeclaration.resolve
[ERROR] at Compiler.process
[ERROR] at ProcessTaskManager.run
[ERROR] at Thread.run

Research leads to the issues #525522 and #526206, but they are supposedly fixed, so this shouldn’t happen, should it? To find out, I opened a new issue — let’s see what comes of it.

I was also rather surprised to find out that compilation only fails if Maven is run on Java 9. If the build runs on 8, JDT will happily create the Java 9 bytecode I want.

Command Line Flags

Just for fun, I tried explicitly adding java.xml.bind with --add-modules, but unfortunately the JDT compiler seems to be unable to process Java 9's new command line options, so that removing the dependency and adding --add-modules=java.xml.bind doesn't work either:

[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-compiler-plugin:3.7.0:
compile (default-compile) on project tycho-jdt:
Fatal error compiling:
Unrecognized option : --add-modules=java.xml.bind
-> [Help 1]

Weird.

Shots

Ooops, slim pickings.

so long … Nicolai

PS: Don’t forget to subscribe or recommend! :)

--

--

Nicolai Parlog
nipafx news

Nicolai is a #Java enthusiast with a passion for learning and sharing — in posts & books; in videos & streams; at conferences & in courses. https://nipafx.dev