Describe the bug When you create a Spring Boot 3 application with a reactive based web server like Spring Cloud Gateway (netty) and include Spring Security generating a native image fails with:
Fatal error: java.lang.TypeNotPresentException: Type org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager not present
at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:117)
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.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68)
at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138)
------------------------------------------------------------------------------------------------------------------------
at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
at java.base/sun.reflect.generics.repository.FieldRepository.computeGenericType(FieldRepository.java:90)
at java.base/sun.reflect.generics.repository.FieldRepository.getGenericType(FieldRepository.java:82)
at java.base/java.lang.reflect.Field.getGenericType(Field.java:276)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.reflect.ReflectionDataBuilder.registerTypesForField(ReflectionDataBuilder.java:486)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.reflect.ReflectionDataBuilder.processMethodMetadata(ReflectionDataBuilder.java:251)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.reflect.ReflectionDataBuilder.duringAnalysis(ReflectionDataBuilder.java:199)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.reflect.ReflectionFeature.duringAnalysis(ReflectionFeature.java:254)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$10(NativeImageGenerator.java:748)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:85)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$11(NativeImageGenerator.java:748)
at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.AbstractAnalysisEngine.runAnalysis(AbstractAnalysisEngine.java:162)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:745)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:578)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:535)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:403)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:580)
at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:128)
Caused by: java.lang.ClassNotFoundException: org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:467)
at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
... 22 more
Sample
I created a Kotlin based sample application to show case the problem at https://github.com/cmdjulian/spring-cloud-gateway-bugs/tree/native-image-spring-security-bug. You can checkout the branch native-image-spring-security-bug. I used ./gradlew nativeCompile with liberica 22.3.r17-nik.
This issue was originally created in Spring Cloud Gateway: https://github.com/spring-cloud/spring-cloud-gateway/issues/2802
Comment From: cmdjulian
Adding implementation("org.springframework.security:spring-security-oauth2-client") to the dependency list solves the issue, but shouldn't be required
Comment From: sjohnr
Hi @cmdjulian, thanks for the sample!
Looking at the sample, you declare the following dependencies:
implementation("org.springframework.boot:spring-boot-starter-security")
...
implementation("org.springframework.cloud:spring-cloud-starter-gateway")
...
Neither of these dependencies declares that you would like spring-security-oauth2-client on your classpath. I believe this dependency is optional in spring-cloud-gateway.
Adding
implementation("org.springframework.security:spring-security-oauth2-client")to the dependency list solves the issue, but shouldn't be required
Given the above explanation, I believe it is actually required. However, you may want to reach out to on spring-cloud-gateway to be sure. I'm going to close this for now, but if you feel I'm missing something, feel free to add an additional comment and we can re-open if needed.