@@ -154,6 +154,8 @@ class HibernateValidatorProcessor {
154
154
155
155
private static final DotName REPEATABLE = DotName .createSimple (Repeatable .class .getName ());
156
156
157
+ private static final DotName GRAALVM_FEATURE = DotName .createSimple ("org.graalvm.nativeimage.hosted.Feature" );
158
+
157
159
private static final Pattern BUILT_IN_CONSTRAINT_REPEATABLE_CONTAINER_PATTERN = Pattern .compile ("\\ $List$" );
158
160
159
161
@ BuildStep
@@ -498,12 +500,12 @@ public void build(
498
500
499
501
for (AnnotationInstance annotation : annotationInstances ) {
500
502
if (annotation .target ().kind () == AnnotationTarget .Kind .FIELD ) {
501
- contributeClass (classNamesToBeValidated , indexView , annotation .target ().asField ().declaringClass (). name () );
503
+ contributeClass (classNamesToBeValidated , indexView , annotation .target ().asField ().declaringClass ());
502
504
reflectiveFields .produce (new ReflectiveFieldBuildItem (getClass ().getName (), annotation .target ().asField ()));
503
505
contributeClassMarkedForCascadingValidation (classNamesToBeValidated , indexView , consideredAnnotation ,
504
506
annotation .target ().asField ().type ());
505
507
} else if (annotation .target ().kind () == AnnotationTarget .Kind .METHOD ) {
506
- contributeClass (classNamesToBeValidated , indexView , annotation .target ().asMethod ().declaringClass (). name () );
508
+ contributeClass (classNamesToBeValidated , indexView , annotation .target ().asMethod ().declaringClass ());
507
509
// we need to register the method for reflection as it could be a getter
508
510
reflectiveMethods
509
511
.produce (new ReflectiveMethodBuildItem (getClass ().getName (), annotation .target ().asMethod ()));
@@ -513,7 +515,7 @@ public void build(
513
515
annotation .target ().asMethod ());
514
516
} else if (annotation .target ().kind () == AnnotationTarget .Kind .METHOD_PARAMETER ) {
515
517
contributeClass (classNamesToBeValidated , indexView ,
516
- annotation .target ().asMethodParameter ().method ().declaringClass (). name () );
518
+ annotation .target ().asMethodParameter ().method ().declaringClass ());
517
519
// a getter does not have parameters so it's a pure method: no need for reflection in this case
518
520
contributeClassMarkedForCascadingValidation (classNamesToBeValidated , indexView , consideredAnnotation ,
519
521
// FIXME this won't work in the case of synthetic parameters
@@ -522,21 +524,21 @@ public void build(
522
524
contributeMethodsWithInheritedValidation (methodsWithInheritedValidation , indexView ,
523
525
annotation .target ().asMethodParameter ().method ());
524
526
} else if (annotation .target ().kind () == AnnotationTarget .Kind .CLASS ) {
525
- contributeClass (classNamesToBeValidated , indexView , annotation .target ().asClass (). name () );
527
+ contributeClass (classNamesToBeValidated , indexView , annotation .target ().asClass ());
526
528
// no need for reflection in the case of a class level constraint
527
529
} else if (annotation .target ().kind () == AnnotationTarget .Kind .TYPE ) {
528
530
// container element constraints
529
531
AnnotationTarget enclosingTarget = annotation .target ().asType ().enclosingTarget ();
530
532
if (enclosingTarget .kind () == AnnotationTarget .Kind .FIELD ) {
531
- contributeClass (classNamesToBeValidated , indexView , enclosingTarget .asField ().declaringClass (). name () );
533
+ contributeClass (classNamesToBeValidated , indexView , enclosingTarget .asField ().declaringClass ());
532
534
reflectiveFields .produce (new ReflectiveFieldBuildItem (getClass ().getName (), enclosingTarget .asField ()));
533
535
if (annotation .target ().asType ().target () != null ) {
534
536
contributeClassMarkedForCascadingValidation (classNamesToBeValidated , indexView ,
535
537
consideredAnnotation ,
536
538
annotation .target ().asType ().target ());
537
539
}
538
540
} else if (enclosingTarget .kind () == AnnotationTarget .Kind .METHOD ) {
539
- contributeClass (classNamesToBeValidated , indexView , enclosingTarget .asMethod ().declaringClass (). name () );
541
+ contributeClass (classNamesToBeValidated , indexView , enclosingTarget .asMethod ().declaringClass ());
540
542
reflectiveMethods
541
543
.produce (new ReflectiveMethodBuildItem (getClass ().getName (), enclosingTarget .asMethod ()));
542
544
if (annotation .target ().asType ().target () != null ) {
@@ -701,33 +703,72 @@ private static void contributeBuiltinConstraints(Set<String> builtinConstraints,
701
703
}
702
704
}
703
705
704
- private static void contributeClass (Set <DotName > classNamesCollector , IndexView indexView , DotName className ) {
705
- classNamesCollector .add (className );
706
+ private static void contributeClass (Set <DotName > classNamesCollector , IndexView indexView , ClassInfo classInfo ) {
707
+ if (isInGraalVMFeature (indexView , classInfo )) {
708
+ return ;
709
+ }
706
710
707
- if (DotNames .OBJECT .equals (className )) {
711
+ classNamesCollector .add (classInfo .name ());
712
+
713
+ if (DotNames .OBJECT .equals (classInfo .name ())) {
708
714
return ;
709
715
}
710
716
711
- for (ClassInfo subclass : indexView .getAllKnownSubclasses (className )) {
717
+ for (ClassInfo subclass : indexView .getAllKnownSubclasses (classInfo . name () )) {
712
718
if (Modifier .isAbstract (subclass .flags ())) {
713
719
// we can avoid adding the abstract classes here: either they are parent classes
714
720
// and they will be dealt with by Hibernate Validator or they are child classes
715
721
// without any proper implementation and we can ignore them.
716
722
continue ;
717
723
}
724
+ if (isInGraalVMFeature (indexView , subclass )) {
725
+ return ;
726
+ }
718
727
classNamesCollector .add (subclass .name ());
719
728
}
720
- for (ClassInfo implementor : indexView .getAllKnownImplementors (className )) {
729
+ for (ClassInfo implementor : indexView .getAllKnownImplementors (classInfo . name () )) {
721
730
if (Modifier .isAbstract (implementor .flags ())) {
722
731
// we can avoid adding the abstract classes here: either they are parent classes
723
732
// and they will be dealt with by Hibernate Validator or they are child classes
724
733
// without any proper implementation and we can ignore them.
725
734
continue ;
726
735
}
736
+ if (isInGraalVMFeature (indexView , implementor )) {
737
+ continue ;
738
+ }
727
739
classNamesCollector .add (implementor .name ());
728
740
}
729
741
}
730
742
743
+ private static boolean isInGraalVMFeature (IndexView indexView , ClassInfo classInfo ) {
744
+ if (classInfo .interfaceNames ().contains (GRAALVM_FEATURE )) {
745
+ return true ;
746
+ }
747
+
748
+ DotName hostingClassName ;
749
+ switch (classInfo .nestingType ()) {
750
+ case TOP_LEVEL :
751
+ return false ;
752
+ case INNER :
753
+ case LOCAL :
754
+ hostingClassName = DotName .createSimple (classInfo .simpleName ());
755
+ break ;
756
+ case ANONYMOUS :
757
+ // TODO: this doesn't work atm, Jandex will need some adjustments
758
+ hostingClassName = classInfo .enclosingMethod ().enclosingClass ();
759
+ break ;
760
+ default :
761
+ return false ;
762
+ }
763
+
764
+ ClassInfo hostingClass = indexView .getClassByName (hostingClassName );
765
+ if (hostingClass == null ) {
766
+ return false ;
767
+ }
768
+
769
+ return isInGraalVMFeature (indexView , hostingClass );
770
+ }
771
+
731
772
private static void contributeClassMarkedForCascadingValidation (Set <DotName > classNamesCollector ,
732
773
IndexView indexView , DotName consideredAnnotation , Type type ) {
733
774
if (VALID != consideredAnnotation ) {
@@ -736,7 +777,10 @@ private static void contributeClassMarkedForCascadingValidation(Set<DotName> cla
736
777
737
778
DotName className = getClassName (type );
738
779
if (className != null ) {
739
- contributeClass (classNamesCollector , indexView , className );
780
+ ClassInfo classInfo = indexView .getClassByName (className );
781
+ if (classInfo != null ) {
782
+ contributeClass (classNamesCollector , indexView , classInfo );
783
+ }
740
784
}
741
785
}
742
786
0 commit comments