Error-prone: Upgrade javac to JDK10 to support classfile version 54

Created on 12 Dec 2017  ·  19Comments  ·  Source: google/error-prone

When running error-prone with JDK 10-ea+35 we get the following compilation warnings:

[javac] warning: /modules/java.base/java/lang/Deprecated.class: major version 54 is newer than 53, the highest major version supported by this compiler.
[javac]   It is recommended that the compiler be upgraded.

for each class of the JDK. This is due to JDK-8188870: Bump classfile version number to 54.

With the new release cycle, the compiler will have to be updated every 6 months to support the new classfile version.

Maybe you could directly switch to JDK11 as classfile version 55 is coming soon, see JDK-8191913: Bump classfile version number to 55.

Most helpful comment

TL;DR Error Prone now supports JDK 10 and 11 when running as a javac plugin (-Xplugin). That's the approach I recommend to use Error Prone with 10 or 11 today.

We're going to keep maintaining error-prone-javac and try to closely track the six month release cadence, but we have some work to do to catch up to the new schedule.

Responding to some of the earlier discussion:

IIUC, the version of Javac used in Error Prone has been "cut"/forked from the JDK before they added JPMS

That used to be the case, but we caught up to the JDK 9 GA in e7323f3070aaf9317f332577b300986d21f046de. The main hurdle for JDK 10 is the issue @eaftan mentioned that it will likely mean dropping support for running on JDK 8 in error-prone-javac. Then anyone using JDK 8 for builds would be stuck on an old release, or we'd need to maintaing branches for JDK major versions, neither of which seem like great options.

My hope is that eventually we can stop using error-prone-javac and make-Xplugin the best and only way to run Error Prone, since it simplifies supporting the six-monthly releases.

I apologize for not knowing more of the intimate details, but as far as I know, Error Prone has relied on the Java 9 compiler for more than 3 years at this point (since cfbbe69 released in version 2.0.2) without requiring JDK 9 be used to compile projects using Error Prone.

Do most Error Prone users want to hop on that every-6-month JDK upgrade treadmill?

Why would this be required going forward when it hasn't been required while Error Prone has internally used JDK9?

It's true that we've been using the JDK 9 javac for a while, but effectively what we've been doing is trying to use a javac close to head. We still want to do that. It was simpler when the release cadences were longer, since there were about three years where "javac 9" and "javac at head" were more or less the same thing.

Version N of javac is a Java N program that expects to run on JDK N. There's some support for running in a bootstrap configuration on JDK N-1, but that's not really a supported production configuration. (e.g. modular compilations aren't well supported with javac 9 running on JDK 8.) So when we move to javac 10 we can probably still support JDK 9, but not JDK 8, which is problematic.

All 19 comments

We're trying to figure out our strategy for these short-term support Java releases. The problem is that shipping a new javac entails running the compiler on a newer JDK. Do most Error Prone users want to hop on that every-6-month JDK upgrade treadmill?

Thoughts?

Maybe we could have the choice? I don't know how feasible it would be to have javac9 as default compiler but allowing developers to override it with a newer javac10/11/etc. Maven dependency in their pom.xml.

FWIW we aren't planning on bumping our JVM version used for builds until
the LTS JDK 11 release. We're currently on JDK 8

On Tue, Feb 6, 2018, 13:34 Vincent Privat notifications@github.com wrote:

Maybe we could have the choice? I don't know how feasible it would be to
have javac9 as default compiler but allowing developers to override it with
a newer javac10/11/etc. Maven dependency in their pom.xml.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/google/error-prone/issues/860#issuecomment-363572158,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AALyUW3Jp0LuQtN1NKKdKZ7P-tB36_wtks5tSMVcgaJpZM4Q_uB1
.

Our company is on JDK 8 still, but we'll move to JDK 9 (or 10) as soon as is feasible. I'd rather not get into the situation where internal projects have to either be held back or do without Error Prone altogether.

I guess it comes down to how frequently the internal APIs against which EP integrates change in practice?

Having to upgrade the JDK would be a major obstacle for us. We would probably stop upgrading error-prone if this becomes a requirement. The reason is that many LTS Linux distribution will probably not ship these new JDK versions anytime soon, and we do not want to tell the developers and users of our project that they have to install a JDK manually.

I believe I'm hitting this same issue as well over at https://github.com/junit-team/junit5/pull/1266.

JUnit 5 is kind of uncommon in that it's always tested against the bleeding-edge version of the Java compiler and uses the -Werror flag, so whereas it currently works without problems with JDK 9, if I try to introduce error-prone for the part of the build that runs JDK 10, it just errors out with messages like:

warning: /8769/java/lang/Void.sig: major version 54 is newer than 53, the highest major version supported by this compiler.
  It is recommended that the compiler be upgraded.

If the error-prone team would be interested in a reproducible example, one can try the following commands:

  1. git clone https://github.com/jbduncan/junit5/tree/error-prone-investigation-4
  2. git checkout 3ff428cb6d045aa81f6812b767c05d7142ad78b9
  3. ./gradlew clean build

Fwiw, using Error Prone as a JavaC Plugin (-Xplugin:ErrorProne) works with JDK 10; but it then have other problems (see https://github.com/google/error-prone/issues/974)

I apologize for not knowing more of the intimate details, but as far as I know, Error Prone has relied on the Java 9 compiler for more than 3 years at this point (since https://github.com/google/error-prone/commit/cfbbe696a603448240f8ad4a59d388b4ce3edcf4 released in version 2.0.2) without requiring JDK 9 be used to compile projects using Error Prone.

Do most Error Prone users want to hop on that every-6-month JDK upgrade treadmill?

Why would this be required going forward when it hasn't been required while Error Prone has internally used JDK9? Could Error Prone not do the same for Java 10 and 11ea? It seems ideal, if possible, to allow users to use anything from JDK 8-11 in their projects now.


The reason is that many LTS Linux distribution will probably not ship these new JDK versions anytime soon

This is at least not true with Ubuntu: https://wiki.ubuntu.com/BionicBeaver/ReleaseNotes#OpenJDK

As of 18.04 release, OpenJDK 10 is the default JRE/JDK. Once OpenJDK 11 reaches GA in September 2018, it will become the default in 18.04.

I apologize for not knowing more of the intimate details, but as far as I know, Error Prone has relied on the Java 9 compiler for more than 3 years at this point (since cfbbe69 released in version 2.0.2) without requiring JDK 9 be used to compile projects using Error Prone.

Do most Error Prone users want to hop on that every-6-month JDK upgrade treadmill?

Why would this be required going forward when it hasn't been required while Error Prone has internally used JDK9? Could Error Prone not do the same for Java 10 and 11ea? It seems ideal, if possible, to allow users to use anything from JDK 8-11 in their projects now.

The version of Javac used in Error Prone has been patched to be compilable with JDK 8, so that it can run on Java 8. I guess this is no longer possible (and IIUC, the version of Javac used in Error Prone has been "cut"/forked from the JDK before they added JPMS, and not upgraded since then –besides backports of some bug fixes– also because of that).

In the mean time, using Error Prone as a Javac plugin seems to Just Work™ (disclaimer: I haven't tried using var, or JPMS).

For example, with Maven (in a profile triggered when using JDK 9+, because it won't work with JDK 8; use the plexus-compiler-javac-errorprone with JDK 8):

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.7.0</version>
  <configuration>
    <compilerArgs>
      <!-- XXX: all Error Prone args should come in a single argument -->
      <arg>-Xplugin:ErrorProne -XepDisableWarningsInGeneratedCode</arg>
    </compilerArgs>
    <annotationProcessorPaths>
      <path>
        <groupId>com.google.errorprone</groupId>
        <artifactId>error_prone_core</artifactId>
        <version>2.3.1</version>
      </path>
    </annotationProcessorPaths>
  </configuration>
</plugin>

(note that this will also put com.google.errorprone:javac in the processor path, while not needed, but annotationProcessorPaths doesn't allow exclusions; this shouldn't be a problem in practice though)

With Gradle, you can use the net.ltgt.errorprone-javacplugin plugin.

@eaftan Should the documentation be updated to recommend -Xplugin:ErrorProne with JDK9+? Should there be new releases/artifacts without the com.google.errorprone:javac dependency? (or marked as <optional>true</optional>, which is almost equivalent)

@tbroyer Thank you for the background. That clears that up. And thank you for the workaround (or possibly just The Solution).

It would be nice to have some official statement on the planned direction from the maintainers. Java 10 has been released for months and Java 11 (which likely will see more adoption more quickly due to the LTS designation) will be released in a couple months. I'm trying to figure out for projects on Java 10+ whether it is best to drop error-prone in the meantime or use it as a compiler plugin.

TL;DR Error Prone now supports JDK 10 and 11 when running as a javac plugin (-Xplugin). That's the approach I recommend to use Error Prone with 10 or 11 today.

We're going to keep maintaining error-prone-javac and try to closely track the six month release cadence, but we have some work to do to catch up to the new schedule.

Responding to some of the earlier discussion:

IIUC, the version of Javac used in Error Prone has been "cut"/forked from the JDK before they added JPMS

That used to be the case, but we caught up to the JDK 9 GA in e7323f3070aaf9317f332577b300986d21f046de. The main hurdle for JDK 10 is the issue @eaftan mentioned that it will likely mean dropping support for running on JDK 8 in error-prone-javac. Then anyone using JDK 8 for builds would be stuck on an old release, or we'd need to maintaing branches for JDK major versions, neither of which seem like great options.

My hope is that eventually we can stop using error-prone-javac and make-Xplugin the best and only way to run Error Prone, since it simplifies supporting the six-monthly releases.

I apologize for not knowing more of the intimate details, but as far as I know, Error Prone has relied on the Java 9 compiler for more than 3 years at this point (since cfbbe69 released in version 2.0.2) without requiring JDK 9 be used to compile projects using Error Prone.

Do most Error Prone users want to hop on that every-6-month JDK upgrade treadmill?

Why would this be required going forward when it hasn't been required while Error Prone has internally used JDK9?

It's true that we've been using the JDK 9 javac for a while, but effectively what we've been doing is trying to use a javac close to head. We still want to do that. It was simpler when the release cadences were longer, since there were about three years where "javac 9" and "javac at head" were more or less the same thing.

Version N of javac is a Java N program that expects to run on JDK N. There's some support for running in a bootstrap configuration on JDK N-1, but that's not really a supported production configuration. (e.g. modular compilations aren't well supported with javac 9 running on JDK 8.) So when we move to javac 10 we can probably still support JDK 9, but not JDK 8, which is problematic.

@cushon That's great news! Current documentation states we need to add a lot of -J--add-exports options with Java 9 and error_prone_ant 2.3.1. Is it still needed with Java 11 and current head?

Those flags aren't needed. (I think I added them testing against a pre-release JDK 9, some of those errors were relaxed or downgraded to warnings.)

As far as I am concerned this issue is solved: with the same error_prone binary we're able to build JOSM on Java 8 to 11 👍
The Ant chapter must be updated in the documentation to explain the correct syntax (it is not easy to guess if @tbroyer does not help you 🥇).

BTW, Gradle and Maven sections would need to be updated too (Maven using annotationProcessorPaths, Gradle using the net.ltgt.errorprone-javacplugin).

Great, thanks for verifying!

The work to update error-prone-javac will still happen, but I can track that somewhere else.

I'll leave this open until the docs are fixed. PRs for ant and gradle especially would be very welcome :)

I haven't found anyone using this approach with maven before. I gave a stab and it looks to work except I can't pass arguments like I could before. If someone doesn't mind having a look, would be appreciated https://github.com/openzipkin/brave/pull/761

I updated the ant and maven examples in 3f2ca43e53266e84e17e4fb3f34888be5cb29293 and 82b319ca63a384f1149cc70ec3b4002df1ce37bd, and also pushed an updated to the installation docs: http://errorprone.info/docs/installation

Was this page helpful?
0 / 5 - 0 ratings

Related issues

michaelhixson picture michaelhixson  ·  6Comments

tbroyer picture tbroyer  ·  6Comments

cushon picture cushon  ·  7Comments

JakeWharton picture JakeWharton  ·  7Comments

sergeykad picture sergeykad  ·  3Comments