@@ -155,8 +155,8 @@ private static void registerLambdasFromConstantNodesInGraph(StructuredGraph grap
155155
156156 if (lambdaClass != null && Serializable .class .isAssignableFrom (lambdaClass )) {
157157 RuntimeReflection .register (ReflectionUtil .lookupMethod (lambdaClass , "writeReplace" ));
158- SerializationBuilder .registerSerializationUIDElements (lambdaClass , false );
159- serializationBuilder .serializationSupport .registerSerializationTargetClass (AccessCondition .unconditional (), serializationBuilder .getHostVM ().dynamicHub (lambdaClass ));
158+ SerializationBuilder .registerSerializationUIDElements (lambdaClass , false , false );
159+ serializationBuilder .serializationSupport .registerSerializationTargetClass (AccessCondition .unconditional (), serializationBuilder .getHostVM ().dynamicHub (lambdaClass ), false );
160160 }
161161 }
162162 }
@@ -423,10 +423,10 @@ public void register(AccessCondition condition, boolean preserved, Class<?> seri
423423 * Making this class reachable as it will end up in the image heap without the analysis
424424 * knowing.
425425 */
426- RuntimeReflection . register (java .io .ObjectOutputStream .class );
426+ ImageSingletons . lookup ( RuntimeReflectionSupport . class ). register (AccessCondition . unconditional (), false , preserved , java .io .ObjectOutputStream .class );
427427
428428 if (denyRegistry .isAllowed (serializationTargetClass )) {
429- addOrQueueConstructorAccessors (cnd , serializationTargetClass , getHostVM ().dynamicHub (serializationTargetClass ));
429+ addOrQueueConstructorAccessors (cnd , serializationTargetClass , getHostVM ().dynamicHub (serializationTargetClass ), preserved );
430430
431431 Class <?> superclass = serializationTargetClass .getSuperclass ();
432432 if (superclass != null ) {
@@ -435,35 +435,35 @@ public void register(AccessCondition condition, boolean preserved, Class<?> seri
435435 ImageSingletons .lookup (RuntimeReflectionSupport .class ).registerMethodLookup (AccessCondition .unconditional (), preserved , superclass , "readResolve" );
436436 }
437437
438- registerForSerialization (cnd , serializationTargetClass );
439- registerForDeserialization (cnd , serializationTargetClass );
438+ registerForSerialization (cnd , preserved , serializationTargetClass );
439+ registerForDeserialization (cnd , preserved , serializationTargetClass );
440440
441441 }
442442 });
443443 }
444444
445- private void addOrQueueConstructorAccessors (AccessCondition cnd , Class <?> serializationTargetClass , DynamicHub hub ) {
445+ private void addOrQueueConstructorAccessors (AccessCondition cnd , Class <?> serializationTargetClass , DynamicHub hub , boolean preserved ) {
446446 if (pendingConstructorRegistrations != null ) {
447447 // cannot yet create constructor accessor -> add to pending
448- pendingConstructorRegistrations .add (() -> registerConstructorAccessors (cnd , serializationTargetClass , hub ));
448+ pendingConstructorRegistrations .add (() -> registerConstructorAccessors (cnd , serializationTargetClass , hub , preserved ));
449449 } else {
450450 // can already run the registration
451- registerConstructorAccessors (cnd , serializationTargetClass , hub );
451+ registerConstructorAccessors (cnd , serializationTargetClass , hub , preserved );
452452 }
453453 }
454454
455- private void registerConstructorAccessors (AccessCondition cnd , Class <?> serializationTargetClass , DynamicHub hub ) {
456- serializationSupport .registerSerializationTargetClass (cnd , hub );
457- registerConstructorAccessor (cnd , serializationTargetClass , null );
455+ private void registerConstructorAccessors (AccessCondition cnd , Class <?> serializationTargetClass , DynamicHub hub , boolean preserved ) {
456+ serializationSupport .registerSerializationTargetClass (cnd , hub , preserved );
457+ registerConstructorAccessor (cnd , serializationTargetClass , null , preserved );
458458 for (Class <?> superclass = serializationTargetClass ; superclass != null ; superclass = superclass .getSuperclass ()) {
459- registerConstructorAccessor (cnd , serializationTargetClass , superclass );
459+ registerConstructorAccessor (cnd , serializationTargetClass , superclass , preserved );
460460 }
461461 }
462462
463- private void registerConstructorAccessor (AccessCondition cnd , Class <?> serializationTargetClass , Class <?> targetConstructorClass ) {
463+ private void registerConstructorAccessor (AccessCondition cnd , Class <?> serializationTargetClass , Class <?> targetConstructorClass , boolean preserved ) {
464464 Optional .ofNullable (addConstructorAccessor (serializationTargetClass , targetConstructorClass ))
465465 .map (ReflectionUtil ::lookupConstructor )
466- .ifPresent (methods -> ImageSingletons .lookup (RuntimeReflectionSupport .class ).register (cnd , false , false , methods ));
466+ .ifPresent (methods -> ImageSingletons .lookup (RuntimeReflectionSupport .class ).register (cnd , false , preserved , methods ));
467467 }
468468
469469 void beforeAnalysis (Feature .BeforeAnalysisAccess beforeAnalysisAccess ) {
@@ -474,37 +474,37 @@ void beforeAnalysis(Feature.BeforeAnalysisAccess beforeAnalysisAccess) {
474474 serializationSupport .setStubConstructor (stubConstructor );
475475 }
476476
477- private static void registerQueriesForInheritableMethod (Class <?> clazz , String methodName , Class <?>... args ) {
477+ private static void registerQueriesForInheritableMethod (boolean preserved , Class <?> clazz , String methodName , Class <?>... args ) {
478478 Class <?> iter = clazz ;
479479 while (iter != null ) {
480- RuntimeReflection . registerMethodLookup (iter , methodName , args );
480+ ImageSingletons . lookup ( RuntimeReflectionSupport . class ). registerMethodLookup (AccessCondition . unconditional (), preserved , iter , methodName , args );
481481 Method method = ReflectionUtil .lookupMethod (true , clazz , methodName , args );
482482 if (method != null ) {
483- RuntimeReflection . register ( method );
483+ registerMethod ( AccessCondition . unconditional (), preserved , clazz , methodName , args );
484484 break ;
485485 }
486486 iter = iter .getSuperclass ();
487487 }
488488 }
489489
490- private static void registerMethod (AccessCondition cnd , Class <?> clazz , String methodName , Class <?>... args ) {
490+ private static void registerMethod (AccessCondition cnd , boolean preserved , Class <?> clazz , String methodName , Class <?>... args ) {
491491 Method method = ReflectionUtil .lookupMethod (true , clazz , methodName , args );
492492 if (method != null ) {
493- ImageSingletons .lookup (RuntimeReflectionSupport .class ).register (cnd , false , false , method );
493+ ImageSingletons .lookup (RuntimeReflectionSupport .class ).register (cnd , false , preserved , method );
494494 } else {
495- RuntimeReflection . registerMethodLookup (clazz , methodName , args );
495+ ImageSingletons . lookup ( RuntimeReflectionSupport . class ). registerMethodLookup (AccessCondition . unconditional (), preserved , clazz , methodName , args );
496496 }
497497 }
498498
499- private void registerForSerialization (AccessCondition cnd , Class <?> serializationTargetClass ) {
499+ private void registerForSerialization (AccessCondition cnd , boolean preserved , Class <?> serializationTargetClass ) {
500500
501501 if (Serializable .class .isAssignableFrom (serializationTargetClass )) {
502502 /*
503503 * ObjectStreamClass.computeDefaultSUID is always called at runtime to verify
504504 * serialization class consistency, so need to register all constructors, methods and
505505 * fields.
506506 */
507- registerSerializationUIDElements (serializationTargetClass , true ); // if MRE
507+ registerSerializationUIDElements (serializationTargetClass , true , preserved ); // if MRE
508508
509509 /*
510510 * Required by jdk.internal.reflect.ReflectionFactory.newConstructorForSerialization
@@ -513,7 +513,7 @@ private void registerForSerialization(AccessCondition cnd, Class<?> serializatio
513513 boolean initClValid = true ;
514514 while (Serializable .class .isAssignableFrom (initCl )) {
515515 Class <?> prev = initCl ;
516- RuntimeReflection . registerAllDeclaredConstructors (initCl );
516+ registerAllDeclaredConstructors (preserved , initCl );
517517 if ((initCl = initCl .getSuperclass ()) == null || (!disableSerialConstructorChecks () &&
518518 !prev .isArray () && !superHasAccessibleConstructor (prev ))) {
519519 initClValid = false ;
@@ -522,18 +522,18 @@ private void registerForSerialization(AccessCondition cnd, Class<?> serializatio
522522 }
523523
524524 if (initClValid ) {
525- RuntimeReflection . registerAllDeclaredConstructors (initCl );
525+ registerAllDeclaredConstructors (preserved , initCl );
526526 }
527527
528528 Class <?> iter = serializationTargetClass ;
529529 while (iter != null ) {
530- RuntimeReflection . registerAllDeclaredFields (iter );
530+ registerAllDeclaredFields (preserved , iter );
531531 try {
532532 Arrays .stream (iter .getDeclaredFields ())
533533 .map (Field ::getType ).forEach (type -> {
534- RuntimeReflection . registerAllDeclaredMethods (type );
535- RuntimeReflection . registerAllDeclaredFields (type );
536- RuntimeReflection . registerAllDeclaredConstructors (type );
534+ registerAllDeclaredMethods (preserved , type );
535+ registerAllDeclaredFields (preserved , type );
536+ registerAllDeclaredConstructors (preserved , type );
537537 });
538538 } catch (LinkageError l ) {
539539 /* Handled with registration above */
@@ -542,37 +542,49 @@ private void registerForSerialization(AccessCondition cnd, Class<?> serializatio
542542 }
543543 }
544544
545- registerQueriesForInheritableMethod (serializationTargetClass , "writeReplace" );
546- registerQueriesForInheritableMethod (serializationTargetClass , "readResolve" );
547- registerMethod (cnd , serializationTargetClass , "writeObject" , ObjectOutputStream .class );
548- registerMethod (cnd , serializationTargetClass , "readObjectNoData" );
549- registerMethod (cnd , serializationTargetClass , "readObject" , ObjectInputStream .class );
545+ registerQueriesForInheritableMethod (preserved , serializationTargetClass , "writeReplace" );
546+ registerQueriesForInheritableMethod (preserved , serializationTargetClass , "readResolve" );
547+ registerMethod (cnd , preserved , serializationTargetClass , "writeObject" , ObjectOutputStream .class );
548+ registerMethod (cnd , preserved , serializationTargetClass , "readObjectNoData" );
549+ registerMethod (cnd , preserved , serializationTargetClass , "readObject" , ObjectInputStream .class );
550550 }
551551
552552 @ SuppressWarnings ("unused" )
553- static void registerSerializationUIDElements (Class <?> serializationTargetClass , boolean fullyRegister ) {
554- RuntimeReflection . registerAllDeclaredConstructors (serializationTargetClass );
555- RuntimeReflection . registerAllDeclaredMethods (serializationTargetClass );
556- RuntimeReflection . registerAllDeclaredFields (serializationTargetClass );
553+ static void registerSerializationUIDElements (Class <?> serializationTargetClass , boolean fullyRegister , boolean preserved ) {
554+ registerAllDeclaredConstructors (preserved , serializationTargetClass );
555+ registerAllDeclaredMethods (preserved , serializationTargetClass );
556+ registerAllDeclaredFields (preserved , serializationTargetClass );
557557 if (fullyRegister ) {
558558 try {
559559 /* This is here a legacy that we can't remove as it is a breaking change */
560- RuntimeReflection . register (serializationTargetClass .getDeclaredConstructors ());
561- RuntimeReflection . register (serializationTargetClass .getDeclaredMethods ());
562- RuntimeReflection . register (serializationTargetClass .getDeclaredFields ());
560+ ImageSingletons . lookup ( RuntimeReflectionSupport . class ). register (AccessCondition . unconditional (), false , preserved , serializationTargetClass .getDeclaredConstructors ());
561+ ImageSingletons . lookup ( RuntimeReflectionSupport . class ). register (AccessCondition . unconditional (), false , preserved , serializationTargetClass .getDeclaredMethods ());
562+ ImageSingletons . lookup ( RuntimeReflectionSupport . class ). register (AccessCondition . unconditional (), false , preserved , serializationTargetClass .getDeclaredFields ());
563563 } catch (LinkageError e ) {
564564 /* Handled by registrations above */
565565 }
566566 }
567- RuntimeReflection .registerFieldLookup (serializationTargetClass , "serialPersistentFields" );
567+ ImageSingletons .lookup (RuntimeReflectionSupport .class ).registerFieldLookup (AccessCondition .unconditional (), preserved , serializationTargetClass , "serialPersistentFields" );
568+ }
569+
570+ static void registerAllDeclaredConstructors (boolean preserved , Class <?> declaringClass ) {
571+ ImageSingletons .lookup (RuntimeReflectionSupport .class ).registerAllDeclaredConstructorsQuery (AccessCondition .unconditional (), true , preserved , declaringClass );
572+ }
573+
574+ static void registerAllDeclaredMethods (boolean preserved , Class <?> declaringClass ) {
575+ ImageSingletons .lookup (RuntimeReflectionSupport .class ).registerAllDeclaredMethodsQuery (AccessCondition .unconditional (), true , preserved , declaringClass );
576+ }
577+
578+ static void registerAllDeclaredFields (boolean preserved , Class <?> declaringClass ) {
579+ ImageSingletons .lookup (RuntimeReflectionSupport .class ).registerAllDeclaredFields (AccessCondition .unconditional (), preserved , declaringClass );
568580 }
569581
570582 public void afterAnalysis () {
571583 sealed ();
572584 }
573585
574- private static void registerForDeserialization (AccessCondition cnd , Class <?> serializationTargetClass ) {
575- ImageSingletons .lookup (RuntimeReflectionSupport .class ).register (cnd , serializationTargetClass );
586+ private static void registerForDeserialization (AccessCondition cnd , boolean preserved , Class <?> serializationTargetClass ) {
587+ ImageSingletons .lookup (RuntimeReflectionSupport .class ).register (cnd , false , preserved , serializationTargetClass );
576588
577589 if (serializationTargetClass .isRecord ()) {
578590 /*
@@ -584,20 +596,20 @@ private static void registerForDeserialization(AccessCondition cnd, Class<?> ser
584596 try {
585597 /* Serialization for records uses the canonical record constructor directly. */
586598 Executable [] methods = new Executable []{RecordUtils .getCanonicalRecordConstructor (serializationTargetClass )};
587- ImageSingletons .lookup (RuntimeReflectionSupport .class ).register (cnd , false , false , methods );
599+ ImageSingletons .lookup (RuntimeReflectionSupport .class ).register (cnd , false , preserved , methods );
588600 Executable [] methods1 = RecordUtils .getRecordComponentAccessorMethods (serializationTargetClass );
589- ImageSingletons .lookup (RuntimeReflectionSupport .class ).register (cnd , false , false , methods1 );
601+ ImageSingletons .lookup (RuntimeReflectionSupport .class ).register (cnd , false , preserved , methods1 );
590602 } catch (LinkageError le ) {
591603 /*
592604 * Handled by the record component registration above.
593605 */
594606 }
595607 } else if (Externalizable .class .isAssignableFrom (serializationTargetClass )) {
596- RuntimeReflection . registerConstructorLookup (serializationTargetClass );
608+ ImageSingletons . lookup ( RuntimeReflectionSupport . class ). registerConstructorLookup (AccessCondition . unconditional (), preserved , serializationTargetClass );
597609 }
598610
599- registerMethod (cnd , serializationTargetClass , "readObject" , ObjectInputStream .class );
600- registerMethod (cnd , serializationTargetClass , "readResolve" );
611+ registerMethod (cnd , preserved , serializationTargetClass , "readObject" , ObjectInputStream .class );
612+ registerMethod (cnd , preserved , serializationTargetClass , "readResolve" );
601613 }
602614
603615 private Constructor <?> newConstructorForSerialization (Class <?> serializationTargetClass , Constructor <?> customConstructorToCall ) {
0 commit comments