I am trying to play with SpringBoot Native image complication.
gradle bootBuildImage
– Generated Docker Image
But running the docker image fails to initialize the Oracle JDBC driver. Any thoughts?
Here is the console log
2023-10-06T16:42:20.006Z INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 17 ms
2023-10-06T16:42:20.021Z WARN 1 --- [ main] oracle.jdbc : Error while registering Oracle JDBC Diagnosability MBean.
java.lang.ExceptionInInitializerError: null
at oracle.jdbc.driver.OracleDiagnosabilityMBean.<init>(OracleDiagnosabilityMBean.java:145) ~[na:na]
at oracle.jdbc.driver.OracleDriver.registerMBeans(OracleDriver.java:417) ~[com.example.demo.DemoApplication:19.3.0.0.0]
at oracle.jdbc.driver.OracleDriver$1.run(OracleDriver.java:249) ~[na:na]
at [email protected]/java.security.AccessController.executePrivileged(AccessController.java:171) ~[na:na]
at [email protected]/java.security.AccessController.doPrivileged(AccessController.java:318) ~[na:na]
at oracle.jdbc.driver.OracleDriver.<clinit>(OracleDriver.java:245) ~[com.example.demo.DemoApplication:19.3.0.0.0]
at [email protected]/java.lang.Class.ensureInitialized(DynamicHub.java:579) ~[com.example.demo.DemoApplication:na]
at [email protected]/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[com.example.demo.DemoApplication:na]
at [email protected]/java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[com.example.demo.DemoApplication:na]
at com.zaxxer.hikari.HikariConfig.setDriverClassName(HikariConfig.java:492) ~[com.example.demo.DemoApplication:na]
at org.springframework.boot.jdbc.DataSourceBuilder$MappedDataSourceProperty.set(DataSourceBuilder.java:479) ~[na:na]
at org.springframework.boot.jdbc.DataSourceBuilder$MappedDataSourceProperties.set(DataSourceBuilder.java:373) ~[com.example.demo.DemoApplication:3.1.4]
at org.springframework.boot.jdbc.DataSourceBuilder.build(DataSourceBuilder.java:183) ~[com.example.demo.DemoApplication:3.1.4]
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:59) ~[na:na]
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari.dataSource(DataSourceConfiguration.java:117) ~[com.example.demo.DemoApplication:3.1.4]
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration__BeanDefinitions$Hikari.lambda$getDataSourceInstanceSupplier$1(DataSourceConfiguration__BeanDefinitions.java:50) ~[na:na]
at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:68) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:54) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.aot.BeanInstanceSupplier.lambda$get$2(BeanInstanceSupplier.java:202) ~[na:na]
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.aot.BeanInstanceSupplier.invokeBeanSupplier(BeanInstanceSupplier.java:214) ~[na:na]
at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:202) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:947) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1214) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1158) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:910) ~[na:na]
at org.springframework.beans.factory.support.RegisteredBean.resolveAutowiredArgument(RegisteredBean.java:229) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:314) ~[na:na]
at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArguments(BeanInstanceSupplier.java:260) ~[na:na]
at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:200) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:947) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1214) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1158) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:312) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolveValue(AutowiredFieldValueResolver.java:188) ~[na:na]
at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolveObject(AutowiredFieldValueResolver.java:154) ~[na:na]
at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolve(AutowiredFieldValueResolver.java:143) ~[na:na]
at com.example.demo.repo.TestRepo__Autowiring.apply(TestRepo__Autowiring.java:14) ~[na:na]
at org.springframework.beans.factory.support.InstanceSupplier$1.get(InstanceSupplier.java:83) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:947) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1214) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1158) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[com.example.demo.DemoApplication:6.0.12]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[com.example.demo.DemoApplication:3.1.4]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) ~[com.example.demo.DemoApplication:3.1.4]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[com.example.demo.DemoApplication:3.1.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[com.example.demo.DemoApplication:3.1.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[com.example.demo.DemoApplication:3.1.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[com.example.demo.DemoApplication:3.1.4]
at com.example.demo.DemoApplication.main(DemoApplication.java:10) ~[com.example.demo.DemoApplication:na]
Caused by: java.lang.IllegalArgumentException: java.lang.NoSuchMethodException: oracle.jdbc.logging.annotations.Feature.values()
at oracle.jdbc.logging.runtime.Features.<init>(Features.java:52) ~[na:na]
at oracle.jdbc.logging.runtime.TraceControllerImpl.<clinit>(TraceControllerImpl.java:39) ~[na:na]
... 78 common frames omitted
Caused by: java.lang.NoSuchMethodException: oracle.jdbc.logging.annotations.Feature.values()
at [email protected]/java.lang.Class.checkMethod(DynamicHub.java:1040) ~[com.example.demo.DemoApplication:na]
at [email protected]/java.lang.Class.getMethod(DynamicHub.java:1025) ~[com.example.demo.DemoApplication:na]
at oracle.jdbc.logging.runtime.Features.<init>(Features.java:48) ~[na:na]
... 79 common frames omitted
2
Answers
Replacing ojdbc8:19.3.jar with ojdbc8:21.7.0.0.jar resolved the issue. With ojdbc8:21.7.0.0.jar GraalVM successfully generated native image, and it runs with no errors.
About two years ago I had a talk with the Oracle team involved in the GraalVM development (thanks to my company).
I told them the same issue, and many similar ones.
They tried including in my project a few configuration files which instructed GraalVM to don’t generated native image for some JARs, like the OJDBC one.
After doing that some other similar issues have been discovered.
Their answer was: "Dor such type of projects we suggest you use the GraalVM JVM, without the native image generation, to get much better performances over the stock JDK, unless we will solve, in future release, those issues".
Much time has been, they worked on it for sure, but I stopped digging into native images by using only the GraalVM JVM.
The docker image I use is
ghcr.io/graalvm/jdk-community:17-ol8
.