Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.4.5
-
None
-
OSX 10.10, JDK 1.8
Description
When @AutoExternalize and @CompileStatic are both applied to a nested (static) class, the generated writeExternal and readExternal methods call writeObject/readObject on 'this' rather than on their arguments. This results in IncompatibleClassChange errors at runtime. Example:
class Person { @groovy.transform.ToString(includePackage=false) @groovy.transform.AutoExternalize @groovy.transform.CompileStatic static class AddressCS { String street, town } }
The bytecode generated for the Person.AddressCS.writeExternal method is:
public writeExternal(Ljava/io/ObjectOutput;)V throws java/io/IOException L0 ALOAD 0 ALOAD 0 GETFIELD Person$AddressCS.street : Ljava/lang/String; INVOKEINTERFACE java/io/ObjectOutput.writeObject (Ljava/lang/Object;)V ACONST_NULL POP ALOAD 0 ALOAD 0 GETFIELD Person$AddressCS.town : Ljava/lang/String; INVOKEINTERFACE java/io/ObjectOutput.writeObject (Ljava/lang/Object;)V ACONST_NULL POP L1 RETURN LOCALVARIABLE this LPerson$AddressCS; L0 L1 0 LOCALVARIABLE out Ljava/io/ObjectOutput; L0 L1 1 MAXSTACK = 2 MAXLOCALS = 2
This seems to occur because the writeObject method call expressions within writeExternal have implicitThis set to true.
The problem is essentially the same for generated readExternal methods.