JDK-6512707 : "incompatible types" after (unrelated) annotation processing
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6,6u10,6u24
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS:
    generic,linux,linux_ubuntu,windows,windows_xp generic,linux,linux_ubuntu,windows,windows_xp
  • CPU: generic,x86
  • Submitted: 2007-01-12
  • Updated: 2012-01-13
  • Resolved: 2012-01-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u30Fixed 7 b44Fixed OpenJDK6Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
javac fails with "incompatible types" in combination with (unrelated) annotation processing.
It seems that this only happens for defaults of annotation values.
Effected are at least annotations (see example) and typed Classes (f.e. Class<? extends Enum>).


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. compile test/M.java and test/P.java into a directory "dir"

2. compile test/A.java, test/D.java and test/V.java with
    -processor test.P
    -cp dir



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
compile without errors
ACTUAL -
compiler error "incompatible types" test.V vs. test.V

ERROR MESSAGES/STACK TRACES THAT OCCUR :
C:\dev\jtools\research\src\test\test\A.java:20: incompatible types
found   : test.V
required: test.V
V value() default @V;
^
    [javac] 1 error


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
---test/M.java---
package test; public @interface M {}
---test/P.java---
package test;
import java.util.Set;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
@SupportedAnnotationTypes("test.M")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class P extends AbstractProcessor {
    public boolean process(Set< ? extends TypeElement> arg0, RoundEnvironment arg1) {
        return false;
    }
}
---test/A.java---
package test;
public @interface A {
    V value() default @V;
}
---test/D.java
package test;@M public interface D {}
---test/V.java
package test; public @interface V {}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
run processors separately.
* javac -proc:only
* javac -proc:none

This is not adequate.

Comments
EVALUATION From Peter.Runge at acma.gov.au on compiler-dev ------------------- Hi everyone, I ran into this bug regarding annotation processing a couple of days ago and have attempted a fix. I have signed and sent off the SCA by e-mail. Do I need to wait for a response before posting patches/fixes? Anyway, I believe the root of the problem is that com.sun.tools.javac.tree.TreeScanner does not scan for default values for methods (which are only used for annotation and enum default values). This causes an issue because cleanTrees() in com.sun.tools.javac.processing.JavacProcessingEnvironment, which I think cleans up symbols from all elements in the source tree, is missing out on cleaning up symbols for default values which is causing the error as described in the bug (e.g. 'TestEnum' incompatible type with 'TestEnum'). What led me to this conclusion was through debugging the compiler, I found that multiple Type objects that had the same name for Enums (but were not equal) were existing when running an annotation processor first - this didn't happen when running the compiler by itself (the same Type object was used throughout the compiler run). For example, at the start of checkType() in com.sun.tools.javac.comp.Check, when the names (used toString()) of the found and required types were the same, found == req for a 'good' compile run without an annotation processor running first but found != req when an annotation processor ran first for enumeration types with default values. toString() for com.sun.tools.javac.code.Type uses the symbol to find the name. This is what led me to believe that symbols were not properly cleaned up after an annotation processor run. Adding a line in TreeScanner's visitMethodDef() to scan(tree.defaultValue) seems to squash the bug. Can anyone think of any issues with this fix? Regards, Peter ------------------------
07-01-2009