I have some code.
I have two classes. They both have inner enums.
The two inner enums have an annotation.
But one of them does not compile. The other one compiles just fine.
In eclipse there's no error, but when I build the code from ant I get a compilation error - the annotation class is not found:
[javac] ProblematicClass.java:147: cannot find symbol
[javac] symbol : class XmlType
[javac] location: class package.ProblematicClass
[javac] @XmlType(name="fff")
[javac] ^
[javac] 1 error
I spent some time looking for it - I thought that the classpath is wrong, I endorsed an updated version of the API (java 6). The issue persisted.
Then I decided to use javac directly:
javac -verbose -classpath lib\X.jar;lib\X2.jar -d bin -sourcepath src -encoding UTF-8 src\package\ProblematicClass.java
Strangely enough I got the same error?! Then I did the same for the class that did compile successfully using ant - it worked.
So there was a difference between the two classes and I had to find it.
And I found it, can you find it?
-->
-->
//Does not compile
public class ProblematicClass
{
@XmlType( name = "fff1" )
public static enum InnerType {}
}
// Compiles
public class CompilableClass
{
@XmlType( name = "fff2" )
public enum InnerType {}
}
Yes, you're correct. The second enum is not static.
This only happens with inner static enums. The anomaly does not occur if it's an inner static class. I don't know why.
So I'm thinking that in the ProblematicClass the annotation is not visible because the import of XmlType is not visible.
I was correct - this one works:
-->
-->
-->
//Does not compile
public class ProblematicClass
{
@javax.xml.bind.annotation.XmlType( name = "fff1" )
public static enum InnerType {}
}
I just supplied the FQN of @XmlType.
So eclipse is working, javac is not. Now is the time to say that Eclipse is not using javac. I thought it was using jikes (made by IBM), but that's not correct. Eclipse is using its own incremental compiler part of JDT Core. JDT stands for Eclipse Java Development Tools.
http://www.eclipse.org/jdt/core/:
JDT Core is the Java infrastructure of the Java
IDE. It includes:
- An incremental Java compiler. Implemented as an Eclipse
builder, it is based on technology evolved from VisualAge for Java compiler.
In particular, it allows to run and debug code which still contains unresolved
errors.
- ...
So either javac or Eclipse's compiler is wrong. I would bet that javac is following the spec more strictly.
This is the second time I'm catching Eclipse's compiler of misconduct. The first time was something related to a very complex case with generics - one of the compilers said it was a warning, the other - error.
Update: I was wrong. I was trying to report the problem. I was making a pretty simple case. I used a different annotation: @javax.annotation.Resource. It worked both on Eclipse and on javac.
So the problem is somehow linked with JAXB.
JAXB is an API bundled with Java 6 (an 'endorsed standard' a 'standalone technology'). The version bundled was JAXB 2.0. If one wants to use a newer version, say JAXB 2.1, an 'Endorsed Standards Override Mechanism' had to be used.
Info on JAXB here.
Info on endorsed mechanism here.
I'm currently with JDK 6 update 10. Somewhere I saw that 'endorsed standard override mechanism' was no longer necessary.
It looks like the problem is more on javac side than on Eclipse's compiler.
I will investigate further.
Update2: It comes out that 'Endorsed Standards Override Mechanism' was existing prior to java 6. Only the standalone technologies were added in Java 6.
Update3: It comes out that 'Endorsed Standards Override Mechanism' is still used.
Update4: It comes out that this bug is very hard to reproduce. My simple examples at some point just started compiling 🙁
Update5: I just created some code that consistently reproduces the bug. I'll write it in a new entry to be cleaner.
Update6: I fixed coloring and finished the new article on the bug.