4

I downloaded JDK source code (6u23 build b5) for research, and Eclipsed decided to automatically build it. Astonishingly, it found errors.

A few examples.

java.beans.MetaData, line 1365:

ConstructorProperties annotation = constructor.getAnnotation(ConstructorProperties.class);

Type mismatch: cannot convert from Annotation to ConstructorProperties

java.awt.AWTEvent, line 220:

AWTAccessor.setAWTEventAccessor(new AWTAccessor.AWTEventAccessor() {

The type new AWTAccessor.AWTEventAccessor(){} must implement the inherited abstract method AWTAccessor.AWTEventAccessor.getAccessControlContext(AWTEvent)

I thought this code supposed to be absolutely correct, if not being one of the best examples of Java usage that one can learn from. But that doesn't even compile!

Update: I exported java package into individual project, removed the java package default import to avoid possible namespace conflicts and used JVM 1.6.0 to build it.

Max Yankov
  • 12,551
  • 12
  • 67
  • 135
  • 1
    What Java version did you compile it with? Note that there may always be errors in software, even if it has high quality - it's software after all, which can't be 100% error free. It doubt that Oracle would deliver uncompilable code (but who knows, errare humanum est ;) ) - so look for differences between your build environment and theirs. – Thomas Jul 04 '11 at 15:09
  • 2
    Almost all of the code in the code base is a good example, however there are plenty of bad examples. :( – Peter Lawrey Jul 04 '11 at 15:10
  • @Peter Well that's true for every large project to some degree I think. The JDK source code and API design are quite good for their age and the fact that the 1.0 APIs had to be designed in a quite short timeframe (now hopefully nobody takes the cloneable implementation as the paragon of great architectural design) – Voo Jul 04 '11 at 15:15
  • 2
    @Voo, also large portions of the JDK are from third party libraries, some of which used generated code resulting in ugly code which has been updated for best practices for some time. e.g. There is a class called com.sun.java.swing.plaf.nimbus. InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState – Peter Lawrey Jul 04 '11 at 15:19
  • Added details about compiler to post. – Max Yankov Jul 04 '11 at 15:20
  • @golergka, Which JDK 6 update did you use, the latest is update 26? ;) – Peter Lawrey Jul 04 '11 at 15:21
  • Peter, I used the latest JDK for building. Might that be a problem? – Max Yankov Jul 04 '11 at 15:24
  • @Peter Ok I only looked at the "official" parts of the API (ie collections, imagereader) and some interesting undocumented (the unsafe part for one) and those looked quite nice. Interesting classname - very meaningful :D – Voo Jul 04 '11 at 16:42
  • @golergka, Java 6 update 26 is the latest version of the JDK and it comes with a src.zip which contains the source for the most public classes. My guess is you downloaded the OpenJDK bundle (the latest was for Java 6 update 23) – Peter Lawrey Jul 05 '11 at 05:44
  • @Peter, no, I downloaded complete JDK source bundle from here: http://download.java.net/jdk6/6u23/promoted/b05/jdk-6u23-fcs-src-b05-jrl-12_nov_2010.jar – Max Yankov Jul 05 '11 at 07:39
  • @golargka, Like I said. That is the source bundle for OpenJDK (which is very similar). They don't release the complete source for the Sun/Oracle JDK. The place to look is the src.zip which comes with the JDK. – Peter Lawrey Jul 05 '11 at 07:49

2 Answers2

2

The problem you have here is that the specification for generics has evolved over time. :| The latest version of Sun/Oracle Java compiles this code correctly, however its the IDE which doesn't realise it now compiles. (Unfortunately Eclipse uses its own compiler and its not always exactly the same as the Sun/Oracle compiler)

I am pretty sure older versions of the compiler would produce an error for this line of code.

It used to be that if a type was not a generic, all generics were turned off, even if that didn't make sense. In the case of this method.

public <T extends Annotation> T getAnnotation(Class<T> annotationClass) 

// constructor is not a generic type.
private static String[] getAnnotationValue(Constructor constructor) {
        ConstructorProperties annotation = constructor.getAnnotation(ConstructorProperties.class);

The older compilers would assume this was a non-generic method as the Constructor is not generic. However the newer compiler identifies this method is self contained and it shouldn't matter whether the class is a generic type of not.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Can I do something for Eclipse to work correctly in this situation? – Max Yankov Jul 04 '11 at 15:26
  • I wouldn't attempt to recompile the entire JDK (its only about 95% complete in src.zip), just recompile the classes which interest you (don't say everything ;). You could use the Sun/Oracle compiler to compile its source, change the code so it compiles in Eclipse, or get the IBM JDK source. – Peter Lawrey Jul 04 '11 at 15:31
  • I use the project with the java package, not the whole JDK. But thanks for advice about changing the compiler though! I'll google that. – Max Yankov Jul 04 '11 at 15:35
  • I'm still looking for a way to change compiler in Eclipse, but I just realize that this can't be all – what about not implemented abstract method? – Max Yankov Jul 04 '11 at 15:42
  • I have Java 6 update 25 and it has the method implemented on line 255. Perhaps you want to look at the src.zip for Java 6 update 26 (the latest) – Peter Lawrey Jul 04 '11 at 15:45
0

Oh there is an awful lot of confusion about the implementation of the JLS as far as generic method parameters are concerned. It might well be that the code you posted compiles with javac, but not with Eclipse (which in my opinion has a superior but incorrect compiler). This compiles in Eclipse:

private static String[] getAnnotationValue(Constructor<?> constructor) {
  ConstructorProperties annotation = 
    constructor.getAnnotation(ConstructorProperties.class);

This doesn't (your example, with a raw-typed Constructor):

private static String[] getAnnotationValue(Constructor constructor) {
  ConstructorProperties annotation = 
    constructor.getAnnotation(ConstructorProperties.class);

Check out this question I had recently. It gives me the creeps:

Reference is ambiguous with generics

I'd definitely look for the error in Eclipse

Community
  • 1
  • 1
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • And what about not implemented abstract method? This error has nothing to do with generics. – Max Yankov Jul 04 '11 at 15:42
  • That error I couldn't reproduce. I don't have a method `AWTAccessor.AWTEventAccessor.getAccessControlContext(AWTEvent)` in my JDK – Lukas Eder Jul 04 '11 at 15:46