Community
Participate
Working Groups
If class B extends A, then B will be recompiled when A's structure changes - for instance, when the return type or modifiers of a method change. At present, changes to annotations are not considered structural changes. So, if A has a method "public int foo()", changing it to "protected int foo()" will trigger recompilation of B; but changing it to "@Bar public int foo()" will not. This causes problems for certain annotation processors. Consider a processor that looks for classes annotated with @GetterTarget, and when it finds one produces a subclass containing getXXX() methods for every protected field in its superclasses that is annotated with a particular annotation. That processor should be run whenever annotations change on any of its supertypes. This is very similar to the idea that adding @Deprecated to a type or method, or @Retention to an annotation, should result in recompilation of its dependents. Those examples already work in Eclipse, because they are special-cased. The request here is for all annotations to be treated the same way. Specifically, any aspect of a type's structure that can be accessed from a JSR-269 annotation processor should also be honored when evaluating structural changes, so that the annotation processor gets called when it should.
*** Bug 223497 has been marked as a duplicate of this bug. ***
Please consider raising severity of this bug. This bug is a real show-stopper for us. Consider a very simple annotation processor validating that each field annotated with @Reference should have a type annotated with @Referable (a variation on 'dependency injection' theme). This basic processor is not going to work in incremental build mode. For example, if we remove @Referable annotation on some class the classes which depend on that class (including classes with @Reference fields referring that class) will not be recompiled and our validating processor will not even be called so no errors will be flagged to the user. Thus the referential integrity of our model will be compromised. The only workaround being the full build is really unacceptable as it ruins the user experience and will not scale on large projects.
DI is an interesting use case for this feature. Can you clarify the expectation? I'm imagining you have something like: @Reference(Foo.class) class Bar { ... } and then you are expecting that if annotations on Foo change, the compiler should recompile Bar? Presumably it would not work if the class were referred to by name alone, e.g., @Reference("com.you.Foo") class Bar { ... }
Walter, I meant something like that: @Referable class Foo { ... } class Bar { @Reference Foo foo; } in which case an instance of Foo will be injected by DI container into the field 'foo'. The invariant being 'each field annotated with @Reference should refer to a @Referable class'. So if @Referable is removed from 'Foo' our processor should flag an error on 'Bar.foo'.
Another use case. Parameter types of @WebMethod methods should be annotated with @XmlRootElement (from JAXB). I.e.: @WebService class Foo { @WebMethod void foo(Bar bar); } @XmlRootElement class Bar { ... } So if @XmlRootElement is removed from 'Bar' our processor should flag an error on 'bar' parameter of 'Foo#foo' method.
So, in all these cases you have a normal compilation dependency (that is, the compiler clearly knows it has a type dependency); no enhancement of the dependency computation is needed, rather it's a matter of broadcasting annotation changes in the same way that, e.g., changing the type hierarchy of the annotated type would be broadcast.
Exactly!
Created attachment 121111 [details] test case Here's a patch for org.eclipse.jdt.apt.tests, that demonstrates the problem. The test case in this patch currently fails. I'll try and write a jdt.core (not APT) test to verify this - I figured I'd start with something I knew well.
Created attachment 121159 [details] Proposed patch
Created attachment 121479 [details] Test cases Here's a suite of test cases that run in org.eclipse.jdt.core.tests.builder. These tests fail without the proposed patch, and pass with it. Note that they (of course) require a 1.5 VM. I've also modified BuilderTests to include the new test cases, in the 1.5 section. One question: I don't really understand why changing an annotation on an inner type X within type A causes type B to be recompiled, if B references A (but not A.X). Is it because dependencies are managed on the basis of compilation units rather than types? It's working fine, I'm just wondering why.
> Is it because dependencies are managed on the basis of compilation units rather than types? Correctamondo Type dependencies take too much space & since we end up recompiling the entire compilation unit - why bother ?
Fix and tests released for 3.5M5
Verified for 3.5M5 using I20090126-1300