24
24
/*
25
25
* @test
26
26
* @summary Checks that the appropriate value is given to the canonical ctr
27
+ * @library /test/lib
27
28
* @compile --enable-preview -source ${jdk.version} DifferentStreamFieldsTest.java
28
29
* @run testng/othervm --enable-preview DifferentStreamFieldsTest
29
30
* @run testng/othervm/java.security.policy=empty_security.policy --enable-preview DifferentStreamFieldsTest
30
31
*/
31
32
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
-
46
33
import java .io .ByteArrayInputStream ;
47
34
import java .io .ByteArrayOutputStream ;
48
- import java .io .DataOutputStream ;
49
35
import java .io .IOException ;
50
36
import java .io .InvalidClassException ;
51
37
import java .io .InvalidObjectException ;
52
38
import java .io .ObjectInputStream ;
53
39
import java .io .ObjectOutputStream ;
54
40
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 ;
58
46
59
47
/**
60
48
* Checks that the appropriate value is given to the canonical ctr.
@@ -114,7 +102,7 @@ public void testWithDifferentTypes(Class<?> clazz, Object expectedXValue)
114
102
throws Exception {
115
103
out .println ("\n ---" );
116
104
assert clazz .isRecord ();
117
- byte [] bytes = SerialByteStreamBuilder
105
+ byte [] bytes = SerialObjectBuilder
118
106
.newBuilder (clazz .getName ())
119
107
.build ();
120
108
@@ -123,7 +111,7 @@ public void testWithDifferentTypes(Class<?> clazz, Object expectedXValue)
123
111
Object actualXValue = clazz .getDeclaredMethod ("x" ).invoke (obj );
124
112
assertEquals (actualXValue , expectedXValue );
125
113
126
- bytes = SerialByteStreamBuilder
114
+ bytes = SerialObjectBuilder
127
115
.newBuilder (clazz .getName ())
128
116
.addPrimitiveField ("y" , int .class , 5 ) // stream junk
129
117
.build ();
@@ -143,7 +131,7 @@ record R15(boolean a, byte b, short c, char d, int e, long f, float g,
143
131
double h , Object i , String j , long []k , Object []l )
144
132
implements Serializable {}
145
133
146
- byte [] bytes = SerialByteStreamBuilder
134
+ byte [] bytes = SerialObjectBuilder
147
135
.newBuilder (R15 .class .getName ())
148
136
.addPrimitiveField ("x" , int .class , 5 ) // stream junk
149
137
.build ();
@@ -173,7 +161,7 @@ record R(int x) implements Serializable {}
173
161
var r = new R (5 );
174
162
byte [] OOSBytes = serialize (r );
175
163
176
- byte [] builderBytes = SerialByteStreamBuilder
164
+ byte [] builderBytes = SerialObjectBuilder
177
165
.newBuilder (R .class .getName ())
178
166
.addPrimitiveField ("x" , int .class , 5 )
179
167
.build ();
@@ -191,7 +179,7 @@ record R(int x, int y) implements Serializable {}
191
179
var deser1 = deserialize (OOSBytes );
192
180
assertEquals (deser1 , r );
193
181
194
- byte [] builderBytes = SerialByteStreamBuilder
182
+ byte [] builderBytes = SerialObjectBuilder
195
183
.newBuilder (R .class .getName ())
196
184
.addPrimitiveField ("x" , int .class , 7 )
197
185
.addPrimitiveField ("y" , int .class , 8 )
@@ -200,15 +188,15 @@ record R(int x, int y) implements Serializable {}
200
188
var deser2 = deserialize (builderBytes );
201
189
assertEquals (deser2 , deser1 );
202
190
203
- builderBytes = SerialByteStreamBuilder
191
+ builderBytes = SerialObjectBuilder
204
192
.newBuilder (R .class .getName ())
205
193
.addPrimitiveField ("y" , int .class , 8 ) // reverse order
206
194
.addPrimitiveField ("x" , int .class , 7 )
207
195
.build ();
208
196
deser2 = deserialize (builderBytes );
209
197
assertEquals (deser2 , deser1 );
210
198
211
- builderBytes = SerialByteStreamBuilder
199
+ builderBytes = SerialObjectBuilder
212
200
.newBuilder (R .class .getName ())
213
201
.addPrimitiveField ("w" , int .class , 6 ) // additional fields
214
202
.addPrimitiveField ("x" , int .class , 7 )
@@ -223,15 +211,15 @@ record R(int x, int y) implements Serializable {}
223
211
deser1 = deserialize (OOSBytes );
224
212
assertEquals (deser1 , r );
225
213
226
- builderBytes = SerialByteStreamBuilder
214
+ builderBytes = SerialObjectBuilder
227
215
.newBuilder (R .class .getName ())
228
216
.addPrimitiveField ("y" , int .class , 0 )
229
217
.addPrimitiveField ("x" , int .class , 0 )
230
218
.build ();
231
219
deser2 = deserialize (builderBytes );
232
220
assertEquals (deser2 , deser1 );
233
221
234
- builderBytes = SerialByteStreamBuilder
222
+ builderBytes = SerialObjectBuilder
235
223
.newBuilder (R .class .getName ()) // no field values
236
224
.build ();
237
225
deser2 = deserialize (builderBytes );
@@ -249,7 +237,7 @@ record Str(String part1, String part2) implements Serializable {}
249
237
var deser1 = deserialize (serialize (r ));
250
238
assertEquals (deser1 , r );
251
239
252
- byte [] builderBytes = SerialByteStreamBuilder
240
+ byte [] builderBytes = SerialObjectBuilder
253
241
.newBuilder (Str .class .getName ())
254
242
.addField ("part1" , String .class , "Hello" )
255
243
.addField ("part2" , String .class , "World!" )
@@ -258,7 +246,7 @@ record Str(String part1, String part2) implements Serializable {}
258
246
var deser2 = deserialize (builderBytes );
259
247
assertEquals (deser2 , deser1 );
260
248
261
- builderBytes = SerialByteStreamBuilder
249
+ builderBytes = SerialObjectBuilder
262
250
.newBuilder (Str .class .getName ())
263
251
.addField ("cruft" , String .class , "gg" )
264
252
.addField ("part1" , String .class , "Hello" )
@@ -280,7 +268,7 @@ record IntArray(int[]ints, long[]longs) implements Serializable {}
280
268
assertEquals (deser1 .ints (), r .ints ());
281
269
assertEquals (deser1 .longs (), r .longs ());
282
270
283
- byte [] builderBytes = SerialByteStreamBuilder
271
+ byte [] builderBytes = SerialObjectBuilder
284
272
.newBuilder (IntArray .class .getName ())
285
273
.addField ("ints" , int [].class , new int []{5 , 4 , 3 , 2 , 1 })
286
274
.addField ("longs" , long [].class , new long []{9L })
@@ -296,7 +284,7 @@ record StrArray(String[]stringArray) implements Serializable {}
296
284
StrArray deser1 = deserialize (serialize (r ));
297
285
assertEquals (deser1 .stringArray (), r .stringArray ());
298
286
299
- byte [] builderBytes = SerialByteStreamBuilder
287
+ byte [] builderBytes = SerialObjectBuilder
300
288
.newBuilder (StrArray .class .getName ())
301
289
.addField ("stringArray" , String [].class , new String []{"foo" , "bar" })
302
290
.build ();
@@ -317,7 +305,7 @@ record NumberHolder(Number n) implements Serializable {}
317
305
var deser1 = deserialize (serialize (r ));
318
306
assertEquals (deser1 , r );
319
307
320
- byte [] builderBytes = SerialByteStreamBuilder
308
+ byte [] builderBytes = SerialObjectBuilder
321
309
.newBuilder (NumberHolder .class .getName ())
322
310
.addField ("n" , Integer .class , 123 )
323
311
.build ();
@@ -333,7 +321,7 @@ record IntegerHolder(Integer i) implements Serializable {}
333
321
var deser1 = deserialize (serialize (r ));
334
322
assertEquals (deser1 , r );
335
323
336
- byte [] builderBytes = SerialByteStreamBuilder
324
+ byte [] builderBytes = SerialObjectBuilder
337
325
.newBuilder (IntegerHolder .class .getName ())
338
326
.addField ("i" , Number .class , 123 )
339
327
.build ();
@@ -353,7 +341,7 @@ record StringHolder(String s) implements Serializable {}
353
341
var deser1 = deserialize (serialize (r ));
354
342
assertEquals (deser1 , r );
355
343
356
- byte [] builderBytes = SerialByteStreamBuilder
344
+ byte [] builderBytes = SerialObjectBuilder
357
345
.newBuilder (StringHolder .class .getName ())
358
346
.addField ("s" , Integer .class , 123 )
359
347
.build ();
@@ -377,7 +365,7 @@ record IntHolder(int i) implements Serializable {}
377
365
var deser1 = deserialize (serialize (r ));
378
366
assertEquals (deser1 , r );
379
367
380
- byte [] builderBytes = SerialByteStreamBuilder
368
+ byte [] builderBytes = SerialObjectBuilder
381
369
.newBuilder (IntHolder .class .getName ())
382
370
.addPrimitiveField ("i" , long .class , 123L )
383
371
.build ();
@@ -406,158 +394,4 @@ static <T> T deserialize(byte[] streamBytes)
406
394
ObjectInputStream ois = new ObjectInputStream (bais );
407
395
return (T ) ois .readObject ();
408
396
}
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
- }
563
397
}
0 commit comments