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

Docker部署Spring Boot应用时Bean创建失败及Cassandra连接问题求助

问题:Docker环境下Spring Boot连接AWS Cassandra失败,Bean创建异常

我是Docker新手,尝试用docker build构建Spring Boot应用镜像,镜像创建成功,但运行时出现Bean创建失败错误。本地运行(包括直接执行jar包)完全正常,仅Docker环境下出问题。数据库是AWS上的Cassandra Keyspace,推测和连接有关。

Dockerfile

FROM openjdk:17-jdk-buster AS build

WORKDIR /app

COPY build.gradle settings.gradle gradlew /app/
COPY gradle /app/gradle

COPY src /app/src

RUN chmod +x gradlew

RUN ./gradlew build --no-daemon --info

FROM openjdk:17-jdk-buster

WORKDIR /app

COPY --from=build /app/build/libs/*.jar /app/application.jar
COPY --from=build /app/build/resources/main/cassandra_truststore.jks /app/cassandra_truststore.jks

EXPOSE 8000

ENTRYPOINT ["java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseContainerSupport", "-Djava.security.egd=file:/dev/./urandom","-jar","/app/application.jar"]

Repository接口

public interface VisitorsRepository extends CassandraRepository<VisitorEntity, String> {}

Service类(手动创建Bean,未使用@Service注解)

@RequiredArgsConstructor
@Slf4j
public class VisitorService {

@Autowired
private VisitorsRepository repository;

public ApiResponse execute(VisitorDto dto){
    return Mono.just(repository.save(VisitorMapper.dtoToEntity(dto)))
            .map(visitorEntity ->
                            ResponseMapper.buildResponse(true, HttpStatus.CREATED.value(), HttpStatus.CREATED.getReasonPhrase(), HttpStatus.CREATED.value(), HttpStatus.CREATED.getReasonPhrase())
                    )
            .doOnSuccess(m -> log.info("entity saved"))
            .doOnError(error -> log.error("Error saving entity: " + error.getMessage()))
            .onErrorResume(error -> Mono.error(new RuntimeException(error.getMessage()))).block();
}
}

Bean配置类

@Configuration
public class ServiceConfiguration {

  @Bean
  public VisitorService getVisitorService(){
     return new VisitorService();
  }
}

Controller类

@RestController
@CrossOrigin(origins = "*")
@RequestMapping(value = "/api")
@AllArgsConstructor
@Validated
@Slf4j
public class VisitorController {

   private final VisitorService service;

   @PostMapping("/create-visitor")
   public ResponseEntity<ApiResponse> execute(@RequestBody @Valid VisitorDto dto){
      try{
          ApiResponse apiResponse = service.execute(dto);
          return new ResponseEntity<ApiResponse>(apiResponse,HttpStatus.OK);
      }catch (Exception e){
          e.getStackTrace();
          throw new BadRequestException(e.getMessage());
   }

  }
}

错误日志

ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'visitorController' defined in URL [jar:nested:/app/application.jar/!BOOT-INF/classes/!/ipservice/controller/VisitorController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'getVisitorService': Unsatisfied dependency expressed through field 'repository': Error creating bean with name 'visitorsRepository' defined in ipservice.repository.VisitorsRepository defined in @EnableCassandraRepositories declared on CassandraConfig: Cannot resolve reference to bean 'cassandraTemplate' while setting bean property 'cassandraTemplate'

Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)

ipservice.configuration.CassandraConfig$$SpringCGLIB$$0.session() ~[!/:0.0.1-SNAPSHOT]

Caused by: java.security.KeyManagementException: problem accessing trust store

application.yml配置

cloud:
  aws:
   stack:
    auto: false
   region:
    static: "us-east-1"
   cassandra:
    username: "cassandra-user-at-466964128512"
    password: "XXXXXXXXX"
    trustStoreUrl: "./src/main/resources/cassandra_truststore.jks"
    trustStorePassword: "XXXXXXX"
    keySpace: "comparaasegurate"
    localDatacenter: "us-east-1"
    resolveContactPoints: true
    contactPoints: "cassandra.us-east-1.amazonaws.com:9142"
    requestPageSize: 3500
    requestTimeout: 3
    requestConsistency: "LOCAL_QUORUM"
    reconnectOnInit: true
    sssEngineFactoryClass: "DefaultSslEngineFactory"
    sslHostnameValidation: true

问题分析

核心错误是java.security.KeyManagementException: problem accessing trust store,说明Docker容器内无法找到Cassandra的信任证书文件:

  1. Dockerfile中已将cassandra_truststore.jks复制到容器的/app目录,但application.yml里的trustStoreUrl配置的是本地开发路径./src/main/resources/cassandra_truststore.jks,容器内不存在这个路径,导致SSL连接初始化失败,进而引发后续Cassandra相关Bean(如cassandraTemplate、visitorsRepository)创建失败,最终导致Controller依赖注入异常。
  2. 次要问题:VisitorService同时使用@RequiredArgsConstructor和@Autowired注入仓库,手动创建Bean时@Autowired可能无法正常生效,不符合Spring依赖注入最佳实践。

解决方案

1. 修正信任证书路径

修改application.yml中的trustStoreUrl为容器内实际路径:

trustStoreUrl: "file:/app/cassandra_truststore.jks"

或利用容器工作目录/app,简化为:

trustStoreUrl: "./cassandra_truststore.jks"

2. 修复Service的依赖注入

改用构造器注入替代@Autowired,确保手动创建Bean时依赖能正确注入:

  • 更新VisitorService:
@RequiredArgsConstructor
@Slf4j
public class VisitorService {
    private final VisitorsRepository repository;

    public ApiResponse execute(VisitorDto dto){
        // 原有业务逻辑保持不变
    }
}
  • 更新ServiceConfiguration:
@Configuration
public class ServiceConfiguration {

    @Bean
    public VisitorService getVisitorService(VisitorsRepository repository){
        return new VisitorService(repository);
    }
}

3. 验证容器内文件(可选)

若仍有问题,可临时修改Dockerfile的ENTRYPOINT进入容器检查文件:

ENTRYPOINT ["bash"]

运行容器后执行ls /app,确认cassandra_truststore.jks存在,确保复制步骤无误。


内容的提问来源于stack exchange,提问作者Michael Torres Ospina

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:24:59