Name: avC70361 Date: 06/04/99
The javac of Kestrel-F produces incompatible with previous versions of javac.
The javac produces an inner class(with a reference to outer class) for every anonymous
class defined in non-static method. But the previous javac generates the inner class
only when the reference to the outer class is explicitly needed. Moreover, new compiler
doesn't mark the anonymous class final, whereas the older one does. All that can cause
problems with icompatibility of serialization. First, with the new compiler when serializing
anonymous class the outer class is serialized too, but with previous compiler it isn't.
The serialVersionUID will be different due to the additional non-transient field, and
due to the absent final mofifier.
Here is a test demonstrating the bug.
-------------AnonymousTest.java-----------
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class AnonymousTest {
public static void main(String[] args) {
AnonymousTest t = new AnonymousTest();
try {
ObjectOutputStream os = new ObjectOutputStream(
new ByteArrayOutputStream()
);
os.writeObject(t.createObject());
System.out.println("Passed");
} catch (IOException e) {
System.out.println("Failed. Unexpected exception : " + e);
}
}
public Object createObject() {
return new Serializable() {
void method1() {
}
};
}
public static Object createObject2() {
return new Serializable() {
void method2() {
}
};
}
}
-------------------------
1. javap output:
1.1. jdk 1.2:
<avv@mizar(pts/3).296> java -version
java version "1.2"
Classic VM (build JDK-1.2-V, green threads, sunwjit)
<avv@mizar(pts/3).297> javac AnonymousTest.java
<avv@mizar(pts/3).298> javap -private "AnonymousTest\$1"
Compiled from AnonymousTest.java
final class AnonymousTest$1 extends java.lang.Object implements java.io.Serializable {
//^^^^^^^^^^^
AnonymousTest$1();
void method1();
}
<avv@mizar(pts/3).299> javap -private "AnonymousTest\$2"
Compiled from AnonymousTest.java
final class AnonymousTest$2 extends java.lang.Object implements java.io.Serializable {
//^^^^^^^^^^^
AnonymousTest$2();
void method2();
}
1.2. Kestrel:
<avv@mizar(pts/3).316> java -version
java version "1.3"
Classic VM (build JDK-1.3-F, green threads, sunwjit)
<avv@mizar(pts/3).317> javac AnonymousTest.java
<avv@mizar(pts/3).318> javap -private "AnonymousTest\$1"
Compiled from AnonymousTest.java
class AnonymousTest$1 extends java.lang.Object implements java.io.Serializable {
//^^^^^
private final AnonymousTest this$0;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AnonymousTest$1(AnonymousTest);
void method1();
}
<avv@mizar(pts/3).319> javap -private "AnonymousTest\$2"
Compiled from AnonymousTest.java
class AnonymousTest$2 extends java.lang.Object implements java.io.Serializable {
//^^^^^
AnonymousTest$2();
void method2();
}
2. serialver output:
2.1. jdk 1.2:
<avv@mizar(pts/3).327> java -version
java version "1.2"
Classic VM (build JDK-1.2-V, green threads, sunwjit)
<avv@mizar(pts/3).328> javac AnonymousTest.java
<avv@mizar(pts/3).329> serialver "AnonymousTest\$1"
AnonymousTest$1: static final long serialVersionUID = 1679244602498112304L;
//^^^^^^^^^^^^^^^^^^^^^
<avv@mizar(pts/3).330> serialver "AnonymousTest\$2"
AnonymousTest$2: static final long serialVersionUID = 7417134557284076014L;
//^^^^^^^^^^^^^^^^^^^^^
2.2 Kestrel:
<avv@mizar(pts/3).332> java -version
java version "1.3"
Classic VM (build JDK-1.3-F, green threads, sunwjit)
<avv@mizar(pts/3).333> javac AnonymousTest.java
<avv@mizar(pts/3).334> serialver "AnonymousTest\$1"
AnonymousTest$1: static final long serialVersionUID = -3679484467859067554L;
//^^^^^^^^^^^^^^^^^^^^^^
<avv@mizar(pts/3).335> serialver "AnonymousTest\$2"
AnonymousTest$2: static final long serialVersionUID = -2682274742240042661L;
//^^^^^^^^^^^^^^^^^^^^^^
3. Test output:
3.1. jdk 1.2:
<avv@mizar(pts/3).339> java -version
java version "1.2"
Classic VM (build JDK-1.2-V, green threads, sunwjit)
<avv@mizar(pts/3).340> javac AnonymousTest.java
<avv@mizar(pts/3).341> java AnonymousTest
Passed
3.2. Kestrel:
<avv@mizar(pts/3).343> java -version
java version "1.3"
Classic VM (build JDK-1.3-F, green threads, sunwjit)
<avv@mizar(pts/3).344> javac AnonymousTest.java
<avv@mizar(pts/3).345> java AnonymousTest
Failed. Unexpected exception : java.io.NotSerializableException: AnonymousTest
======================================================================
- relates to
-
JDK-8161009 15.9.5: Anonymous classes aren't actually 'final'
- Closed
-
JDK-4777101 final treatment of anonymous classes not marked in .class files?
- Closed