Skip to content

Commit

Permalink
8340409: [lworld] Simple serialization and deserialization of core mi…
Browse files Browse the repository at this point in the history
…grated classes
  • Loading branch information
Roger Riggs committed Oct 24, 2024
1 parent 72472c4 commit e02c628
Show file tree
Hide file tree
Showing 20 changed files with 2,586 additions and 421 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
* an enum type
* <LI> Other conditions given in the <cite>Java Object Serialization
* Specification</cite>
* <LI> A {@linkplain Class#isValue()} value class implements {@linkplain Serializable}
* but does not delegate to a serialization proxy using {@code writeReplace()}.
* <LI> A {@linkplain Class#isValue()} value class implements {@linkplain Externalizable}.
* </UL>
*
* @since 1.1
Expand Down
539 changes: 355 additions & 184 deletions src/java.base/share/classes/java/io/ObjectInputStream.java

Large diffs are not rendered by default.

54 changes: 43 additions & 11 deletions src/java.base/share/classes/java/io/ObjectOutputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import jdk.internal.util.ByteArray;
import sun.reflect.misc.ReflectUtil;

import static java.io.ObjectInputStream.TRACE;

/**
* An ObjectOutputStream writes primitive data types and graphs of Java objects
* to an OutputStream. The objects can be read (reconstituted) using an
Expand Down Expand Up @@ -158,9 +160,36 @@
* defaultWriteObject and writeFields initially terminate any existing
* block-data record.
*
* <a id="record-serialization"></a>
* <p>Records are serialized differently than ordinary serializable or externalizable
* objects, see <a href="ObjectInputStream.html#record-serialization">record serialization</a>.
*
* <a id="valueclass-serialization"></a>
* <p>Value classes are {@linkplain Serializable} through the use of the serialization proxy pattern.
* The serialization protocol does not support a standard serialized form for value classes.
* The value class delegates to a serialization proxy by supplying an alternate
* record or object to be serialized instead of the value class.
* When the proxy is deserialized it re-constructs the value object and returns the value object.
* For example,
* {@snippet lang="java" :
* value class ZipCode implements Serializable { // @highlight substring="value class"
* private static final long serialVersionUID = 1L;
* private int zipCode;
* public ZipCode(int zip) { this.zipCode = zip; }
* public int zipCode() { return zipCode; }
*
* public Object writeReplace() { // @highlight substring="writeReplace"
* return new ZipCodeProxy(zipCode);
* }
*
* private record ZipCodeProxy(int zipCode) implements Serializable {
* public Object readResolve() { // @highlight substring="readResolve"
* return new ZipCode(zipCode);
* }
* }
* }
* }
*
* @spec serialization/index.html Java Object Serialization Specification
* @author Mike Warres
* @author Roger Riggs
Expand Down Expand Up @@ -344,6 +373,9 @@ public void useProtocolVersion(int version) throws IOException {
* object are written transitively so that a complete equivalent graph of
* objects can be reconstructed by an ObjectInputStream.
*
* <p>Serialization and deserialization of value classes is described in
* {@linkplain ObjectOutputStream##valueclass-serialization value class serialization}.
*
* <p>Exceptions are thrown for problems with the OutputStream and for
* classes that should not be serialized. All exceptions are fatal to the
* OutputStream, which is left in an indeterminate state, and it is up to
Expand Down Expand Up @@ -413,6 +445,9 @@ protected void writeObjectOverride(Object obj) throws IOException {
* writeUnshared, and not to any transitively referenced sub-objects in the
* object graph to be serialized.
*
* <p>Serialization and deserialization of value classes is described in
* {@linkplain ObjectOutputStream##valueclass-serialization value class serialization}.
*
* <p>ObjectOutputStream subclasses which override this method can only be
* constructed in security contexts possessing the
* "enableSubclassImplementation" SerializablePermission; any attempt to
Expand Down Expand Up @@ -1198,9 +1233,6 @@ private void writeObject0(Object obj, boolean unshared)
} else if (obj instanceof Enum) {
writeEnum((Enum<?>) obj, desc, unshared);
} else if (obj instanceof Serializable) {
if (cl.isValue() && !desc.isInstantiable()) {
throw new NotSerializableException(cl.getName());
}
writeOrdinaryObject(obj, desc, unshared);
} else {
if (extendedDebugInfo) {
Expand Down Expand Up @@ -1456,8 +1488,8 @@ private void writeOrdinaryObject(Object obj,
if (desc.isRecord()) {
writeRecordData(obj, desc);
} else if (desc.isExternalizable() && !desc.isProxy()) {
if (desc.forClass().isValue())
throw new NotSerializableException("Externalizable not valid for value class "
if (desc.isValue())
throw new InvalidClassException("Externalizable not valid for value class "
+ desc.forClass().getName());
writeExternalData((Externalizable) obj);
} else {
Expand Down Expand Up @@ -1507,10 +1539,10 @@ private void writeRecordData(Object obj, ObjectStreamClass desc)
throws IOException
{
assert obj.getClass().isRecord();
ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
if (slots.length != 1) {
List<ObjectStreamClass.ClassDataSlot> slots = desc.getClassDataLayout();
if (slots.size() != 1) {
throw new InvalidClassException(
"expected a single record slot length, but found: " + slots.length);
"expected a single record slot length, but found: " + slots.size());
}

defaultWriteFields(obj, desc); // #### seems unnecessary to use the accessors
Expand All @@ -1523,9 +1555,9 @@ private void writeRecordData(Object obj, ObjectStreamClass desc)
private void writeSerialData(Object obj, ObjectStreamClass desc)
throws IOException
{
ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
for (int i = 0; i < slots.length; i++) {
ObjectStreamClass slotDesc = slots[i].desc;
List<ObjectStreamClass.ClassDataSlot> slots = desc.getClassDataLayout();
for (int i = 0; i < slots.size(); i++) {
ObjectStreamClass slotDesc = slots.get(i).desc;
if (slotDesc.hasWriteObjectMethod()) {
PutFieldImpl oldPut = curPut;
curPut = null;
Expand Down
Loading

0 comments on commit e02c628

Please sign in to comment.