I am following spring-native getting started guide.
I can create a spring boot native image which works fine. But as soon as I add DataSource configuration and a few extra dependencies (spring-boot-starter-data-jpa, ojdbc8), even though it works fine from IDE, the native executable does not work.
I tried creating a native docker image as well as a native executable, both are giving the same error as below. I am sure I might be overlooking something.
Error:
vishal@LP-xxxxxx:/mnt/c/vishal/tempws/gs-rest-service/complete$ docker run --rm -p 8080:8080 rest-service-complete:0.0.1-SNAPSHOT
2022-08-30 22:05:49.835 INFO 1 --- [ main] o.s.nativex.NativeListener : AOT mode enabled
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.1)
2022-08-30 22:05:49.837 INFO 1 --- [ main] c.e.restservice.RestServiceApplication : Starting RestServiceApplication using Java 11.0.16.1 on aae020a2c84e with PID 1 (/workspace/com.example.restservice.RestServiceApplication started by cnb in /workspace)
2022-08-30 22:05:49.837 INFO 1 --- [ main] c.e.restservice.RestServiceApplication : No active profile set, falling back to 1 default profile: "default"
2022-08-30 22:05:49.857 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-08-30 22:05:49.858 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-08-30 22:05:49.858 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.64]
2022-08-30 22:05:49.861 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-08-30 22:05:49.861 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 24 ms
2022-08-30 22:05:49.867 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 'dataSourceScriptDatabaseInitializer': Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Unexpected exception during bean creation; nested exception is java.lang.RuntimeException: Failed to instantiate class oracle.jdbc.driver.OracleDriver
2022-08-30 22:05:49.867 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2022-08-30 22:05:49.869 ERROR 1 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Native reflection configuration for oracle.jdbc.driver.OracleDriver.<init>() is missing.
Action:
Native configuration for a method accessed reflectively is likely missing.
You can try to configure native hints in order to specify it explicitly.
See https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#native-hints for more details.
I am using sample code same as per documentation: https://github.com/spring-guides/gs-rest-service The only change I have made is in pom.xml and application.yaml. Which are provided as below.
As I mentioned, the application works fine from IntelliJ IDE without any issues. I can build native executable as well as native docker image. But executing them gives me error.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>rest-service-complete</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rest-service-complete</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-native.version>0.12.1</spring-native.version>
<binary-name>rest-service-complete</binary-name>
<native-buildtools.version>0.9.13</native-buildtools.version>
<native-image-extra-flags></native-image-extra-flags>
<skip-native-build>true</skip-native-build>
<repackage.classifier/>
</properties>
<profiles>
<profile>
<id>native</id>
<properties>
<repackage.classifier>exec</repackage.classifier>
<skip-native-build>false</skip-native-build>
</properties>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-native</artifactId>
<version>${spring-native.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>oracle.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>${repackage.classifier}</classifier>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-aot-maven-plugin</artifactId>
<version>${spring-native.version}</version>
<executions>
<execution>
<id>test-generate</id>
<goals>
<goal>test-generate</goal>
</goals>
</execution>
<execution>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native-buildtools.version}</version>
<executions>
<execution>
<id>build-native</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<imageName>${binary-name}</imageName>
<skip>${skip-native-build}</skip>
<buildArgs>
<buildArg>-H:+ReportExceptionStackTraces ${native-image-extra-flags}</buildArg>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-release</id>
<name>Spring release</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-release</id>
<name>Spring release</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
application.yaml
spring:
datasource:
url: "jdbc:oracle:thin:@xx.xx.xx.xxx:1621:xxxx"
driver-class-name: "oracle.jdbc.driver.OracleDriver"
username: "xxxx"
password: "xxxx"
Additional detail if it matters: I am on windows WSL2 Ubuntu
I tried both approaches on the documentation
(1) native image
> mvn spring-boot:build-image
> docker run --rm -p 8080:8080 rest-service-complete:0.0.1-SNAPSHOT
(2) native executable
> mvn -Pnative -DskipTests package
> ./target/rest-service-complete
In both cases, I got the same error.
Updates
To make sure it is not WSL2 issue, I tired later on on linux machine but got same error. I also tried connecting SQLserver with mssql-jdbc driver, same issue, works fine with java -jar
but fails when running native-executable.