-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Replace javax.annotation.Generated with custom gRPC annotation #9179
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
Comments
FYI, I just tried upgrading a project from Spring Boot 2.7.4 to 3.0.0-M5. One of the first issues I run into is:
Spring Boot 3 (Spring Framework 6) is moving to Jakarta EE 9 APIs (jakarta.) instead of EE 8 (javax.). Depending on |
Would it be possible to have an option to skip using javax.annotation as described by #9153? |
Our gRPC users in OpenLiberty are affected by this too when using EE9/EE10. The recommended solution is not to bundle an extra compile time [ADDED gh] dependency (why would users want to use Tomcat for this when they are used to OpenLiberty) but to use https://openliberty.io/blog/2021/03/17/eclipse-transformer.html (I would have added this to #9153 but it is locked.) |
IMO, using eclipse-transformer is a workaround. gRPC should support EE9/EE10 too. |
Nobody needs to bundle an extra dependency. annotations-api is a compile-only dependency.
Nobody is depending on Tomcat. It is the annotations-api, which has no actual logic inside. |
I was aware of the retention policy of the annotation, I was referring to #9153 where you say "Our README recommends a compile-time dependency on org.apache.tomcat:annotations-api:6.0.53", by users I meant developers who would need something like the above reference in their build, apologies for my loose language causing any loss of meaning. |
A workaroud for Gradle, add it to implementation 'javax.annotation:javax.annotation-api:1.3.2' |
Hello @ejona86 Is there any news on this issue? With the upgrade to Spring Boot 3, this is something blocking and will affect a lot of projects. It would be nice if this annotation could be configurable or even to be able to skip this annotation. Thank you very much |
I don't really see any new problem here. "Add the dependency like everyone else." You simply were able to side-step the dependency before. I do not recommend bundling; a project that compiles generated code is the one that should have the compile-only dependency. Nothing is broken. Everyone can build. Nobody is blocked. Nothing has changed in my original issue description: before we make any change we need to understand what tools are able to consume. Anyone is free to audit parts of the tooling ecosystem and reported their findings. |
As an application developer, I am developing a JavaEE 9 application and using gRPC. I used this maven project
It is not a solution to use JEE 8 to build this library because it will not be compatible to my JEE9 application. That's why I made this comment |
Compatible? If you add the snippet from the README:
What error do you get? My understanding is that should work without issue. |
I don't understand why I need to add an artifact from 2017, that was renamed, to get my java-grpc application working. Furthermore when javax no longer exists. If you don't have inconvenience, we can contribute to solve this issue. |
It appears ErrorProne accepts any annotation, as long as the name is "Generated": @oburgosm, we'd be happy for you to contribute. But that contribution would need to at least start with investigating what annotations the tooling ecosystem would accept, as mentioned when this issue was opened. |
I use the following workaround to not require to include the useless My project is based on Spring Boot 3. The code generation runs during the For all Maven users, simply add this to your plugins and you are good to go.
If you want to use the Tomcat annotation instead, adapt the hth |
Please ensure that this is not a SOURCE level annotation so that Jacoco can detect it. |
Lombok is an example of a widely used library in java. In the latest version 1.18.30 the user can configure which Generated annotation should be added, or if it should not be added at all. The default behavior is no Generated annotation is added. Key : lombok.addJakartaGeneratedAnnotation Generate @jakarta.annotation.Generated on all generated code (default: false). Examples: Key : lombok.addJavaxGeneratedAnnotation Generate @javax.annotation.Generated on all generated code (default: follow lombok.addGeneratedAnnotation). Examples: @ejona86 as the developer could you possible consider to listen to the request of the users of the library that you are developing and make the Generated annotation configurable similar to Lombok? |
I encountered the same problem, hoping for a quicker update. |
I just don't to be locked to a dependency from 2018 just to compile code. If it is just a compile-time dependency, why not switch to jakarta, where the package has been relocated to? For now I guess I'll go with the code replacement hack 😢 |
The Gradle workaround is great for Gradle users but for Maven users, this kind of manipulation will be much more awkward (guess they'll have to either use org.codehaus.mojo/exec-maven-plugin to break out to a shell script that is OS dependent, or make use of the gmavenplus plugin to inline a groovy script to do the same thing). This kind of thing could be implemented by plugin maintainers such as myself but I am really against having to keep protobuf-plugin specific logic in generic Maven plugins that are built to support everything in a standard way. |
Just looked at the code, and I think I've answered my own question! grpc-java/compiler/src/java_plugin/cpp/java_plugin.cpp Lines 91 to 97 in 454f1c5
If my understanding of this is correct, people using gRPC directly should be able to just do this just to avoid generating the annotation at all:
Likewise it looks like users of my Maven plugin would do this like so: <plugin>
<groupId>io.github.ascopes</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<configuration>
<binaryMavenPlugins>
<binaryMavenPlugin>
<groupId>io.grpc</groupId>
<artifactId>protoc-gen-grpc-java</artifactId>
<version>${grpc.version}</version>
<options>@generated=omit</options>
</binaryMavenPlugin>
</binaryMavenPlugins>
<protocVersion>${protobuf-java.version}</protocVersion>
</configuration>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin> Admittedly, this then means tools like JaCoCo will flag this code for coverage unless you are able to exclude the output package via configuration... not fantastic but a workaround nonetheless. |
Make sure you include both command line flags so that it works for all
versions of grpc
…On Mon, May 12, 2025, 1:34 AM Ashley ***@***.***> wrote:
*ascopes* left a comment (grpc/grpc-java#9179)
<#9179 (comment)>
Just looked at the code, and I think I've answered my own question!
https://github.com/grpc/grpc-java/blob/454f1c5c6acc46e3d93ddf434a4e77943f5f52ec/compiler/src/java_plugin/cpp/java_plugin.cpp#L91
If my understanding of this is correct, people using gRPC directly should
be able to just do this just to avoid generating the annotation at all:
protoc --plugin=protoc-gen-grpc-java=/path/to/protoc-gen-grpc-java --grpc-java_out=target/generated-sources/grpc ***@***.***=omit ...
Likewise it looks like users of my Maven plugin would do this like so:
<plugin>
<groupId>io.github.ascopes</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<configuration>
<binaryMavenPlugins>
<binaryMavenPlugin>
<groupId>io.grpc</groupId>
<artifactId>protoc-gen-grpc-java</artifactId>
<version>${grpc.version}</version>
***@***.***=omit</options>
</binaryMavenPlugin>
</binaryMavenPlugins>
<protocVersion>${protobuf-java.version}</protocVersion>
</configuration>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
Admittedly, this then means tools like JaCoCo will flag this code for
coverage unless you are able to exclude the output package via
configuration... not fantastic but a workaround nonetheless.
—
Reply to this email directly, view it on GitHub
<#9179 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACECGJGM77HZN3DRIWWDYST26AXHFAVCNFSM6AAAAABZQ7C7LSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQNZQHA4TKMJYHE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
same problem, I use Java 21, expact the code will generate with @javax.annotation.Generated annotation, expected @jakarta.annotation.Generated, |
https://github.com/floverfelt/find-and-replace-maven-plugin <plugin>
<groupId>io.github.floverfelt</groupId>
<artifactId>find-and-replace-maven-plugin</artifactId>
<version>1.2.0</version>
<executions>
<execution>
<id>exec</id>
<phase>process-sources</phase>
<goals>
<goal>find-and-replace</goal>
</goals>
<configuration>
<replacementType>file-contents</replacementType>
<baseDir>target/generated-sources/protobuf/</baseDir>
<findRegex>javax</findRegex>
<replaceValue>jakarta</replaceValue>
<recursive>true</recursive>
<fileMask>.java</fileMask>
</configuration>
</execution>
</executions>
</plugin> |
Bumping this PR |
Was going to voice support in #11215 but it's locked? |
Hopefully we can get it (or something similar) actioned - there is clearly a widespread desire within the community - fingers crossed. |
maybe open another PR? |
I have recently been using Java 21 to write a new server program, and this issue is really bothering me a lot |
Re-opened another PR - please get around it. |
I am not a maintainer of this project, but I did encounter issues when using it. I hope someone who is a maintainer can merge this PR. |
I know - I'm just looking for support to be voiced on the PR as there is clearly a desire for this functionality. |
@ejona86 have you done professional java development? Are you aware of the evergreen refrain from managers - "how does code coverage look?" If you have, you know this thread will literally stay alive until the new annotations are added, if you haven't please understand that literally most people who encounter this at work will literally just think you are wrong about this (and stubborn) |
@alexanderankin, what would be broken with code coverage? Can you share what tool you are using and any necessary configuration for observing annotations? The main problem with your comment and others is you are asserting a solution without explaining your problem. I updated #9179 (comment) to mention Jacoco. Although I don't know how to actually enable the filtering. I see jacoco added the annotation support in 2019, but it doesn't look like tooling like Gradle added support for the feature. While I couldn't test it, it seems Jacoco should be fine, as the pre-existing |
It is possibly worth noting that compiling without the annotations on the classpath when a dependency uses javax.annotations can cause -Xlint in javac to not play nicely when the retention is not SOURCE, as it will often flag missing annotations during the builds. This can limit the ability for users to enable more restrictive linting on their projects or to use -Werror with -Xlint to enforce higher code standards. Generally this will manifest in noise such as the following whenever linters or annotation processors try to traverse this kind of thing.
|
@ascopes, javax.annotation.Generated has retention SOURCE. If someone is using the other annotations, then they need a stronger dependency because of their usages, not gRPC. I would agree that tooling is poor around things like this, but the problem comes up pretty frequently in ordinary development. (Bazel is the only build tool that seems to have gotten this right with its hjars.) |
@ejona86 The change that we are advocating for is straightforward, simple, and does not add any additional dependencies to gRPC itself. However, it reduces the friction for those who rely upon gRPC in contemporary Java development environments. This issue has been open for multiple years without progress nor resolution. As an interim measure could we please look to provide the community with what they've been requesting and perhaps re-visit it when a better solution is available? Please stop letting perfect be the enemy of good enough. |
This is a good example of whats wrong with the whole ecosystem. Its little things like this that lead these stacks down a slow road to irrelevance. Even spring has moved on from javax. |
I don't think its worthwhile to try to investigate from the perspective of enumerating tools, that could explode in terms of complexity. the solution that would be simplest to implement/test/verify, and the most popular, is simply to allow users of the program to generate code with |
After many years of issue 9179 being open, there's been nothing to show that we need the javax.annotations.Generated annotation. Most tools use file paths and a few check for annotations with "Generated" in the name. ErrorProne has a few that check for javax.annotations.Generated, but only UnnecessarilyFullyQualified looks like it'd be a problem and it is disabled by default. We're not getting any more information, no users have reported issues with `@generated=omit`, and the existing dependency is annoying users, so just drop it. Given we will still retain the GrpcGenerated annotation, it seems highly likely things are already okay. Even if there are problems they would probably be addressed by adding a io.grpc.stub.annotations.Generated annotation or small tweaks. In the short-term, (non-Bazel) users can use `@generated=javax`, but long-term we could consider removing the option assuming we've resolved any outstanding issues. We will want to update the examples and the README to remove the org.apache.tomcat:annotations-api dependency after the next release. Fixes grpc#9179
I just sent out #12080 to default to |
Better than nothing .-. |
Since Java 9 dropped
javax.annotation.Generated
users have had to explicitly depend on a dep (typically Tomcat's annotation API) to get the annotation. It'd be nice not to need that the extra dep.But even more important is that the removal of Generated from Java 9 upset the ecosystem as a whole and fragmented it so badly that I believe many tools are no longer assuming they can predict which annotation will be used and are heuristics like "is the annotation named 'Generated'" to determine whether they should it as generated code.
If we do an investigation and find that indeed all the tools we may care about (linters, static analyzers, IDEs) are observing Generated annotations in any package, then we can make our own
io.grpc.Generated
. Unfortunately, I expect theio.grpc.GrpcGenerated
annotation may not suffice because its name is not exactly "Generated." We'll also need to figure out what retention it needs.Tools to investigate (off the top of my head): Error Prone, IntelliJ, Eclipse, Android linter, Find Bugs, Checkstyle. The tools to investigate should be those that may be used by gRPC users, not just those directly used by gRPC maintainers.
javax.annotation.processing.Generated
is not a relevant replacement; see #3633. I highly doubtjakarta.annotation.Generated
would ever be appropriate, even with it being the new home for the annotation; it'd only have an advantage if Nullable goes that way as well, which seems unlikely. But that'd also take investigation of Kotlin and other null-caring tools.The text was updated successfully, but these errors were encountered: