Community
Participate
Working Groups
Build Identifier: 20090619-0625 I created a class that extends an abstract class with a compareTo-Method. The class that is compiled from eclipse is different from the one i created with the java compiler, resulting in a mismatching serialversionuid. Reproducible: Always Steps to Reproduce: 1. Create an Abstract Class that implements Comparable and Serializable: 2.Create an Implementation that overwrites this class: 3. Compile with eclipse 4. Compile with javac 5. The javac compiler adds an extra Method public bridge synthetic int compareTo(java.lang.Object x0); that is not created by the eclipse Compiler
Created attachment 160322 [details] Testcases and class Files The attachment contains my Testclasses(test-fodler) and the compiled classes by eclipse(in the build/eclipse folder)/java (in the build/test folder)
First of all, if you really care about the serialVersionUID, you should provide it yourself. There is absolutely no guarantee that Eclipse compiler and javac compiler will generate the same version UID. Srikanth, please investigate if the bridge method is required there. Thanks.
Simplified test case that can be cut & pasted into package explorer: ------------------------------8<-------------------------------- import java.io.Serializable; public class Test extends AbstractBase<Test> { @Override public int compareTo(Test pO) { return 1; } } abstract class AbstractBase<TA extends AbstractBase> implements Serializable, Comparable<TA> { public int compareTo(TA pO) { return -1; } } ---------------------------------------------------------------- javap Test (Test.class produced by javac5,6,7) ----------------------------------------------- public class Test extends AbstractBase{ public Test(); public int compareTo(Test); public int compareTo(AbstractBase); public int compareTo(java.lang.Object); } javap Test (Test.class produced by eclipse) ------------------------------------------- Compiled from "Test.java" public class Test extends AbstractBase{ public Test(); public int compareTo(Test); public int compareTo(AbstractBase); } So a bridge does appear to be missing. However purely in terms of control flow, this shouldn't matter since Test inherits the bridge public int compareTo(java.lang.Object) ----> public int compareTo(AbstractBase) and overrides the latter with its own bridge public int compareTo(AbstractBase) ----> public int compareTo(Test); So effectively there is a bridge from public int compareTo(java.lang.Object) ---> public int compareTo(Test); so that the program below prints "Test#CompareTo" as expected and matching javac in this call stack: Test.compareTo(Test) line: 5 Test.compareTo(AbstractBase) line: 1 Test(AbstractBase<TA>).compareTo(Object) line: 1 Test.main(String[]) line: 12 import java.io.Serializable; public class Test extends AbstractBase<Test> { @Override public int compareTo(Test pO) { System.out.println("Test#CompareTo"); return 1; } public static void main(String [] args) { Comparable c = new Test(); Object o = c; c.compareTo(o); } } abstract class AbstractBase<TA extends AbstractBase> implements Serializable, Comparable<TA> { public int compareTo(TA pO) { System.out.println("AbstractBase#CompareTo"); return -1; } } Having a single bridge a la javac would -- slightly improve performance -- eliminate this gratuitous difference with javac -- eliminate the kind of issues that arise via use of reflection APIs (see bug#298362) I'll investigate and see what it would take.
(In reply to comment #2) > First of all, if you really care about the serialVersionUID, you should provide > it yourself. > There is absolutely no guarantee that Eclipse compiler and javac compiler will > generate the same version UID. Or that two different versions of javac will generate the same SUID. Or for that matter that two different versions of eclipse compiler will generate the same SUID. Section 4.6 (Stream Unique Identifiers) in "Java Object Serialization Specification version 1.5.0" states: "It is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected serialVersionUID conflicts during deserialization, causing deserialization to fail." > Srikanth, please investigate if the bridge method is required there. > Thanks. As the example program in comment#3 shows from a control flow pov, we are doing the right thing. While it would be ideal to eliminate this gratuitous difference between javac and ecj, after an initial investigation it looks like a lot of work for clearing up something that the specification tolerates/makes allowances for and what the spec anyway warns about as being the developer's responsibility. Given the above, I am inclined to close this as WONT_FIX.
This has a long history: See bug#10104, bug#30209, bug#32227, bug#30357, bug#37328, bug#50958 (and many many more)
*** This bug has been marked as a duplicate of bug 10104 ***
Having the target milestone be 2.0M4 is kind of weird in my opinion. In any case, is there a reason why the visibility of this bug has been reduced?
(In reply to comment #7) > Having the target milestone be 2.0M4 is kind of weird in my opinion. I'll admit it felt very odd setting it to that, for better or worse, that is the documented process we are following (http://wiki.eclipse.org/JDT_Core_Committer_FAQ#What_target_milestone_should_be_used.3F) > In any case, is there a reason why the visibility of this bug has been reduced? I think it was submitted that way - Stefan ?
I submitted it as normal, because I know using the serialversionUID is the best practice :). In our project we don't and we mix compilers(for Developertests only :)), so I didn't find it critical or blocking.
(In reply to comment #8) > > In any case, is there a reason why the visibility of this bug has been reduced? > > I think it was submitted that way - Stefan ? In the defect modification history, there is a record: Who When What Removed Added srikanth_sankaran@in.ibm.com 2010-03-01 04:06:07 EST Group Security_Advisories so I may have had my finger in the pie without knowing it :) I'll reset it shortly.
Verified for 3.6M6 using build I20100305-1011