-
Notifications
You must be signed in to change notification settings - Fork 5.8k
JDK-8306819: Consider disabling the compiler's default active annotation processing #14432
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back darcy! A progress list of the required criteria for merging this PR into |
@jddarcy This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
Keep alive. |
/csr needed |
@jddarcy has indicated that a compatibility and specification (CSR) request is needed for this pull request. @jddarcy please create a CSR request for issue JDK-8306819 with the correct fix version. This pull request cannot be integrated until the CSR request is approved. |
With the preparatory work of 8310061: Note if implicit annotation processing is being used in JDK 21, please review this first cut at removing implicit annotation processing by default. In this first iteration, I left the javac note in the properties file. In a subsequent iteration, we may decided to keep the old policy or earlier source levels, etc. Depending on the final disposition of that point, the property key should be fully expunged. Once it is clearer what the eventual policy will be, I'll file the corresponding CSR. |
Annotation processing use is fundamental to newer frameworks like Quarkus, Micronaut and Spring framework is also adopting more use of annotation processing. This is because it enables frameworks and libraries to move some work from runtime to build time for reduced memory consumption and faster startup (replacing reflection, dynamic proxies etc). For myself I have annotation processors that:
Its also common to use annotation processing for mapping/adapting between types (e.g. MapStruct) I'd suggest the use of annotation processing is actually taking off in the last say 5 years as we especially look to deploy applications into cloud hosted environments where we pay money for the amount of CPU and Memory used. Annotation processing means that a LOT of libraries can move some or even most of their functionality to build time reducing the CPU required to initialise the library and the total memory consumption.
To me I see the exact opposite happening and it's driven by cloud adoption and the desire to move work from runtime to build time. |
This doesn't remove annotation processors, just disables them running by default with no input from the developer (I assume if they were simply in the compiler classpath, which could happen by accident). As mentioned, it can still be enabled by its flag, and it's likely build systems will set that flag for you if you have declared you use annotation processors for your build. I also disagree in the hardly used anymore part though, but I have no data. |
@rbygrave This patch isn't aimed to remove AP. 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. Such classpath separation have already been promoted by build tools like Gradle. After all, your build tool should be setting the |
Pretty sure he was only speaking against the statement that AP is an unused feature.
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) |
Yes, I understand that.
BUT it has NOT been promoted by Maven. In the bug report and in this PR I do not see any explicit recognition of how this change will impact the community that is using Maven and I am suggesting that this is a significant proportion of the community. For example, all the libraries that use annotation processing that document maven use could be impacted along the lines that their documentation will now be at least misleading (and sometimes incorrect). This change might indeed be a good long term change but it seems to be being made without any recognition or understanding of how impactful it will be. |
Mailing list message from Josiah Noel on compiler-dev: Is it really such a common thing that people accidentally include unrelated On Sun, Sep 10, 2023, 8:58 AM altrisi <duke at openjdk.org> wrote: -------------- next part -------------- |
If this is the new reality I can deal with it, but it would indeed be nice to know that the full gravity of this breaking change was acknowledged and taken into account when making this decision. (The initial proposal seems to make the assertion |
For whoever wondering about the impact of this breaking change, in JDK 21, the previous release and the previous LTS release, there's a new warning when the default active AP is used: #14499 https://bugs.openjdk.org/browse/JDK-8310061 |
To expand on and reiterate points already made by @liach , the goal here is only to change whether or not annotation processing is run implicitly in a case like
Accomplishing this is being broken up over (at least) two releases. In JDK 21, there were two related changes: JDK-8308245: Add -proc:full to describe current default annotation processing policy The
The message is a note rather than a waning to avoid tripping up people who run their builds with So, starting in JDK 21, if you want to get the old look-on-the-classpath behavior, it is sufficient to use |
In fact this is a thing that can cause problems. At present, annotation processor authors have to be cautious about including dependencies because commonly used libraries (such as Guava or Eclipse Collections) can conflict with other processors and/or the user's project with surprising (and sometimes subtle) results. I'm not sure about other build tools, but Maven does supply a means to include an annotation processor on a (relatively) isolated class path, i.e. separately from the application's class path. Though this is somewhat more cumbersome, it is certainly safer. |
Maven's
I do appreciate this, thanks. I've added myself to this mailing list. |
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. Likewise,, specifying --release $N is a good practice too. |
@@ -67,7 +67,7 @@ enum ImplicitType { | |||
|
|||
enum AnnoType { | |||
NONE, // no annotation processing | |||
SERVICE, // implicit annotation processing, via ServiceLoader | |||
// SERVICE, // implicit annotation processing, via ServiceLoader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why keeping this if it won't be used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why keeping this if it won't be used?
Sure; I can delete that before the changeset goes back.
/integrate |
Going to push as commit dc4bc4f.
Your commit was automatically rebased without conflicts. |
After much head scratching attempting to run the benchmarks for 8309130, I realised this change broke microbenchmarks:
|
Yes, JMH is using an annotation processor which now does not run anymore |
Hello @DanielThomas, thank you reporting and narrowing down the microbenchmark failures. This is now being addressed in https://bugs.openjdk.org/browse/JDK-8317802. |
Thanks for taking care of that issue @jaikiran . |
Maven is listed as a participant in the OpenJDK Quality Outreach effort (https://wiki.openjdk.org/display/quality/Quality+Outreach). The prior change of the javac emitting the note was explicitly raised on the quality discuss alias in July 2023 (https://mail.openjdk.org/pipermail/quality-discuss/2023-July/thread.html), ahead of the GA of JDK 21 in September. The change in this PR is likewise publicized this the October 2023 quality discuss message (https://mail.openjdk.org/pipermail/quality-discuss/2023-October/001129.html), months ahead of the expected GA of JDK 23 in March 2024. |
Just out of curiosity though, why didn't this (pretty sizable breaking change) get a JEP? The dynamic agents being disabled by default got one. |
The short answer is despite the Sturm und Drang of any discussions on Reddit, I don't agree with the assessment that this PR constitutes a "pretty sizable breaking change." To summarize: the capabilities of javac with respect to annotation processing are not changing in any way. The only aspect that is changing is what is the default policy if no explicit annotation processing configuration options are given. If a build environment is already using any of the javac options If a build environment does not have annotation processors on the class path, nothing changes. In JDK 21, javac prints a note -- not a warning for a reason I'll explain below -- to identify the situations where implicit annotation processing is being relied on. Now it is true that users might not see this note, but communication about the JDK 21 change was publicized on the quality-discuss list to help make sure interested parties were informed of the change. The reason the javac message is a note and not a warning is so that build environments running under Starting in JDK 21, a build environment or other javac invocation can be explicitly configured to request the old default policy by using Only in JDK 22 will the default policy actually be change to not look on the class path for annotation processors (unless |
Just to say, most of our libs build against 11, 17, 21 and EA/22. So for this reason our projects we can't trivially make use of |
Noted; thanks. |
Mailing list message from Ethan McCue on compiler-dev: I'm still unclear why this change is not going through the same general On Fri, Oct 20, 2023 at 9:45?PM Joe Darcy <darcy at openjdk.org> wrote: -------------- next part -------------- |
I have learned very late (about a month ago, and through JMH bug reports!) about this change. Looking at incoming bug reports, I can see this is looking to break significant amount of day-to-day things that rely on annotation processing to work by default. This includes existing JMH benchmarks, existing JCStress tests, and that is only OpenJDK tools so far! The proposed fix, "enable the annotation processing in build" seems to underestimate how many already existing build configs are there, and how widespread annotation processing is. So this is a harbinger of a widespread breakage when updating to JDK 22 and beyond. Yet, I see only tiny discussion about this in either here or in the CSR. It mostly just states that disabling annotation processors is the right thing to do to solve the externally reported problematic scenario. Normally, given the impact for changing a policy like this, I would have expected to see a JEP-sized discussion that weighs pros and cons for mitigation strategies, polls what problems real projects would run into, discusses to what extent we want to deal with currently supported JDK releases, etc. After more digging, the only (?) discussions I could find is Reddit post and this PR comments, which contain some valid questions, concerns, and scenarios the discussion for a change like this should consider. Yes, there was a warning message. This only highlights that hardly anyone reads the warning messages, especially buried somewhere in CI logs. This also does not capture the unfortunate reality that JDK 21 only starts to see major use, so most users did not even had the opportunity to see the warning message! In other words, warning messages are inefficient tools to bring quick attention to the issue that proposes to change the JDK behavior in a considerable way. IMO, JEPs are done for this reason, even for less impactful things. So I suggest we revert JDK-8306819 from JDK 22, and start over with the JEP targeting JDK 23 or even 24. I believe this would be a right thing to do at this point. |
Thanks for the input @shipilev ; I'm looking into options to amend this change later in JDK 22. |
Upon further reflection, we'll be deferring the policy change to disable implicit annotation processing from JDK 22 to JDK 23. The changeset to re-enable the old policy is out for review as #16988. In addition, we plan to backport support for the |
Think there is some reasoning shortcut taken there. That said it would be welcomed to take into account 3 points and not only postpone because the community kind of reject this shift - otherwise it will happen again in a few years:
So overall the original statements should be (in)validated and if there is really an issue using Side note: not great for users but acceptable if the will is really to disable the discovery, keeping the |
PS Support for -proc:full has been backported to Oracle's 17u, 11u, and 8u release trains (JDK-8321416, JDK-8321418, JDK-8321419) as well as the OpenJDK 17u and 11u release trains (JDK-8324670, JDK-8324804). The feature is on track to appear in the April 2024 set of releases. |
FYI, PR to implement the change in annotation processing default policy in JDK 23 out for review: see also discussion thread https://mail.openjdk.org/pipermail/jdk-dev/2024-May/009028.html |
Any hope it got reverted to the good old behavior since gain for the jdk is negligible and impact for end user is huge, plus it breaks annot proc cycle generation? |
…void warnings Until Java<21 the java compiler implicitely looked for and ran any annotation processor found on the classpath. Since Java21 the following warning is shown to inform users about upcoming change of default for this policy. [javac] Note: Annotation processing is enabled because one or more processors were found [javac] on the class path. A future release of javac may disable annotation processing [javac] unless at least one processor is specified by name (-processor), or a search [javac] path is specified (--processor-path, --processor-module-path), or annotation [javac] processing is enabled explicitly (-proc:only, -proc:full). [javac] Use -Xlint:-options to suppress this message. [javac] Use -proc:none to disable annotation processing. - Add a new ant property javac.proc to specify value to be used via <compilerarg line> for all our various javac invocations - For the value use -proc:none to explicitely disable annotation processing during compilation <compilearg line> was chosne as <compiler arg> value run into some cornercase issues in case value was empty. - Reasoning: - Upstream recommends to explcitely specify and control annotation processors instead of them being 'found' implicitely openjdk/jdk#14432 (comment) - Checking all jar libraries in mods/pmods (if they ship a META-INF/avax.annotation.processing.Processor) file found 1 single library shipping an annotation processor: log4j for its plugin system - However we do not use any shipped extra plugin - We have a few custom plugins ourself in src-test having @plugin - Annotation processing was running before for those as shown on compile output [javac] Note: Processing Log4j annotations [javac] Note: Annotations processed - However not running it seems to have no impact on the functionality - Tested via existing DalTest which assert's on output of content of testLogAppender configured via those plugins
Change annotation processing to be opt-in rather than opt-out.
Progress
Issues
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/14432/head:pull/14432
$ git checkout pull/14432
Update a local copy of the PR:
$ git checkout pull/14432
$ git pull https://git.openjdk.org/jdk.git pull/14432/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 14432
View PR using the GUI difftool:
$ git pr show -t 14432
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/14432.diff
Webrev
Link to Webrev Comment