After updating to Spring Boot 3.0.1 and running a native image builded with CNB I get the following error:

2022-12-24T20:20:45.147Z ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourceScriptDatabaseInitializer': Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0: Error creating bean with name 'dataSource': Instantiation of supplied bean failed
    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:1225) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1210) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1157) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:313) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1130) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:905) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[bccb.BoordcomputerConfiguratieBeheerApi:3.0.1]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[bccb.BoordcomputerConfiguratieBeheerApi:3.0.1]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[bccb.BoordcomputerConfiguratieBeheerApi:3.0.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[bccb.BoordcomputerConfiguratieBeheerApi:3.0.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[bccb.BoordcomputerConfiguratieBeheerApi:3.0.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[bccb.BoordcomputerConfiguratieBeheerApi:3.0.1]
    at bccb.BoordcomputerConfiguratieBeheerApi.main(BoordcomputerConfiguratieBeheerApi.java:10) ~[bccb.BoordcomputerConfiguratieBeheerApi:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Instantiation of supplied bean failed
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainInstanceFromSupplier(AbstractAutowireCapableBeanFactory.java:1236) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1210) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1157) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1405) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:334) ~[na:na]
    ... 23 common frames omitted
Caused by: java.lang.ExceptionInInitializerError: null
    at java.base@17.0.5/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[bccb.BoordcomputerConfiguratieBeheerApi:na]
    at java.base@17.0.5/java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[bccb.BoordcomputerConfiguratieBeheerApi:na]
    at com.zaxxer.hikari.HikariConfig.setDriverClassName(HikariConfig.java:492) ~[bccb.BoordcomputerConfiguratieBeheerApi: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) ~[bccb.BoordcomputerConfiguratieBeheerApi:3.0.1]
    at org.springframework.boot.jdbc.DataSourceBuilder.build(DataSourceBuilder.java:183) ~[bccb.BoordcomputerConfiguratieBeheerApi:3.0.1]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:48) ~[na:na]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari.dataSource(DataSourceConfiguration.java:90) ~[bccb.BoordcomputerConfiguratieBeheerApi:na]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration__BeanDefinitions$Hikari__BeanDefinitions.lambda$getDataSourceInstanceSupplier$0(DataSourceConfiguration__BeanDefinitions.java:32) ~[na:na]
    at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:68) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:54) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.lambda$get$2(BeanInstanceSupplier.java:208) ~[na:na]
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:59) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:47) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.invokeBeanSupplier(BeanInstanceSupplier.java:220) ~[na:na]
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:208) ~[na:na]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainInstanceFromSupplier(AbstractAutowireCapableBeanFactory.java:1225) ~[bccb.BoordcomputerConfiguratieBeheerApi:6.0.3]
    ... 35 common frames omitted
Caused by: java.util.MissingResourceException: Can't find bundle for base name com.microsoft.sqlserver.jdbc.SQLServerResource, locale en_US
    at java.base@17.0.5/java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:2045) ~[bccb.BoordcomputerConfiguratieBeheerApi:na]
    at java.base@17.0.5/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1683) ~[bccb.BoordcomputerConfiguratieBeheerApi:na]
    at java.base@17.0.5/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1586) ~[bccb.BoordcomputerConfiguratieBeheerApi:na]
    at java.base@17.0.5/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1549) ~[bccb.BoordcomputerConfiguratieBeheerApi:na]
    at java.base@17.0.5/java.util.ResourceBundle.getBundle(ResourceBundle.java:858) ~[bccb.BoordcomputerConfiguratieBeheerApi:na]
    at com.microsoft.sqlserver.jdbc.SQLServerResource.getResource(SQLServerResource.java:23) ~[na:na]
    at com.microsoft.sqlserver.jdbc.SQLServerDriverPropertyInfo.<init>(SQLServerDriver.java:40) ~[na:na]
    at com.microsoft.sqlserver.jdbc.SQLServerDriver.<clinit>(SQLServerDriver.java:617) ~[bccb.BoordcomputerConfiguratieBeheerApi:na]
    ... 52 common frames omitted

TLDR: Caused by: java.util.MissingResourceException: Can't find bundle for base name com.microsoft.sqlserver.jdbc.SQLServerResource, locale en_US

My pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://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>3.0.1</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    ...

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!-- Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Persistence -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <scope>runtime</scope>
        </dependency>

        ... other deps 
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <docker>
                        <host>unix:///run/user/1000/podman/podman.sock</host>
                        <bindHostToBuilder>true</bindHostToBuilder>
                    </docker>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.hibernate.orm.tooling</groupId>
                <artifactId>hibernate-enhance-maven-plugin</artifactId>
                <version>${hibernate.version}</version>
                <executions>
                    <execution>
                        <id>enhance</id>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                        <configuration>
                            <enableLazyInitialization>true</enableLazyInitialization>
                            <enableDirtyTracking>true</enableDirtyTracking>
                            <enableAssociationManagement>true</enableAssociationManagement>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

What am I missing here? Are there enough native hints provided by Spring Boot for mssql?

Comment From: matthenry87

They don't have the metadata for mssql in the reachability repository yet. I am about to try and tackle this for my own use. You need to add a hint to tell the GraalVM compiler to include that resource bundle at build time.

I'll probably dig into this tomorrow and I'll circle back if I get it working.

Comment From: trolle4

Any news on this? Have the exact same problem.

Comment From: wilkinsona

mssql-jdbc doesn't work by default in a Graal native image. As @matthenry87 suggests above, that could be fixed with some reachability metadata. Alternatively, you could provide your own hints so that Graal includes the resource bundle in the native image.

Comment From: matthenry87

Any news on this? Have the exact same problem.

I got it working. I'll share my hints once I'm at my computer here shortly.

Comment From: matthenry87

resource-config.json

{
  "bundles": [
    {
      "name": "com.microsoft.sqlserver.jdbc.SQLServerResource"
    }
  ]
}

I think I had to add the argument to tell native-image to include all charsets as well. This can easily be implemented using the RuntimeHintsRegistrar too: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#native-image.advanced.custom-hints

Comment From: matthenry87

I haven't completely exercised the mssql driver yet though.. Have been adding hints as I need them rather than using the tracing agent. You may run into other errors at runtime and if so will need to add more hints depending on what it's trying to do.

Comment From: dirkk

@matthenry87 Thanks for your post, this got me going. I would like to add this here if anyone else has a similar setup than I have. I am using Spring Boot 3 and Graal and want to use the SqlServerDriver. Adding the following small class was enough:

public class RuntimeHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(org.springframework.aot.hint.RuntimeHints hints, ClassLoader classLoader) {
        hints
            .resources()
            .registerResourceBundle("com.microsoft.sqlserver.jdbc.SQLServerResource");
    }
}

And adding

@ImportRuntimeHints(RuntimeHints.class)

to a @Configuration class of mine.

This will generate the snippet mentioned before

  "bundles": [
    {
      "name": "com.microsoft.sqlserver.jdbc.SQLServerResource"
    }
  ]

in \build\resources\aot\META-INF\native-image\org.test\myapp\resource-config.json

Comment From: oeresundsgruppen

If you use cachedRowSet - do you also see resource javax/sql/rowset/rowset.properties not found ?