Error-prone: Is plexus-compiler-javac-errorprone still required?

Created on 7 Mar 2019  路  4Comments  路  Source: google/error-prone

Is the plexus-compiler-javac-errorprone still required? Or outdated and to be removed?

I'm as asking specifically because it was removed from the doc, but the example still shows it...

plexus-compiler-javac-errorprone was last updated 4 years ago.

It would be good to have clarification about this, what it was and why it was initially needed, if it's still a problem, and how it's dealt with now. Ideally clarifying the situation for both Java 8 and/or Java 11.

@cushon ?

Most helpful comment

I can't speak for Google, but here are some facts (from memory, I hope I remember everything correctly):

It would be good to have clarification about this, what it was and why it was initially needed,

Java 8 introduced -Xplugin: but there was no possibility to hook into javac previously, so you had to replace the way you called JavaC to replace it with ErrorProne (initially replacing com.sun.tools.javac.Main, then providing a custom javax.tools.JavaCompiler).
Also, ErrorProne uses a patched version of JavaC, based on a post-8 pre-9 version of OpenJDK (see https://github.com/google/error-prone-javac). This is only needed for pre-9 JDKs though (and would actually fail with JDK 10+). plexus-compiler-javac-errorprone (and v0.0.x version of the net.ltgt.errorprone Gradle plugin) uses a custom classloader to give priority to the com.google.errorprone:javac over the system/bootstrap classpath.
See the bottom of https://errorprone.info/docs/installation which still describes this.

if it's still a problem,

Now that ErrorProne (since 2.1 or so) no longer supports Java 7, support has been added for -Xplugin: so it's easier to integrate it into your builds.

and how it's dealt with now.

The new approach using -Xplugin: requires you to prepend com.google.errorprone:javac to the bootstrap classpath (through -Xbootclasspath/p:) when using Java 8. This in turns requires forking a JVM (each time you need to call it when using Maven, or only once when using Gradle as it uses daemon processes).

Ideally clarifying the situation for both Java 8 and/or Java 11.

Java 8 can use -Xplugin: but requires com.google.errorprone:javac to be prepended to the bootstrap classpath through -Xbootclasspath/p:. Or it can use plexus-compiler-javac-errorprone which still works.
Java 11+ requires using the -Xplugin: approach, and doesn't need anything else (you can even exclude com.google.errorprone:javac from being brought in transitively by com.google.errorprone:error_prone_core; the net.ltgt.errorprone does this automatically for instance, and requires you to configure the com.google.errorprone:javac dependency explicitly, in a specific configuration dedicated to be prepended to the bootstrap classpath).

My take on this is that -Xplugin: is the preferred way to use ErrorProne nowadays (see discussion starting at https://github.com/google/error-prone/issues/535#issuecomment-414167065), but if you only want/need to support building with JDK 8 and/or can't afford forking a new JVM for each compilation, then you could stay with plexus-compiler-javac-errorprone.
I believe that plexus-compiler-javac-errorprone is no longer (actively) maintained and in case there are bugs in the custom classloader, I don't think they'll be fixed; so I would recommend migrating to -Xplugin: (and possibly JDK 11 with --release 8).

All 4 comments

@tbroyer

I can't speak for Google, but here are some facts (from memory, I hope I remember everything correctly):

It would be good to have clarification about this, what it was and why it was initially needed,

Java 8 introduced -Xplugin: but there was no possibility to hook into javac previously, so you had to replace the way you called JavaC to replace it with ErrorProne (initially replacing com.sun.tools.javac.Main, then providing a custom javax.tools.JavaCompiler).
Also, ErrorProne uses a patched version of JavaC, based on a post-8 pre-9 version of OpenJDK (see https://github.com/google/error-prone-javac). This is only needed for pre-9 JDKs though (and would actually fail with JDK 10+). plexus-compiler-javac-errorprone (and v0.0.x version of the net.ltgt.errorprone Gradle plugin) uses a custom classloader to give priority to the com.google.errorprone:javac over the system/bootstrap classpath.
See the bottom of https://errorprone.info/docs/installation which still describes this.

if it's still a problem,

Now that ErrorProne (since 2.1 or so) no longer supports Java 7, support has been added for -Xplugin: so it's easier to integrate it into your builds.

and how it's dealt with now.

The new approach using -Xplugin: requires you to prepend com.google.errorprone:javac to the bootstrap classpath (through -Xbootclasspath/p:) when using Java 8. This in turns requires forking a JVM (each time you need to call it when using Maven, or only once when using Gradle as it uses daemon processes).

Ideally clarifying the situation for both Java 8 and/or Java 11.

Java 8 can use -Xplugin: but requires com.google.errorprone:javac to be prepended to the bootstrap classpath through -Xbootclasspath/p:. Or it can use plexus-compiler-javac-errorprone which still works.
Java 11+ requires using the -Xplugin: approach, and doesn't need anything else (you can even exclude com.google.errorprone:javac from being brought in transitively by com.google.errorprone:error_prone_core; the net.ltgt.errorprone does this automatically for instance, and requires you to configure the com.google.errorprone:javac dependency explicitly, in a specific configuration dedicated to be prepended to the bootstrap classpath).

My take on this is that -Xplugin: is the preferred way to use ErrorProne nowadays (see discussion starting at https://github.com/google/error-prone/issues/535#issuecomment-414167065), but if you only want/need to support building with JDK 8 and/or can't afford forking a new JVM for each compilation, then you could stay with plexus-compiler-javac-errorprone.
I believe that plexus-compiler-javac-errorprone is no longer (actively) maintained and in case there are bugs in the custom classloader, I don't think they'll be fixed; so I would recommend migrating to -Xplugin: (and possibly JDK 11 with --release 8).

It's still referenced in the example for NullAway @ https://github.com/uber/NullAway/wiki/Configuration#maven

I spent all of 5 minutes attempting to get rid of it and keep NullAway on Java8 with no success.

@jonfreedman I'd advise starting from https://errorprone.info/docs/installation and then add NullAway:

  • add the NullAway dependency to the <annotationProcessorPaths> next to error_prone_core
  • add the ErrorProne parameters specific to NullAway to the <arg> containing the -Xplugin:ErrorProne:
    xml <arg>-Xplugin:ErrorProne -Xep:NullAway:ERROR -XepOpt:NullAway:AnnotatedPackages=com.uber</arg>

That's all (and then file an issue to NullAway so they update their wiki :wink:)

Was this page helpful?
0 / 5 - 0 ratings