Repository: quarkusio/quarkus
Issue: #19534 broke backwards compatibility with GraalVM/Mandrel 20.3

### Describe the bug

https://github.com/quarkusio/quarkus/pull/19534 results in the following exception when using GraalVM/Mandrel 20.3

```
java.lang.ClassNotFoundException: com.oracle.svm.core.jdk.JDK16OrEarlier
```

### Expected behavior

Tests and applications should build with GraalVM/Mandrel 20.3.

### Actual behavior

Tests and applications fail to build with GraalVM/Mandrel 20.3.

### How to Reproduce?

Build any integration test/quarkus app using `-Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel:20.3-java11`

### Output of `uname -a` or `ver`

_No response_

### Output of `java -version`

11.0.12

### GraalVM version (if different from Java)

20.3

### Quarkus version or git rev

cc16df8dd324cecfedba06aec04c1bf2d17e62f3

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

_No response_

### Additional information

Full stack trace:

```
Fatal error:java.lang.TypeNotPresentException: Type com.oracle.svm.core.jdk.JDK16OrEarlier not present
	at java.base/sun.reflect.annotation.TypeNotPresentExceptionProxy.generateException(TypeNotPresentExceptionProxy.java:46)
	at java.base/sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:86)
	at com.sun.proxy.$Proxy62.onlyWith(Unknown Source)
	at com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor.findTargetClass(AnnotationSubstitutionProcessor.java:883)
	at com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor.handleClass(AnnotationSubstitutionProcessor.java:287)
	at com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor.init(AnnotationSubstitutionProcessor.java:265)
	at com.oracle.svm.hosted.NativeImageGenerator.createDeclarativeSubstitutionProcessor(NativeImageGenerator.java:919)
	at com.oracle.svm.hosted.NativeImageGenerator.setupNativeImage(NativeImageGenerator.java:853)
	at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:554)
	at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:469)
	at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1407)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: java.lang.ClassNotFoundException: com.oracle.svm.core.jdk.JDK16OrEarlier
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:398)
	at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
	at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
	at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
	at java.base/sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:440)
	at java.base/sun.reflect.annotation.AnnotationParser.parseClassValue(AnnotationParser.java:421)
	at java.base/sun.reflect.annotation.AnnotationParser.lambda$parseClassArray$0(AnnotationParser.java:719)
	at java.base/sun.reflect.annotation.AnnotationParser.parseArrayElements(AnnotationParser.java:747)
	at java.base/sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:718)
	at java.base/sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:532)
	at java.base/sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:356)
	at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:287)
	at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:121)
	at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:73)
	at java.base/java.lang.Class.createAnnotationData(Class.java:3757)
	at java.base/java.lang.Class.annotationData(Class.java:3746)
	at java.base/java.lang.Class.getAnnotations(Class.java:3682)
	at com.oracle.svm.hosted.ImageClassLoader.canLoadAnnotations(ImageClassLoader.java:133)
	at com.oracle.svm.hosted.ImageClassLoader.handleClass(ImageClassLoader.java:170)
	at com.oracle.svm.hosted.AbstractNativeImageClassLoaderSupport$ClassInit.handleClassFileName(AbstractNativeImageClassLoaderSupport.java:288)
	at com.oracle.svm.hosted.AbstractNativeImageClassLoaderSupport$ClassInit$1.lambda$visitFile$0(AbstractNativeImageClassLoaderSupport.java:225)
	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
	... 5 more
```

Changed files:
core/runtime/src/main/java/io/quarkus/runtime/graal/LCMSSubstitutionsJDK17.java
core/runtime/src/main/java/io/quarkus/runtime/graal/LCMSSubstitutions.java
core/runtime/src/main/java/io/quarkus/runtime/graal/Target_sun_security_jca_JCAUtil.java
core/runtime/src/main/java/io/quarkus/runtime/util/JavaVersionUtil.java

diff --git a/core/runtime/src/main/java/io/quarkus/runtime/graal/LCMSSubstitutions.java b/core/runtime/src/main/java/io/quarkus/runtime/graal/LCMSSubstitutions.java
index 9557212c5dc..78f0fee74d7 100644
--- a/core/runtime/src/main/java/io/quarkus/runtime/graal/LCMSSubstitutions.java
+++ b/core/runtime/src/main/java/io/quarkus/runtime/graal/LCMSSubstitutions.java
@@ -4,7 +4,8 @@
 
 import com.oracle.svm.core.annotate.Substitute;
 import com.oracle.svm.core.annotate.TargetClass;
-import com.oracle.svm.core.jdk.JDK16OrEarlier;
+
+import io.quarkus.runtime.util.JavaVersionUtil.JDK16OrEarlier;
 
 @TargetClass(className = "sun.java2d.cmm.lcms.LCMS", onlyWith = JDK16OrEarlier.class)
 final class Target_sun_java2d_cmm_lcms_LCMS {
diff --git a/core/runtime/src/main/java/io/quarkus/runtime/graal/LCMSSubstitutionsJDK17.java b/core/runtime/src/main/java/io/quarkus/runtime/graal/LCMSSubstitutionsJDK17.java
index 90f53d9b777..baf8034401c 100644
--- a/core/runtime/src/main/java/io/quarkus/runtime/graal/LCMSSubstitutionsJDK17.java
+++ b/core/runtime/src/main/java/io/quarkus/runtime/graal/LCMSSubstitutionsJDK17.java
@@ -4,7 +4,8 @@
 
 import com.oracle.svm.core.annotate.Substitute;
 import com.oracle.svm.core.annotate.TargetClass;
-import com.oracle.svm.core.jdk.JDK17OrLater;
+
+import io.quarkus.runtime.util.JavaVersionUtil.JDK17OrLater;
 
 @TargetClass(className = "sun.java2d.cmm.lcms.LCMS", onlyWith = JDK17OrLater.class)
 final class Target_sun_java2d_cmm_lcms_LCMS_JDK17 {
diff --git a/core/runtime/src/main/java/io/quarkus/runtime/graal/Target_sun_security_jca_JCAUtil.java b/core/runtime/src/main/java/io/quarkus/runtime/graal/Target_sun_security_jca_JCAUtil.java
index b6e4791951c..436b15a4db6 100644
--- a/core/runtime/src/main/java/io/quarkus/runtime/graal/Target_sun_security_jca_JCAUtil.java
+++ b/core/runtime/src/main/java/io/quarkus/runtime/graal/Target_sun_security_jca_JCAUtil.java
@@ -5,9 +5,10 @@
 import com.oracle.svm.core.annotate.Alias;
 import com.oracle.svm.core.annotate.RecomputeFieldValue;
 import com.oracle.svm.core.annotate.TargetClass;
-import com.oracle.svm.core.jdk.JDK17OrLater;
 
-@TargetClass(className = "sun.security.jca.JCAUtil", onlyWith = JDK17OrLater.class)
+import io.quarkus.runtime.util.JavaVersionUtil;
+
+@TargetClass(className = "sun.security.jca.JCAUtil", onlyWith = JavaVersionUtil.JDK17OrLater.class)
 public final class Target_sun_security_jca_JCAUtil {
 
     @Alias
diff --git a/core/runtime/src/main/java/io/quarkus/runtime/util/JavaVersionUtil.java b/core/runtime/src/main/java/io/quarkus/runtime/util/JavaVersionUtil.java
index 082a6378b0e..6a78ce2e558 100644
--- a/core/runtime/src/main/java/io/quarkus/runtime/util/JavaVersionUtil.java
+++ b/core/runtime/src/main/java/io/quarkus/runtime/util/JavaVersionUtil.java
@@ -1,5 +1,6 @@
 package io.quarkus.runtime.util;
 
+import java.util.function.BooleanSupplier;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -10,6 +11,8 @@ public class JavaVersionUtil {
     private static boolean IS_JAVA_11_OR_NEWER;
     private static boolean IS_JAVA_13_OR_NEWER;
     private static boolean IS_GRAALVM_JDK;
+    private static boolean IS_JAVA_16_OR_OLDER;
+    private static boolean IS_JAVA_17_OR_NEWER;
 
     static {
         performChecks();
@@ -22,9 +25,13 @@ static void performChecks() {
             int first = Integer.parseInt(matcher.group(1));
             IS_JAVA_11_OR_NEWER = (first >= 11);
             IS_JAVA_13_OR_NEWER = (first >= 13);
+            IS_JAVA_16_OR_OLDER = (first <= 16);
+            IS_JAVA_17_OR_NEWER = (first >= 17);
         } else {
             IS_JAVA_11_OR_NEWER = false;
             IS_JAVA_13_OR_NEWER = false;
+            IS_JAVA_16_OR_OLDER = false;
+            IS_JAVA_17_OR_NEWER = false;
         }
 
         String vmVendor = System.getProperty("java.vm.vendor");
@@ -39,7 +46,31 @@ public static boolean isJava13OrHigher() {
         return IS_JAVA_13_OR_NEWER;
     }
 
+    public static boolean isJava16OrLower() {
+        return IS_JAVA_16_OR_OLDER;
+    }
+
+    public static boolean isJava17OrHigher() {
+        return IS_JAVA_17_OR_NEWER;
+    }
+
     public static boolean isGraalvmJdk() {
         return IS_GRAALVM_JDK;
     }
+
+    /* Clone of com.oracle.svm.core.jdk.JDK17OrLater to work around #19645 issue with GraalVM 20.3 */
+    public static class JDK17OrLater implements BooleanSupplier {
+        @Override
+        public boolean getAsBoolean() {
+            return JavaVersionUtil.isJava17OrHigher();
+        }
+    }
+
+    /* Clone of com.oracle.svm.core.jdk.JDK16OrEarlier to work around #19645 issue with GraalVM 20.3 */
+    public static class JDK16OrEarlier implements BooleanSupplier {
+        @Override
+        public boolean getAsBoolean() {
+            return JavaVersionUtil.isJava16OrLower();
+        }
+    }
 }