Community
Participate
Working Groups
Build Identifier: M20110210-1200 public class Foo implements Cloneable { public synchronized Foo clone() { return this; } } Compile this class with the eclipse compiler (default 1.6 compliance settings). Also compile the same class with javac from hotspot 1.6.0_24. In the resulting class files the bridge method for clone() ends up with different access modifiers. The eclipse compiler keeps the synchronized access where as javac does not. For the most part this difference doesn't really matter but it was biting me since the different modifiers leads to a different serialVersionUID and breaks serialization. Reproducible: Always
The javap output (from eclipse .class) Compiled from "Foo.java" public class Foo extends java.lang.Object implements java.lang.Cloneable{ public Foo(); Code: 0: aload_0 1: invokespecial #10; //Method java/lang/Object."<init>":()V 4: return public synchronized Foo clone(); Code: 0: aload_0 1: areturn public synchronized java.lang.Object clone() throws java.lang.CloneNotSupportedException; Code: 0: aload_0 1: invokevirtual #22; //Method clone:()LFoo; 4: areturn } And the output from the javac compiler one (note: clone() bridge is not synchronized access): Compiled from "Foo.java" public class Foo extends java.lang.Object implements java.lang.Cloneable{ public Foo(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public synchronized Foo clone(); Code: 0: aload_0 1: areturn public java.lang.Object clone() throws java.lang.CloneNotSupportedException; Code: 0: aload_0 1: invokevirtual #2; //Method clone:()LFoo; 4: areturn }
(In reply to comment #0) > For the most part this difference doesn't really matter but it was biting me > since the different modifiers leads to a different serialVersionUID and breaks > serialization. There are multiple reasons that will lead to a different serialVersionUID from the javac's one. If you really care about serialization, you should set your own serialVersionUID. This being said, we will check what is supposed to be done regarding the synchronized modifiers and bridge method.
Thanks for the input Oliver. For sure the best thing to do for serialization is to be explicit in the code for serialVersionUID. I have no idea if this particular detail is covered in the specs. That said it does seem unnecessary to carry synchronized access in the bridge method so I lean towards javac being more "correct" in this case
(In reply to comment #3) > Thanks for the input Oliver. For sure the best thing to do for serialization is > to be explicit in the code for serialVersionUID. This is actually the only way to do it to get a reliable behavior. javac and the eclipse compiler don't handle the class literal (X.class for example) the same way. So any usage of the class literal in source would lead to a different serialVersionUID. > I have no idea if this particular detail is covered in the specs. That said it > does seem unnecessary to carry synchronized access in the bridge method so I > lean towards javac being more "correct" in this case. I'll double-check that.
I could not find any specific details on the synchronized keyword, but I agree that it makes sense to drop it since the "inner" call is synchronized. Srikanth, any comment on this ?
Created attachment 191223 [details] Proposed fix + regression test
Srikanth, please review. Fix is trivial.
Agree with the fix. Patch looks good.
Released for 3.7M7.
Verified for 3.7M7 using build I20110421-1800