Skip to content

Commit aad3cf4

Browse files
committedOct 12, 2020
8254234: Add test library stream object builder
Reviewed-by: rriggs
1 parent 4184959 commit aad3cf4

File tree

2 files changed

+229
-189
lines changed

2 files changed

+229
-189
lines changed
 

‎test/jdk/java/io/Serializable/records/DifferentStreamFieldsTest.java

+23-189
Original file line numberDiff line numberDiff line change
@@ -24,37 +24,25 @@
2424
/*
2525
* @test
2626
* @summary Checks that the appropriate value is given to the canonical ctr
27+
* @library /test/lib
2728
* @compile --enable-preview -source ${jdk.version} DifferentStreamFieldsTest.java
2829
* @run testng/othervm --enable-preview DifferentStreamFieldsTest
2930
* @run testng/othervm/java.security.policy=empty_security.policy --enable-preview DifferentStreamFieldsTest
3031
*/
3132

32-
import org.testng.annotations.DataProvider;
33-
import org.testng.annotations.Test;
34-
35-
import static java.io.ObjectStreamConstants.SC_SERIALIZABLE;
36-
import static java.io.ObjectStreamConstants.STREAM_MAGIC;
37-
import static java.io.ObjectStreamConstants.STREAM_VERSION;
38-
import static java.io.ObjectStreamConstants.TC_CLASSDESC;
39-
import static java.io.ObjectStreamConstants.TC_ENDBLOCKDATA;
40-
import static java.io.ObjectStreamConstants.TC_NULL;
41-
import static java.io.ObjectStreamConstants.TC_OBJECT;
42-
import static java.io.ObjectStreamConstants.TC_STRING;
43-
import static java.lang.System.out;
44-
import static org.testng.Assert.assertEquals;
45-
4633
import java.io.ByteArrayInputStream;
4734
import java.io.ByteArrayOutputStream;
48-
import java.io.DataOutputStream;
4935
import java.io.IOException;
5036
import java.io.InvalidClassException;
5137
import java.io.InvalidObjectException;
5238
import java.io.ObjectInputStream;
5339
import java.io.ObjectOutputStream;
5440
import java.io.Serializable;
55-
import java.io.UncheckedIOException;
56-
import java.util.LinkedHashMap;
57-
import java.util.Map;
41+
import jdk.test.lib.serial.SerialObjectBuilder;
42+
import org.testng.annotations.DataProvider;
43+
import org.testng.annotations.Test;
44+
import static java.lang.System.out;
45+
import static org.testng.Assert.assertEquals;
5846

5947
/**
6048
* Checks that the appropriate value is given to the canonical ctr.
@@ -114,7 +102,7 @@ public void testWithDifferentTypes(Class<?> clazz, Object expectedXValue)
114102
throws Exception {
115103
out.println("\n---");
116104
assert clazz.isRecord();
117-
byte[] bytes = SerialByteStreamBuilder
105+
byte[] bytes = SerialObjectBuilder
118106
.newBuilder(clazz.getName())
119107
.build();
120108

@@ -123,7 +111,7 @@ public void testWithDifferentTypes(Class<?> clazz, Object expectedXValue)
123111
Object actualXValue = clazz.getDeclaredMethod("x").invoke(obj);
124112
assertEquals(actualXValue, expectedXValue);
125113

126-
bytes = SerialByteStreamBuilder
114+
bytes = SerialObjectBuilder
127115
.newBuilder(clazz.getName())
128116
.addPrimitiveField("y", int.class, 5) // stream junk
129117
.build();
@@ -143,7 +131,7 @@ record R15(boolean a, byte b, short c, char d, int e, long f, float g,
143131
double h, Object i, String j, long[]k, Object[]l)
144132
implements Serializable {}
145133

146-
byte[] bytes = SerialByteStreamBuilder
134+
byte[] bytes = SerialObjectBuilder
147135
.newBuilder(R15.class.getName())
148136
.addPrimitiveField("x", int.class, 5) // stream junk
149137
.build();
@@ -173,7 +161,7 @@ record R(int x) implements Serializable {}
173161
var r = new R(5);
174162
byte[] OOSBytes = serialize(r);
175163

176-
byte[] builderBytes = SerialByteStreamBuilder
164+
byte[] builderBytes = SerialObjectBuilder
177165
.newBuilder(R.class.getName())
178166
.addPrimitiveField("x", int.class, 5)
179167
.build();
@@ -191,7 +179,7 @@ record R(int x, int y) implements Serializable {}
191179
var deser1 = deserialize(OOSBytes);
192180
assertEquals(deser1, r);
193181

194-
byte[] builderBytes = SerialByteStreamBuilder
182+
byte[] builderBytes = SerialObjectBuilder
195183
.newBuilder(R.class.getName())
196184
.addPrimitiveField("x", int.class, 7)
197185
.addPrimitiveField("y", int.class, 8)
@@ -200,15 +188,15 @@ record R(int x, int y) implements Serializable {}
200188
var deser2 = deserialize(builderBytes);
201189
assertEquals(deser2, deser1);
202190

203-
builderBytes = SerialByteStreamBuilder
191+
builderBytes = SerialObjectBuilder
204192
.newBuilder(R.class.getName())
205193
.addPrimitiveField("y", int.class, 8) // reverse order
206194
.addPrimitiveField("x", int.class, 7)
207195
.build();
208196
deser2 = deserialize(builderBytes);
209197
assertEquals(deser2, deser1);
210198

211-
builderBytes = SerialByteStreamBuilder
199+
builderBytes = SerialObjectBuilder
212200
.newBuilder(R.class.getName())
213201
.addPrimitiveField("w", int.class, 6) // additional fields
214202
.addPrimitiveField("x", int.class, 7)
@@ -223,15 +211,15 @@ record R(int x, int y) implements Serializable {}
223211
deser1 = deserialize(OOSBytes);
224212
assertEquals(deser1, r);
225213

226-
builderBytes = SerialByteStreamBuilder
214+
builderBytes = SerialObjectBuilder
227215
.newBuilder(R.class.getName())
228216
.addPrimitiveField("y", int.class, 0)
229217
.addPrimitiveField("x", int.class, 0)
230218
.build();
231219
deser2 = deserialize(builderBytes);
232220
assertEquals(deser2, deser1);
233221

234-
builderBytes = SerialByteStreamBuilder
222+
builderBytes = SerialObjectBuilder
235223
.newBuilder(R.class.getName()) // no field values
236224
.build();
237225
deser2 = deserialize(builderBytes);
@@ -249,7 +237,7 @@ record Str(String part1, String part2) implements Serializable {}
249237
var deser1 = deserialize(serialize(r));
250238
assertEquals(deser1, r);
251239

252-
byte[] builderBytes = SerialByteStreamBuilder
240+
byte[] builderBytes = SerialObjectBuilder
253241
.newBuilder(Str.class.getName())
254242
.addField("part1", String.class, "Hello")
255243
.addField("part2", String.class, "World!")
@@ -258,7 +246,7 @@ record Str(String part1, String part2) implements Serializable {}
258246
var deser2 = deserialize(builderBytes);
259247
assertEquals(deser2, deser1);
260248

261-
builderBytes = SerialByteStreamBuilder
249+
builderBytes = SerialObjectBuilder
262250
.newBuilder(Str.class.getName())
263251
.addField("cruft", String.class, "gg")
264252
.addField("part1", String.class, "Hello")
@@ -280,7 +268,7 @@ record IntArray(int[]ints, long[]longs) implements Serializable {}
280268
assertEquals(deser1.ints(), r.ints());
281269
assertEquals(deser1.longs(), r.longs());
282270

283-
byte[] builderBytes = SerialByteStreamBuilder
271+
byte[] builderBytes = SerialObjectBuilder
284272
.newBuilder(IntArray.class.getName())
285273
.addField("ints", int[].class, new int[]{5, 4, 3, 2, 1})
286274
.addField("longs", long[].class, new long[]{9L})
@@ -296,7 +284,7 @@ record StrArray(String[]stringArray) implements Serializable {}
296284
StrArray deser1 = deserialize(serialize(r));
297285
assertEquals(deser1.stringArray(), r.stringArray());
298286

299-
byte[] builderBytes = SerialByteStreamBuilder
287+
byte[] builderBytes = SerialObjectBuilder
300288
.newBuilder(StrArray.class.getName())
301289
.addField("stringArray", String[].class, new String[]{"foo", "bar"})
302290
.build();
@@ -317,7 +305,7 @@ record NumberHolder(Number n) implements Serializable {}
317305
var deser1 = deserialize(serialize(r));
318306
assertEquals(deser1, r);
319307

320-
byte[] builderBytes = SerialByteStreamBuilder
308+
byte[] builderBytes = SerialObjectBuilder
321309
.newBuilder(NumberHolder.class.getName())
322310
.addField("n", Integer.class, 123)
323311
.build();
@@ -333,7 +321,7 @@ record IntegerHolder(Integer i) implements Serializable {}
333321
var deser1 = deserialize(serialize(r));
334322
assertEquals(deser1, r);
335323

336-
byte[] builderBytes = SerialByteStreamBuilder
324+
byte[] builderBytes = SerialObjectBuilder
337325
.newBuilder(IntegerHolder.class.getName())
338326
.addField("i", Number.class, 123)
339327
.build();
@@ -353,7 +341,7 @@ record StringHolder(String s) implements Serializable {}
353341
var deser1 = deserialize(serialize(r));
354342
assertEquals(deser1, r);
355343

356-
byte[] builderBytes = SerialByteStreamBuilder
344+
byte[] builderBytes = SerialObjectBuilder
357345
.newBuilder(StringHolder.class.getName())
358346
.addField("s", Integer.class, 123)
359347
.build();
@@ -377,7 +365,7 @@ record IntHolder(int i) implements Serializable {}
377365
var deser1 = deserialize(serialize(r));
378366
assertEquals(deser1, r);
379367

380-
byte[] builderBytes = SerialByteStreamBuilder
368+
byte[] builderBytes = SerialObjectBuilder
381369
.newBuilder(IntHolder.class.getName())
382370
.addPrimitiveField("i", long.class, 123L)
383371
.build();
@@ -406,158 +394,4 @@ static <T> T deserialize(byte[] streamBytes)
406394
ObjectInputStream ois = new ObjectInputStream(bais);
407395
return (T) ois.readObject();
408396
}
409-
410-
static class SerialByteStreamBuilder {
411-
412-
private final ObjectOutputStream objectOutputStream;
413-
private final ByteArrayOutputStream byteArrayOutputStream;
414-
415-
record NameAndType<T>(String name, Class<T>type) {}
416-
417-
private String className;
418-
private final LinkedHashMap<NameAndType<?>, Object> primFields = new LinkedHashMap<>();
419-
private final LinkedHashMap<NameAndType<?>, Object> objectFields = new LinkedHashMap<>();
420-
421-
private SerialByteStreamBuilder() {
422-
try {
423-
byteArrayOutputStream = new ByteArrayOutputStream();
424-
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
425-
} catch (IOException e) {
426-
throw new UncheckedIOException(e);
427-
}
428-
}
429-
430-
public static SerialByteStreamBuilder newBuilder(String className) {
431-
return (new SerialByteStreamBuilder()).className(className);
432-
}
433-
434-
private SerialByteStreamBuilder className(String className) {
435-
this.className = className;
436-
return this;
437-
}
438-
439-
public <T> SerialByteStreamBuilder addPrimitiveField(String name, Class<T> type, T value) {
440-
if (!type.isPrimitive())
441-
throw new IllegalArgumentException("Unexpected non-primitive field: " + type);
442-
primFields.put(new NameAndType<>(name, type), value);
443-
return this;
444-
}
445-
446-
public <T> SerialByteStreamBuilder addField(String name, Class<T> type, T value) {
447-
if (type.isPrimitive())
448-
throw new IllegalArgumentException("Unexpected primitive field: " + type);
449-
objectFields.put(new NameAndType<>(name, type), value);
450-
return this;
451-
}
452-
453-
private static int getPrimitiveSignature(Class<?> cl) {
454-
if (cl == Integer.TYPE) return 'I';
455-
else if (cl == Byte.TYPE) return 'B';
456-
else if (cl == Long.TYPE) return 'J';
457-
else if (cl == Float.TYPE) return 'F';
458-
else if (cl == Double.TYPE) return 'D';
459-
else if (cl == Short.TYPE) return 'S';
460-
else if (cl == Character.TYPE) return 'C';
461-
else if (cl == Boolean.TYPE) return 'Z';
462-
else throw new InternalError();
463-
}
464-
465-
private static void writeUTF(DataOutputStream out, String str) throws IOException {
466-
int utflen = str.length(); // assume ASCII
467-
assert utflen <= 0xFFFF;
468-
out.writeShort(utflen);
469-
out.writeBytes(str);
470-
}
471-
472-
private void writePrimFieldsDesc(DataOutputStream out) throws IOException {
473-
for (Map.Entry<NameAndType<?>, Object> entry : primFields.entrySet()) {
474-
assert entry.getKey().type() != void.class;
475-
out.writeByte(getPrimitiveSignature(entry.getKey().type())); // prim_typecode
476-
out.writeUTF(entry.getKey().name()); // fieldName
477-
}
478-
}
479-
480-
private void writePrimFieldsValues(DataOutputStream out) throws IOException {
481-
for (Map.Entry<NameAndType<?>, Object> entry : primFields.entrySet()) {
482-
Class<?> cl = entry.getKey().type();
483-
Object value = entry.getValue();
484-
if (cl == Integer.TYPE) out.writeInt((int) value);
485-
else if (cl == Byte.TYPE) out.writeByte((byte) value);
486-
else if (cl == Long.TYPE) out.writeLong((long) value);
487-
else if (cl == Float.TYPE) out.writeFloat((float) value);
488-
else if (cl == Double.TYPE) out.writeDouble((double) value);
489-
else if (cl == Short.TYPE) out.writeShort((short) value);
490-
else if (cl == Character.TYPE) out.writeChar((char) value);
491-
else if (cl == Boolean.TYPE) out.writeBoolean((boolean) value);
492-
else throw new InternalError();
493-
}
494-
}
495-
496-
private void writeObjectFieldDesc(DataOutputStream out) throws IOException {
497-
for (Map.Entry<NameAndType<?>, Object> entry : objectFields.entrySet()) {
498-
Class<?> cl = entry.getKey().type();
499-
assert !cl.isPrimitive();
500-
// obj_typecode
501-
if (cl.isArray()) {
502-
out.writeByte('[');
503-
} else {
504-
out.writeByte('L');
505-
}
506-
writeUTF(out, entry.getKey().name());
507-
out.writeByte(TC_STRING);
508-
writeUTF(out,
509-
(cl.isArray() ? cl.getName() : "L" + cl.getName() + ";")
510-
.replace('.', '/'));
511-
}
512-
}
513-
514-
private void writeObject(DataOutputStream out, Object value) throws IOException {
515-
objectOutputStream.reset();
516-
byteArrayOutputStream.reset();
517-
objectOutputStream.writeUnshared(value);
518-
out.write(byteArrayOutputStream.toByteArray());
519-
}
520-
521-
private void writeObjectFieldValues(DataOutputStream out) throws IOException {
522-
for (Map.Entry<NameAndType<?>, Object> entry : objectFields.entrySet()) {
523-
Class<?> cl = entry.getKey().type();
524-
assert !cl.isPrimitive();
525-
if (cl == String.class) {
526-
out.writeByte(TC_STRING);
527-
writeUTF(out, (String) entry.getValue());
528-
} else {
529-
writeObject(out, entry.getValue());
530-
}
531-
}
532-
}
533-
534-
private int numFields() {
535-
return primFields.size() + objectFields.size();
536-
}
537-
538-
public byte[] build() {
539-
try {
540-
ByteArrayOutputStream baos = new ByteArrayOutputStream();
541-
DataOutputStream dos = new DataOutputStream(baos);
542-
dos.writeShort(STREAM_MAGIC);
543-
dos.writeShort(STREAM_VERSION);
544-
dos.writeByte(TC_OBJECT);
545-
dos.writeByte(TC_CLASSDESC);
546-
dos.writeUTF(className);
547-
dos.writeLong(0L);
548-
dos.writeByte(SC_SERIALIZABLE);
549-
dos.writeShort(numFields()); // number of fields
550-
writePrimFieldsDesc(dos);
551-
writeObjectFieldDesc(dos);
552-
dos.writeByte(TC_ENDBLOCKDATA); // no annotations
553-
dos.writeByte(TC_NULL); // no superclasses
554-
writePrimFieldsValues(dos);
555-
writeObjectFieldValues(dos);
556-
dos.close();
557-
return baos.toByteArray();
558-
} catch (IOException unexpected) {
559-
throw new AssertionError(unexpected);
560-
}
561-
}
562-
}
563397
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
/*
2+
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package jdk.test.lib.serial;
25+
26+
import java.io.ByteArrayOutputStream;
27+
import java.io.DataOutputStream;
28+
import java.io.IOException;
29+
import java.io.ObjectOutputStream;
30+
import java.io.UncheckedIOException;
31+
import java.util.LinkedHashMap;
32+
import java.util.Map;
33+
import static java.io.ObjectStreamConstants.*;
34+
35+
/**
36+
* A basic builder of a serial object.
37+
*/
38+
public class SerialObjectBuilder {
39+
40+
private final ObjectOutputStream objectOutputStream;
41+
private final ByteArrayOutputStream byteArrayOutputStream;
42+
43+
private record NameAndType<T>(String name, Class<T>type) { }
44+
45+
private String className;
46+
private long suid;
47+
private SerialObjectBuilder superClass;
48+
private final LinkedHashMap<NameAndType<?>, Object> primFields = new LinkedHashMap<>();
49+
private final LinkedHashMap<NameAndType<?>, Object> objectFields = new LinkedHashMap<>();
50+
51+
private SerialObjectBuilder() {
52+
try {
53+
byteArrayOutputStream = new ByteArrayOutputStream();
54+
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
55+
} catch (IOException e) {
56+
throw new UncheckedIOException(e);
57+
}
58+
}
59+
60+
public static SerialObjectBuilder newBuilder(String className) {
61+
return (new SerialObjectBuilder()).className(className);
62+
}
63+
64+
private SerialObjectBuilder className(String className) {
65+
this.className = className;
66+
return this;
67+
}
68+
69+
public SerialObjectBuilder suid(long suid) {
70+
this.suid = suid;
71+
return this;
72+
}
73+
74+
public SerialObjectBuilder superClass(SerialObjectBuilder superClass) {
75+
this.superClass = superClass;
76+
return this;
77+
}
78+
79+
public <T> SerialObjectBuilder addPrimitiveField(String name, Class<T> type, T value) {
80+
if (!type.isPrimitive())
81+
throw new IllegalArgumentException("Unexpected non-primitive field: " + type);
82+
primFields.put(new NameAndType<>(name, type), value);
83+
return this;
84+
}
85+
86+
public <T> SerialObjectBuilder addField(String name, Class<T> type, T value) {
87+
if (type.isPrimitive())
88+
throw new IllegalArgumentException("Unexpected primitive field: " + type);
89+
objectFields.put(new NameAndType<>(name, type), value);
90+
return this;
91+
}
92+
93+
private static void writeUTF(DataOutputStream out, String str) throws IOException {
94+
assert str.codePoints().noneMatch(cp -> cp > 127); // only ASCII for now
95+
int utflen = str.length();
96+
assert utflen <= 0xFFFF; // only small strings for now
97+
out.writeShort(utflen);
98+
out.writeBytes(str);
99+
}
100+
101+
private void writePrimFieldsDesc(DataOutputStream out) throws IOException {
102+
for (Map.Entry<NameAndType<?>, Object> entry : primFields.entrySet()) {
103+
Class<?> primClass = entry.getKey().type();
104+
assert primClass.isPrimitive();
105+
assert primClass != void.class;
106+
out.writeByte(primClass.descriptorString().getBytes()[0]); // prim_typecode
107+
out.writeUTF(entry.getKey().name()); // fieldName
108+
}
109+
}
110+
111+
private void writePrimFieldsValues(DataOutputStream out) throws IOException {
112+
for (Map.Entry<NameAndType<?>, Object> entry : primFields.entrySet()) {
113+
Class<?> cl = entry.getKey().type();
114+
Object value = entry.getValue();
115+
if (cl == Integer.TYPE) out.writeInt((int) value);
116+
else if (cl == Byte.TYPE) out.writeByte((byte) value);
117+
else if (cl == Long.TYPE) out.writeLong((long) value);
118+
else if (cl == Float.TYPE) out.writeFloat((float) value);
119+
else if (cl == Double.TYPE) out.writeDouble((double) value);
120+
else if (cl == Short.TYPE) out.writeShort((short) value);
121+
else if (cl == Character.TYPE) out.writeChar((char) value);
122+
else if (cl == Boolean.TYPE) out.writeBoolean((boolean) value);
123+
else throw new InternalError();
124+
}
125+
}
126+
127+
private void writeObjectFieldDesc(DataOutputStream out) throws IOException {
128+
for (Map.Entry<NameAndType<?>, Object> entry : objectFields.entrySet()) {
129+
Class<?> cl = entry.getKey().type();
130+
assert !cl.isPrimitive();
131+
// obj_typecode
132+
if (cl.isArray()) {
133+
out.writeByte('[');
134+
} else {
135+
out.writeByte('L');
136+
}
137+
writeUTF(out, entry.getKey().name());
138+
out.writeByte(TC_STRING);
139+
writeUTF(out, cl.descriptorString());
140+
}
141+
}
142+
143+
private void writeObject(DataOutputStream out, Object value) throws IOException {
144+
objectOutputStream.reset();
145+
byteArrayOutputStream.reset();
146+
objectOutputStream.writeUnshared(value);
147+
out.write(byteArrayOutputStream.toByteArray());
148+
}
149+
150+
private void writeObjectFieldValues(DataOutputStream out) throws IOException {
151+
for (Map.Entry<NameAndType<?>, Object> entry : objectFields.entrySet()) {
152+
Class<?> cl = entry.getKey().type();
153+
assert !cl.isPrimitive();
154+
if (cl == String.class) {
155+
out.writeByte(TC_STRING);
156+
writeUTF(out, (String) entry.getValue());
157+
} else {
158+
writeObject(out, entry.getValue());
159+
}
160+
}
161+
}
162+
163+
private int numFields() {
164+
return primFields.size() + objectFields.size();
165+
}
166+
167+
private static void writeClassDesc(DataOutputStream dos,
168+
SerialObjectBuilder sb)
169+
throws IOException
170+
{
171+
dos.writeByte(TC_CLASSDESC);
172+
dos.writeUTF(sb.className);
173+
dos.writeLong(sb.suid);
174+
dos.writeByte(SC_SERIALIZABLE);
175+
dos.writeShort(sb.numFields()); // number of fields
176+
sb.writePrimFieldsDesc(dos);
177+
sb.writeObjectFieldDesc(dos);
178+
dos.writeByte(TC_ENDBLOCKDATA); // no annotations
179+
if (sb.superClass == null) {
180+
dos.writeByte(TC_NULL); // no superclasses
181+
} else {
182+
writeClassDesc(dos, sb.superClass);
183+
}
184+
}
185+
186+
public byte[] build() {
187+
try {
188+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
189+
DataOutputStream dos = new DataOutputStream(baos);
190+
dos.writeShort(STREAM_MAGIC);
191+
dos.writeShort(STREAM_VERSION);
192+
dos.writeByte(TC_OBJECT);
193+
writeClassDesc(dos, this);
194+
if (superClass != null) {
195+
superClass.writePrimFieldsValues(dos);
196+
superClass.writeObjectFieldValues(dos);
197+
}
198+
writePrimFieldsValues(dos);
199+
writeObjectFieldValues(dos);
200+
dos.close();
201+
return baos.toByteArray();
202+
} catch (IOException unexpected) {
203+
throw new AssertionError(unexpected);
204+
}
205+
}
206+
}

0 commit comments

Comments
 (0)
Please sign in to comment.