> > Very simply, and exactly as I described: It doesn't exist in the API for > > annotations in JDK 8, so the annotation processor should never be passed > > any reference to it. It doesn't exist. > > > > It is unclear to me how this really helps processors like the > ServiceProviderProcessor do the right thing (whatever that is) when > compiling a named module? >
If you accept my second suggestion (allow version- or language-feature- specific processors), then it allows you to have separate module-aware (whatever it does) and non-module-aware implementations. Most annotation processors probably won't need that, but it solves the corner case for one that does - instead of screaming at users that their Java version is too new, the compiler can just pick the appropriate implementation. For that matter: You're the Java compiler (yes, you, Honza, are personally the Java compiler! I imagine you have days where you feel like that :-)). If you wanted to be completely insane about it, you could have an annotation processor that analyzes Processor sources, and actually writes out a file somewhere in META-INF that describes what APIs that processor calls and what classes it uses, so the compiler could intelligently decide whether to warn about the source version or not. If, say, the supported level is 9 and you're compiling on 10, and there were no changes to ElementKind, you know it will not see elements it doesn't understand, so, no need to warn. Most of the time, there won't be a reason to warn - just occasional cases where there are really big changes. > Or, as an another example, imagine an annotation processor that checks that > all classes referred to from a public API (classes, methods and fields) are > public API classes as well. It needs to determine what is the API, and (as > it is written for JDK 8 originally) it is using a heuristics for that. When > compiling a JDK 9+ named module, there is no need for the heuristics, and > using the heuristics may lead to either false reports (which is not that > bad), but also to a false "acceptance/pass" of the program (i.e. the AP may > be silent), which is worse. And hiding the model for modules from the AP is > not going to improve this. > Which is why I suggested either a way to have version-/feature- specific annotation processors when there is no other way to deal with it. 99% of annotation processors won't have this (or any other) problem - which is why printing a warning in case the annotation processor *is *in that 1% is not a good way to deal with it. This thread shows that really clearly: We have people wanting to make pointless and potentially-harmful code changes (at the very least, returning SupportedSourceVersion.latest() means the compiler will have to actually instantiate all such annotation processors to call that method, slowing down build speed, perhaps a lot) just to hide a warning that, for most annotation processors, really should be ignored. A warning that is wrong 99% of the time is a torture device. > > i don't think there ought to be any difficulty handling *additions* to > the > > API, and for the most part that takes care of itself, since the > annotation > > processor won't reference classes that didn't exist when it was written. > > You'd have to filter the set returned by getElementsAnnotatedWith, but > > > > I think this is trying to solve a problem where the AP may crash on seeing > a new kind of elements. This still leaves some open questions, but, for me, > a more important case is the case where the AP does not fail, but also does > not do what it is supposed to do silently. It is hard to see how hiding > anything from the API is going to help with that. > Well, I wasn't just suggesting hiding elements that shouldn't exist from the API - but make let me make that explicit: If you were an annotation processor supporting JDK 8, the containing element of a package would not be a Module, and if you were on JDK 7, ExecutableElement.getModifiers() would not return Modifier.DEFAULT. Internally, you could do that with annotations that indicate the source level an element, modifier or whatever was introduced in and some generic filtering collection implementations that hide things those things, and a ThreadLocal context for the currently-being-run annotation processor's source level - implementing this would not be that terrifying or ugly, and could be made declarative enough that such changes don't require big code changes throughout the compiler. So, that's two different ways javac could do a better job of this: 1. Present processors with the API they expect, hiding things that might break it. 2. Version/feature-specific annotation processors, so you can have a fallback for older JDKs. 3. Have javac, which has complete information about the processor when the processor itself is being compiled, do some flow analysis and emit some metadata that can be used when the annotation processor is about to be called, to decide whether to issue the warning or not. Any or all of these would improve the current situation. -Tim > (Also, getElementsAnnotatedWith is almost surely not the only method you'd > need to consider, and quite possibly not the most important one. There is > also RoundEnvironment.getRootElements, and then various other methods in > the model, like PackageElement.getEnclosingElement which is AFAIK returning > the owning module for source level >= 9, ExecutableElement.getModifiers() > may include Modifier.DEFAULT since JDK 8, etc.) > > Jan > > > > that's simple. The only corner case is an annotation processor written > > against, say, JDK 9 but supporting source level, say, 7. There it might > be > > better to allow an annotation processor which can specify "only run me on > > JDK 7" and "run me on 9 and up" if you want to use 9-specific stuff. > > > > -Tim > > > > > > > > > > Jan > > > > > > > > > > the annotation processor expects; and perhaps deprecate / delete > > > > compatibility layers for older JDKs on a schedule. Making this the > > > > annotation processor author's problem, or worse, the annotation > > processor > > > > user's problem, is the worst possible solution. > > > > > > > > If the compiler is going to break its API, it should not be other > > > people's > > > > problem to deal with it. And it certainly shouldn't be making people > > > jump > > > > through hoops to fix warnings that it *might have* when it actually > > > hasn't. > > > > > > > > So, yeah, I get the reasoning, but it is the wrong solution to a > > problem > > > > that has yet to actually exist, yelling at people to do something > > because > > > > it might. > > > > > > > > -Tim > > > > > > > > > -- > > http://timboudreau.com > > > -- http://timboudreau.com