You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot原生应用使用AWSSecretsManagerPostgreSQLDriver启动失败求助

Spring Boot原生镜像运行时AWS SecretsManager驱动无默认构造方法异常解决

问题异常

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

数据库驱动条件配置

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);
}

已尝试的反射配置方案

  • 方案1:使用@RegisterReflection注解
@RegisterReflection(classes = {UUID[].class, AWSSecretsManagerPostgreSQLDriver.class})
  • 方案2:添加reflect-config.json配置文件
    路径: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:自定义RuntimeHintsRegistrar
@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);
    }
}

完整堆栈信息

:: 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

解决思路

1. 精准配置反射规则

AWSSecretsManagerPostgreSQLDriver无参构造无法被反射调用,需明确注册无参构造(若存在)或所需带参构造:

  • 修改RuntimeHints配置,显式指定构造方法:
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
    hints.reflection()
         .registerType(AWSSecretsManagerPostgreSQLDriver.class, 
                       typeHint -> typeHint.withConstructor());
}

2. 调整reflect-config.json配置精度

替换原配置为显式声明无参构造,确保配置被AOT编译正确识别:

[
  {
    "name": "com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver",
    "constructors": [
      {
        "parameters": []
      }
    ]
  }
]

3. 绕过反射直接实例化驱动

如果驱动无无参构造,手动创建驱动实例并设置给数据源,避免HikariCP的反射实例化逻辑:

else {
    AWSSecretsManagerPostgreSQLDriver driver = new AWSSecretsManagerPostgreSQLDriver();
    dataSource.setDriver(driver);
    dataSource.setJdbcUrl(url.replace("jdbc:", "jdbc-secretsmanager:"));
    dataSource.setUsername(secretArn);
}

4. 升级依赖版本

检查aws-secretsmanager-jdbc版本,旧版本可能缺少原生镜像支持的元数据,升级至最新稳定版本尝试解决。

5. 验证反射配置生效

构建原生镜像时添加-H:+PrintReflectionConfiguration参数,查看生成的反射配置中是否包含目标驱动的构造方法,确认自定义配置是否被正确合并。


内容的提问来源于stack exchange,提问作者FkJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:34:50