Bug 186565 - [1.5][compiler] 1.4/1.5 .class file interaction
Summary: [1.5][compiler] 1.4/1.5 .class file interaction
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.7 M4   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-05-11 10:16 EDT by Olivier Thomann CLA
Modified: 2010-12-07 05:26 EST (History)
4 users (show)

See Also:
Olivier_Thomann: review+


Attachments
Patch under test (6.01 KB, patch)
2010-10-20 05:58 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Revised patch under test (8.45 KB, patch)
2010-11-02 03:52 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Final patch (8.46 KB, patch)
2010-11-02 11:14 EDT, Srikanth Sankaran CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Olivier Thomann CLA 2007-05-11 10:16:40 EDT
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.
Comment 1 Kent Johnson CLA 2007-05-17 14:49:28 EDT
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);
Comment 2 Olivier Thomann CLA 2007-05-18 10:36:11 EDT
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.
Comment 3 Kent Johnson CLA 2007-05-18 10:53:49 EDT
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
Comment 4 Olivier Thomann CLA 2007-05-18 12:21:22 EDT
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.
Comment 5 Kent Johnson CLA 2007-05-18 13:17:54 EDT
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.
Comment 6 Philipe Mulet CLA 2007-05-19 09:41:39 EDT
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 ?
Comment 7 Srikanth Sankaran CLA 2010-10-20 05:55:39 EDT
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.
Comment 8 Srikanth Sankaran CLA 2010-10-20 05:58:10 EDT
Created attachment 181269 [details]
Patch under test
Comment 9 Srikanth Sankaran CLA 2010-10-21 00:15:42 EDT
The attached patch fails some tests and I won't
have time to analyze them in time for 3.7 M3.
Retargetting for M4.
Comment 10 Srikanth Sankaran CLA 2010-11-02 03:52:55 EDT
Created attachment 182190 [details]
Revised patch under test
Comment 11 Srikanth Sankaran CLA 2010-11-02 03:57:10 EDT
See also https://bugs.eclipse.org/bugs/show_bug.cgi?id=328827#c6
Comment 12 Srikanth Sankaran CLA 2010-11-02 11:14:05 EDT
Created attachment 182218 [details]
Final patch 

This patch fixes the problem and passes all JDT/Core tests.
Comment 13 Srikanth Sankaran CLA 2010-11-02 11:20:44 EDT
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.
Comment 14 Olivier Thomann CLA 2010-11-02 11:54:58 EDT
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.
Comment 15 Srikanth Sankaran CLA 2010-11-02 12:22:12 EDT
Released in HEAD for 3.7 M4
Comment 16 Ayushman Jain CLA 2010-12-07 05:26:06 EST
Verified for 3.7M4 using build I20101205-2000.
Comment 17 Ayushman Jain CLA 2010-12-07 05:26:24 EST
.