Community
Participate
Working Groups
When mixing on the classpath .class files compiled with 1.4 target and 1.5 target, we can end up with interesting issues. In the test case described below the Eclipse compiler reports: ---------- 1. ERROR in D:\tests_sources\C.java (at line 3) public class C extends B<String> { ^ The type A is not generic; it cannot be parameterized with arguments <T> ---------- 1 problem (1 error) Where javac 1.5 compiles the code reporting an unchecked warning: d:\tests_sources>javac -Xlint:unchecked -classpath classA14.jar;classB15.jar C.java C.java:6: warning: [unchecked] unchecked conversion found : java.util.List required: java.util.List<java.lang.String> return l; ^ 1 warning Test case: 1) Create a class A with the following source: import java.util.List; public class A { List l; } 2) Compile it in 1.4 mode and create a jar file called classA14.jar that contains only the A.class file. jar cvf classA14.jar A.class 3) Now change the source of A to be: import java.util.List; public class A<T> { List<T> l; } 4) Create a class B with this source: public class B<T> extends A<T> {} 5) Compile A and B together and put the resulting B.class (do not include A.class) into a jar called classB15.jar. jar cvf classB15.jar B.class 6) Create a class C with this source: import java.util.List; public class C extends B<String> { List<String> foo() { return l; } } 7) delete A.java and B.java to make sure that they are not picked up during the compilation of C. 8) compile it with the following command line: -classpath classA14.jar;classB15.jar C.java According to the warning reported by javac, it looks like they convert A to be a raw type.
This may be as straight forward as replacing: if (refTypeVariables == Binding.NO_TYPE_VARIABLES) { // check generic this.environment.problemReporter.nonGenericTypeCannotBeParameterized(null, resolvedType, this.arguments); return this; // cannot reach here as AbortCompilation is thrown with : if (refTypeVariables == Binding.NO_TYPE_VARIABLES) { // check generic // add a class library warning here return this.environment.createRawType(resolvedType, null);
Could not we achieve the same result by tagging the class file reader to read all .class files as 1.4 class files? Then the generic signature would not be surface and the raw types would be used for free.
But I think this problem can happen even when .class files are generated by a 1.5 compiler. For example, add a type variable to a type A -> A<T> now what happens if I use the wrong jar file? I see A instead of A<T> but both .class files were generated as 1.5
What I meant is that even if the .class files were produced as 1.5 .class file if the compiler settings are 1.4, the class file reader would not expose more than 1.4 specific contents which means it would not expose the generic signature of the method infos. If the user is using 1.4 libraries and the project settings are 1.5, then we might go with the conversion you mentionned in comment 1.
But if the compiler settings are 1.4, then we already do not read the generic signature. Its only with settings at 1.5 & beyond that we can come across a .class file that expects a generic type.
It may be more work than what got suggested in comment 1. Basically, a raw type (or param type) relies on the fact that its generic type provides type variables (for later substituting etc...). Probably need more tuning --> 3.4 ?
I had expected that the fix for bug 324850 would automatically taken care of this bug. However, that wasn't the case and further tweaks are needed. Patch to follow shortly.
Created attachment 181269 [details] Patch under test
The attached patch fails some tests and I won't have time to analyze them in time for 3.7 M3. Retargetting for M4.
Created attachment 182190 [details] Revised patch under test
See also https://bugs.eclipse.org/bugs/show_bug.cgi?id=328827#c6
Created attachment 182218 [details] Final patch This patch fixes the problem and passes all JDT/Core tests.
Olivier, please review -- TIA. This fix removed the genericity checks and arity checks for binary types (along the lines the fix for bug 83083 removed bounds check in Binary types under the premise that the dependency tracking would automatically trigger the incremental build and problems if any would be reported in the source) These checks looks untenable for a binary type in hybrid 1.4-/1.5+ modes.
Patch looks good. Both failures from bug 329250 are also fixed with this patch. We need intensive testing from users with this mixed mode cases.
Released in HEAD for 3.7 M4
Verified for 3.7M4 using build I20101205-2000.
.