spring-bootspring-boot-native

Unable to run Spring Boot native application with AWSSecretsManagerPostgreSQLDriver


I'm trying to run an existing Spring Boot application natively, but I'm getting this exception:

java.lang.NoSuchMethodException: com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver.<init>()

The database driver is conditional:

        if(StringUtils.isEmpty(secretArn) || Constants.NO_OPERATION.equals(secretArn))
        {
            dataSource.setJdbcUrl(url);
            dataSource.setDriverClassName("org.postgresql.Driver");
            dataSource.setUsername(username);
            dataSource.setPassword(password);
        }
        else
        {
            dataSource.setDriverClassName(AWSSecretsManagerPostgreSQLDriver.class.getName());
            dataSource.setJdbcUrl(url.replace("jdbc:", "jdbc-secretsmanager:"));
            dataSource.setUsername(secretArn);
        }

I have already tried:

1) @RegisterReflection(classes = {UUID[].class, AWSSecretsManagerPostgreSQLDriver.class})
2) src/main/resources/META-INF/native-image/com.amazonaws.secretsmanager/aws-secretsmanager-jdbc-additional-hints/reflect-config.json
[
  {
    "name": "com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver",
    "allDeclaredConstructors": true
  }
]
3) @SpringBootApplication(proxyBeanMethods = false)
@ImportRuntimeHints(MyRuntimeHints.class)
public class CoreApplication 

public class MyRuntimeHints implements RuntimeHintsRegistrar
{

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        hints.reflection().registerType(AWSSecretsManagerPostgreSQLDriver.class);
    }

}

Stacktrace:

 :: Spring Boot ::                (v3.4.1)
2025-01-20T14:52:24.786Z  INFO 1 --- [core-native] [           main] b.c.digital.core.CoreApplication  : Starting AOT-processed CoreApplication using Java 21.0.2 with PID 1 (/app/digital-core-backend started by root in /app)
2025-01-20T14:52:24.786Z  INFO 1 --- [core-native] [           main] b.c.digital.core.CoreApplication  : The following 1 profile is active: "skip-migrations"
2025-01-20T14:52:24.975Z  INFO 1 --- [core-native] [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=0cfe84c1-9d59-39cc-92c1-04cef9915c66
2025-01-20T14:52:26.372Z  WARN 1 --- [core-native] [           main] io.undertow.websockets.jsr               : UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
2025-01-20T14:52:26.372Z  INFO 1 --- [core-native] [           main] io.undertow.servlet                      : Initializing Spring embedded WebApplicationContext
2025-01-20T14:52:26.372Z  INFO 1 --- [core-native] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1586 ms
2025-01-20T14:52:26.788Z  WARN 1 --- [core-native] [           main] w.s.c.ServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory': Failed to initialize dependency 'dataSourceScriptDatabaseInitializer' of LoadTimeWeaverAware bean 'entityManagerFactory': Error creating bean with name 'dataSourceScriptDatabaseInitializer': Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0: Error creating bean with name 'readWriteDataSource': Instantiation of supplied bean failed
Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory': Failed to initialize dependency 'dataSourceScriptDatabaseInitializer' of LoadTimeWeaverAware bean 'entityManagerFactory': Error creating bean with name 'dataSourceScriptDatabaseInitializer': Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0: Error creating bean with name 'readWriteDataSource': Instantiation of supplied bean failed
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:970)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
    at br.com.digital.core.CoreApplication.main(CoreApplication.java:14)
    at java.base@21.0.2/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourceScriptDatabaseInitializer': Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0: Error creating bean with name 'readWriteDataSource': Instantiation of supplied bean failed
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveAutowiredArgument(BeanInstanceSupplier.java:369)
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArguments(BeanInstanceSupplier.java:289)
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:223)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:979)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1239)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1182)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:563)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:289)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:312)
    ... 11 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'readWriteDataSource': Instantiation of supplied bean failed
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1245)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1182)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:563)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:289)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1631)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1519)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913)
    at org.springframework.beans.factory.support.RegisteredBean.resolveAutowiredArgument(RegisteredBean.java:253)
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveAutowiredArgument(BeanInstanceSupplier.java:366)
    ... 23 more
Caused by: java.lang.RuntimeException: Failed to instantiate class com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver
    at com.zaxxer.hikari.HikariConfig.setDriverClassName(HikariConfig.java:502)
    at br.com.digital.config.AbstractDataSourceConfig.createDataSource(AbstractDataSourceConfig.java:59)
    at br.com.digital.config.SingleDataSourceConfig.readWriteDataSource(SingleDataSourceConfig.java:19)
    at br.com.digital.config.SingleDataSourceConfig$$SpringCGLIB$$0.CGLIB$readWriteDataSource$0(<generated>)
    at br.com.digital.config.SingleDataSourceConfig$$SpringCGLIB$$FastClass$$1.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:348)
    at br.com.digital.config.SingleDataSourceConfig$$SpringCGLIB$$0.readWriteDataSource(<generated>)
    at br.com.digital.config.SingleDataSourceConfig__BeanDefinitions.lambda$getReadWriteDataSourceInstanceSupplier$0(SingleDataSourceConfig__BeanDefinitions.java:34)
    at org.springframework.util.function.ThrowingFunction.apply(ThrowingFunction.java:63)
    at org.springframework.util.function.ThrowingFunction.apply(ThrowingFunction.java:51)
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.lambda$get$1(BeanInstanceSupplier.java:219)
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiateWithFactoryMethod(SimpleInstantiationStrategy.java:88)
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.invokeBeanSupplier(BeanInstanceSupplier.java:256)
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:219)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:979)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1239)
    ... 36 more
Caused by: java.lang.NoSuchMethodException: com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver.<init>()
    at java.base@21.0.2/java.lang.Class.checkMethod(DynamicHub.java:1075)
    at java.base@21.0.2/java.lang.Class.getConstructor0(DynamicHub.java:1238)
    at java.base@21.0.2/java.lang.Class.getConstructor(DynamicHub.java:2442)
    at com.zaxxer.hikari.HikariConfig.setDriverClassName(HikariConfig.java:498)
    ... 54 more

Any ideas?

Thanks


Solution

  • In the end option 2 was correct, the problem was that the container was not being updated on ECS so I lost the test.

    src/main/resources/META-INF/native-image/com.amazonaws.secretsmanager/aws-secretsmanager-jdbc-additional-hints/reflect-config.json

    [
      {
        "name": "com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver",
        "allDeclaredConstructors": true
      }
    ]