-
Notifications
You must be signed in to change notification settings - Fork 744
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
Var/LazyInit/etc annotations can cause problems for Android builds due to reliance on javax.lang.model.element.Modifier #2122
Comments
Thanks for the write-up and the suggestions. I agree that, in hindsight, using a different representation of the modifiers would have been a good choice, since At this point, my concern is that would be a breaking change to the API of There are ways to do the change incrementally (like introducing the new way to specify modifiers in parallel with the current one, deprecate the current one, and wait a while before removing it). We could also introduce a separate Android-compatible version of the annotations artifact. A few other stray thoughts: it would be nice if those javac diagnostics could be controlled by a flag (like Finally, you mentioned in the thread
We're actually doing something similar to that, which is why we hadn't noticed this issue in our own code. As long as the dep is removed before dexing, and the annotations referencing the enum are |
This would be quite helpful. Something as simple as having a The above could theoretically break builds which use one version of the EP checkers and a different version of the EP annotations artifact (e.g. 2.5.1 core and 2.5.2 annotations could result in
So, Given that, my current thinking as to internal workarounds has evolved to favor forking That said, we'd love to have a good way to keep to mainline EP without an internal fork (have done that before, not a huge pain, but not the best either). |
Future versions of Android may include We could think about doing something like: public @interface IncompatibleModifiers {
/** @deprecated use {@link #modifier} instead. */
@Deprecated
javax.lang.model.element.Modifier[] value();
com.google.errorprone.annotations.Modifier[] modifier();
} And waiting a few releases, and then deleting public @interface IncompatibleModifiers {
/** @deprecated use {@link #value} instead. */
@Deprecated
com.google.errorprone.annotations.Modifier[] modifier();
com.google.errorprone.annotations.Modifier[] value();
} If I had a time machine to use a different If the change I described happened, do you have any input on how quickly you'd want to see support for the old element be removed? I'm just curious if you have opinions about the rate of breaking changes in the API, we don't get a lot of feedback on that generally.
That makes sense to me in the short term, FWIW. I'd like to give you an alternative using mainline EP, but also can't promise we're going to have that alternative in the immediate future. |
So, I think - but I am not sure - that this might just work immediately for us:
But only if, at the same time the I think it might be worth testing if that would be enough to prevent the compiler from trying to complete e.g. I might do a quick internal experiment on this. If that works, we might even be fine with I understand this is not super high priority on your end, but would you guys consider a PR implementing the solution you detailed above if that fixed the issue for us?
We are currently doing this, and it does mitigate the problem for us. But we'd love to be able to go back to not forking any part of Error Prone and just being on mainline! (Plus, I suspect we aren't the only ones using EP for Android outside of Google...)
So, this is separate from the issue at hand, but, since you ask... We did run into an issue recently where to get NullAway to work with Error Prone 2.5.1, we had to drop compatibility with 2.3.x (uber/NullAway#447). So far, that hasn't been too painful a decision, to be honest. Internally, we are currently on Error Prone 2.4.0. Would have been more complicated if we were lagging further behind, though, and we might yet hear of some NullAway third-party user who has issues upgrading to 0.9.0 because of it. As for why we aren't on 2.5.1 yet, we build massive monorepos with However, the main reasons are usually not any changes to core or the APIs (we modify our own checkers to match whichever EP version we are on and that's often <1hr for all of them at worst), or new checkers being introduced (we can always set them to The true upgrade pain points for us are: a) dependency changes where upgrading Error Prone can easily involve a cascading upgrade of core deps for us (e.g. Guava), and b) existing checkers that have been updated to be more precise. The later is often a trade-off between adding a dozen to a few hundred suppressions or setting to The first issue, (a), just seems like a fact of life to me. Not sure (b) has an easy solution either, but at least in theory could be avoided if big changes to checkers resulted to checkers or in a world where you could say something like We can simulate the later by forking a checker internally and renaming, but this is rarely worth it as an intermediate/mitigation step. Just to be clear, though, I am not asking you to address any of this stuff. I am more concerned by the original issue. But you asked for feedback on breaking changes and EP versions, hence the brain-dump. |
FYI - R8 gives much more detailed warnings about this in AGP 7.0+
|
for use in `@IncompatibleModifiers` and `@RequiredModifiers`, as an alternative to `javax.lang.model.element.Modifier` which is not available at compile-time on Android. #2122 PiperOrigin-RevId: 375137408
for use in `@IncompatibleModifiers` and `@RequiredModifiers`, as an alternative to `javax.lang.model.element.Modifier` which is not available at compile-time on Android. #2122 PiperOrigin-RevId: 375503791
I went ahead and deprecated |
Really appreciated, I think with this, we should be able to stop forking the annotations artifact after the next EP release! (We shouldn't really care about the deprecated API so long as it's not being used within EP itself) |
in preparation for introducing a new `Modifier` enum. #2122 PiperOrigin-RevId: 375545113
in preparation for introducing a new `Modifier` enum. #2122 PiperOrigin-RevId: 375574262
for use in `@IncompatibleModifiers` and `@RequiredModifiers`, as an alternative to `javax.lang.model.element.Modifier` which is not available at compile-time on Android. #2122 PiperOrigin-RevId: 375548532
for use in `@IncompatibleModifiers` and `@RequiredModifiers`, as an alternative to `javax.lang.model.element.Modifier` which is not available at compile-time on Android. #2122 PiperOrigin-RevId: 375766509
Description of the problem / feature request:
Multiple annotations inside
com.google.errorprone:error_prone_annotations
use the meta-annotation@IncompatibleModifiers(FINAL)
.Here,
FINAL
referencesjavax.lang.model.element.Modifier.FINAL
. However, theandroid.jar
file used to build Android projects does not includejavax.lang.model.element.Modifier
.This results in the following error whenever code using
@Var
,@LazyInit
,@ForOverride
, etc. is compiled for Android with a-Werror
flag (our default setup):For an example, here is a simple repro as a standalone Android project using gradle (see below for instructions).
Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
Observe:
What version of Error Prone are you using?
Can repro on 2.5.1, 2.4, and 2.3.3
Have you found anything relevant by searching the web?
I posted on the mailing list and got prompt help from Liam figuring out the root cause of the issue. Thanks!
My recommended solution
The real problem here is
@IncompatibleModifiers
and its use ofjavax.lang.model.element.Modifier
's enum values as annotation parameters.Could
com.google.errorprone:error_prone_annotations
perhaps include a separateModifier
enum that doesn't depend onjavax.lang.model.element.Modifier
, and use that for the public API of the@IncompatibleModifiers
meta-annotation and for annotating the relevant Error Prone annotations?This will likely complicate
IncompatibleModifiersChecker
a bit, or require a mapping from the new customModifier
enum tojavax.lang.model.element.Modifier
, but it will make the annotation fully compatible with Android builds.FYI, if you agree that supporting Android with
-Werror
is important, and that the above is a reasonable solution, I'd be more than happy to give it a first try at a PR that replacesjavax.lang.model.element.Modifier
with e.g.com.google.errorprone.annotations.Modifier
.The text was updated successfully, but these errors were encountered: