RFR: JDK-8306819: Consider disabling the compiler's default active annotation processing [v2]
Alex B
duke at openjdk.org
Mon Sep 25 13:07:16 UTC 2023
On Wed, 13 Sep 2023 04:29:53 GMT, Joe Darcy <darcy at openjdk.org> wrote:
>> Change annotation processing to be opt-in rather than opt-out.
>
> Joe Darcy has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains five commits:
>
> - Merge branch 'master' into JDK-8306819
> - Updates for a clean test run.
> - Merge branch 'master' into JDK-8306819
> - Merge branch 'master' into JDK-8306819
> - JDK-8306819: Consider disabling the compiler's default active annotation processing
Oh there is now a PR for my (bug) report. That's nice to see (although I somehow didn't get the notification for it lol).
Anyway here some additional information from my perspective:
<details><summary>Backstory of this issue</summary>
So a while ago we updated a project to Java 17 and we somehow got this error when using ``records``:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile (default-compile) on project maven-module-xxx: Compilation failure
[ERROR] D:\REDACTED\src\main\java\xxx\Job.java: Internal compiler error: java.lang.Exception: javax.lang.model.element.UnknownElementException: Unknown element: "de.xxx.Parameters" at org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:172)
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile (default-compile) on project maven-module-xxx: Compilation failure
D:\REDACTED\src\main\java\xxx\Job.java: Internal compiler error: java.lang.Exception: javax.lang.model.element.UnknownElementException: Unknown element: "de.xxx.Parameters" at org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:172)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:568)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
at org.codehaus.classworlds.Launcher.main (Launcher.java:47)
Caused by: org.apache.maven.plugin.compiler.CompilationFailureException: Compilation failure
D:\REDACTED\src\main\java\xxx\Job.java: Internal compiler error: java.lang.Exception: javax.lang.model.element.UnknownElementException: Unknown element: "de.xxx.Parameters" at org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:172)
at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute (AbstractCompilerMojo.java:1310)
at org.apache.maven.plugin.compiler.CompilerMojo.execute (CompilerMojo.java:198)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:568)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
at org.codehaus.classworlds.Launcher.main (Launcher.java:47)
The error was kind of confusing and the only thing hinting to a annotation processor was the ``handleProcessor`` in the stacktrace.
As it later turned out this was caused by [``org.hibernate.validator:hibernate-validator-annotation-processor``](https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor) (→ https://hibernate.atlassian.net/browse/HV-1863) which was somehow on the classpath.
So there was an annotation processor that was kind of magically executed with no log output so there was 0 chance of finding out that it was even executed, so that's one of the reasons why I created this issue.
</details>
<details><summary>About your discussion of AP pollutions in classpath</summary>
> > This aims to avoid unintentional AP pollutions in classpath, like if one AP is present in a dependency and thus your classpath but you don't want it to run.
> In practice is this a thing that happens? Most processors I've seen (like Lombok or record builder for example) are typically added as provided or optional scope dependencies. (and so cannot be transitively pulled)
> Is it really such a common thing that people accidentally include unrelated annotation processor dependencies transitively via maven?
I can show a very simple example:
[Log4J2s PluginProcessor](https://github.com/apache/logging-log4j2/blob/c7f0f15dd6d37fc8f23689b975163ec2df80a9ec/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessor.java) (registered via Java Service Loading [here](https://github.com/apache/logging-log4j2/blob/c7f0f15dd6d37fc8f23689b975163ec2df80a9ec/log4j-core/src/main/resources/META-INF/services/javax.annotation.processing.Processor)) is likely included and executed in a lot of projects that don't require and know about it.
> Yes, in terms of good build hygiene, I recommend separately specifying the path for annotation processors and the path for general compiler dependencies, even if they happen to be the same path.
There is 2 problems with this statement:
1. The average developer that compiles with Maven oder Gradle doesn't know about this "good practice" and there is nothing hinting to it. Update: This is (partially) addressed with [JDK-8310061](https://bugs.openjdk.org/browse/JDK-8310061)
2. Even if this is the case and you split it into to separate "paths" there is no way in preventing e.g. Log4J2s PluginProcessor getting into the "general compiler dependencies" because it's inside log4j-core.jar (without this jar logging no longer works)
</details>
I again want to say that my intention was not to remove Annotation processing but simply considering disabling it by default due to the security concerns mentioned in the issue.
Also thank you for your efforts and the progress already done with [JDK-8310061](https://bugs.openjdk.org/browse/JDK-8310061) I think the new message is already a good step into the right direction :)
-------------
PR Comment: https://git.openjdk.org/jdk/pull/14432#issuecomment-1733668825
More information about the compiler-dev
mailing list