Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring OXM / JAXB: Failure when executing native image #30021

Closed
steinsag opened this issue Feb 23, 2023 · 2 comments
Closed

Spring OXM / JAXB: Failure when executing native image #30021

steinsag opened this issue Feb 23, 2023 · 2 comments
Assignees
Labels
for: external-project Needs a fix in external project status: declined A suggestion or change that we don't feel we should currently apply theme: aot An issue related to Ahead-of-time processing

Comments

@steinsag
Copy link

Summary

  • SpringBoot: 3.0.3
  • Kotlin: 1.7.22
  • Java: 17.0.5 Temurin (on Ubuntu 64 Bit)
  • simple SpringBoot Web project, see: https://github.com/steinsag/spring-native-xml
  • Spring OXM is used to marshal some simple XML structure to a string
  • JVM execution works as expected
  • AOT also successful
  • BUT: native execution fails with:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'helloXmlService': Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'createJaxbMarshaller': Proxy class defined by interfaces [interface jakarta.xml.bind.annotation.XmlAccessorType, interface org.glassfish.jaxb.core.v2.model.annotation.Locatable] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles= and -H:DynamicProxyConfigurationResources= options.

expected behavior: All XML runtime classes automatically discovered during AOT as official Spring OXM approach is used.

How to reproduce

sample project: https://github.com/steinsag/spring-native-xml

git clone [email protected]:steinsag/spring-native-xml.git spring-native-xml
cd spring-native-xml
./mvnw spring-boot:build-image -Pnative
docker run --rm -p 8080:8080 spring-native-xml:0.0.1-SNAPSHOT

Full stacktrace

$ docker run --rm -p 8080:8080 spring-native-xml:0.0.1-SNAPSHOT

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.3)

2023-02-23T20:22:00.351Z  INFO 1 --- [           main] s.p.s.SpringNativeXmlApplicationKt       : Starting AOT-processed SpringNativeXmlApplicationKt using Java 17.0.6 with PID 1 (/workspace/services.progressit.springnativexml.SpringNativeXmlApplicationKt started by cnb in /workspace)
2023-02-23T20:22:00.351Z  INFO 1 --- [           main] s.p.s.SpringNativeXmlApplicationKt       : No active profile set, falling back to 1 default profile: "default"
2023-02-23T20:22:00.374Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-02-23T20:22:00.375Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-02-23T20:22:00.375Z  INFO 1 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.5]
2023-02-23T20:22:00.382Z  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-02-23T20:22:00.382Z  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 31 ms
2023-02-23T20:22:00.402Z  WARN 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'helloXmlService': Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'createJaxbMarshaller': Proxy class defined by interfaces [interface jakarta.xml.bind.annotation.XmlAccessorType, interface org.glassfish.jaxb.core.v2.model.annotation.Locatable] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.
2023-02-23T20:22:00.403Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-02-23T20:22:00.404Z ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'helloXmlService': Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'createJaxbMarshaller': Proxy class defined by interfaces [interface jakarta.xml.bind.annotation.XmlAccessorType, interface org.glassfish.jaxb.core.v2.model.annotation.Locatable] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:351) ~[na:na]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArguments(BeanInstanceSupplier.java:271) ~[na:na]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:206) ~[na:na]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainInstanceFromSupplier(AbstractAutowireCapableBeanFactory.java:1226) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1211) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1158) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:917) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:3.0.3]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:3.0.3]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:3.0.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:3.0.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:3.0.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:3.0.3]
        at services.progressit.springnativexml.SpringNativeXmlApplicationKt.main(SpringNativeXmlApplication.kt:13) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'createJaxbMarshaller': Proxy class defined by interfaces [interface jakarta.xml.bind.annotation.XmlAccessorType, interface org.glassfish.jaxb.core.v2.model.annotation.Locatable] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1752) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1405) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:334) ~[na:na]
        ... 21 common frames omitted
Caused by: com.oracle.svm.core.jdk.UnsupportedFeatureError: Proxy class defined by interfaces [interface jakarta.xml.bind.annotation.XmlAccessorType, interface org.glassfish.jaxb.core.v2.model.annotation.Locatable] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.
        at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:89) ~[na:na]
        at com.oracle.svm.core.reflect.proxy.DynamicProxySupport.getProxyClass(DynamicProxySupport.java:171) ~[na:na]
        at [email protected]/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:47) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:na]
        at [email protected]/java.lang.reflect.Proxy.newProxyInstance(Proxy.java:1037) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:na]
        at org.glassfish.jaxb.runtime.v2.model.annotation.LocatableAnnotation.create(LocatableAnnotation.java:53) ~[na:na]
        at org.glassfish.jaxb.runtime.v2.model.annotation.RuntimeInlineAnnotationReader.getClassAnnotation(RuntimeInlineAnnotationReader.java:92) ~[na:na]
        at org.glassfish.jaxb.runtime.v2.model.annotation.RuntimeInlineAnnotationReader.getClassAnnotation(RuntimeInlineAnnotationReader.java:29) ~[na:na]
        at org.glassfish.jaxb.runtime.v2.model.impl.ClassInfoImpl.getClassOrPackageAnnotation(ClassInfoImpl.java:434) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at org.glassfish.jaxb.runtime.v2.model.impl.ClassInfoImpl.getAccessType(ClassInfoImpl.java:446) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at org.glassfish.jaxb.runtime.v2.model.impl.ClassInfoImpl.getProperties(ClassInfoImpl.java:293) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeClassInfoImpl.getProperties(RuntimeClassInfoImpl.java:159) ~[na:na]
        at org.glassfish.jaxb.runtime.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:219) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:72) ~[na:na]
        at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:52) ~[na:na]
        at org.glassfish.jaxb.runtime.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:185) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:67) ~[na:na]
        at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:52) ~[na:na]
        at org.glassfish.jaxb.runtime.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:332) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at org.glassfish.jaxb.runtime.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:347) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:415) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:255) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1115) ~[na:na]
        at org.glassfish.jaxb.runtime.v2.ContextFactory.createContext(ContextFactory.java:144) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at org.glassfish.jaxb.runtime.v2.JAXBContextFactory.createContext(JAXBContextFactory.java:44) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.2 - d104f19]
        at jakarta.xml.bind.ContextFinder.find(ContextFinder.java:368) ~[na:na]
        at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:605) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.0]
        at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:546) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:4.0.0]
        at org.springframework.oxm.jaxb.Jaxb2Marshaller.createJaxbContextFromClasses(Jaxb2Marshaller.java:559) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.oxm.jaxb.Jaxb2Marshaller.getJaxbContext(Jaxb2Marshaller.java:508) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.oxm.jaxb.Jaxb2Marshaller.afterPropertiesSet(Jaxb2Marshaller.java:485) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1798) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1748) ~[services.progressit.springnativexml.SpringNativeXmlApplicationKt:6.0.5]
        ... 31 common frames omitted
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 23, 2023
@sdeleuze sdeleuze self-assigned this Feb 23, 2023
@sdeleuze sdeleuze added the theme: aot An issue related to Ahead-of-time processing label Feb 23, 2023
@sdeleuze
Copy link
Contributor

After a deeper look to the sample, I tend to think this issue is not Spring specific and should be raised with a non Spring repro on https://github.com/oracle/graalvm-reachability-metadata side. The proxy interfaces seems not dependent of user classes.

When you provide them with for example @ImportRuntimeHints(Hints::class) and:

class Hints : RuntimeHintsRegistrar {
    override fun registerHints(hints: RuntimeHints, classLoader: ClassLoader?) {
        hints.proxies().registerJdkProxy(XmlAccessorType::class.java, Locatable::class.java)
    }
}

An org.glassfish.jaxb.runtime.v2.runtime.IllegalAnnotationsException is thrown but I guess it will be fixable on reachability metadata side as well.

As a consequence I close this issue on Spring side, if you can, please add a comment with the reachability metadata issue.

@sdeleuze sdeleuze closed this as not planned Won't fix, can't repro, duplicate, stale Feb 24, 2023
@sdeleuze sdeleuze added status: declined A suggestion or change that we don't feel we should currently apply for: external-project Needs a fix in external project and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Feb 24, 2023
@steinsag
Copy link
Author

steinsag commented Feb 28, 2023

It seems there is a relevant feature request on GraalVM reachability metadata issue: oracle/graalvm-reachability-metadata#137

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: external-project Needs a fix in external project status: declined A suggestion or change that we don't feel we should currently apply theme: aot An issue related to Ahead-of-time processing
Projects
None yet
Development

No branches or pull requests

3 participants