강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

bebe님의 프로필 이미지
bebe

작성한 질문수

6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법

Gradle Build 시 에러 발생

해결된 질문

작성

·

63

·

수정됨

2

1. 현재 학습 진도

  • 몇 챕터/몇 강을 수강 중이신가요?

    • 2-7강

       

  • 여기까지 이해하신 내용은 무엇인가요?

    • git Action CI/CD

 

2. 어려움을 겪는 부분

  • 어느 부분에서 막히셨나요?

    • git push 후 workflow에서 Gradle 빌드 실패

  • 코드의 어떤 로직이 이해가 안 되시나요?

  • 어떤 개념이 헷갈리시나요?

 

3. 시도해보신 내용

  • 문제 해결을 위해 어떤 시도를 해보셨나요?

  • 에러가 발생했다면 어떤 에러인가요?

    • git push 후 workflow에서 Gradle 빌드 실패

  • 현재 작성하신 코드를 공유해주세요

     

빌드를 진행할 때 먼저 3개의 테스트에서 실패합니다.

SimpleEventListenerTest > 현재 코드 구조에서 @TransactionalEventListener는 작동하지 않는다 FAILED
    java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143
        Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1770
            Caused by: jakarta.persistence.PersistenceException at AbstractEntityManagerFactoryBean.java:421
                Caused by: org.hibernate.exception.JDBCConnectionException at SQLExceptionTypeDelegate.java:49
                    Caused by: java.sql.SQLNonTransientConnectionException at SQLError.java:111
SimpleEventListenerTest > @TransactionalEventListener는 활성 트랜잭션이 필요하다 FAILED
    java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143
        Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1770
            Caused by: jakarta.persistence.PersistenceException at AbstractEntityManagerFactoryBean.java:421
                Caused by: org.hibernate.exception.JDBCConnectionException at SQLExceptionTypeDelegate.java:49
                    Caused by: java.sql.SQLNonTransientConnectionException at SQLError.java:111
SimpleEventListenerTest > @EventListener는 트랜잭션이 없어도 정상 동작한다 FAILED
    java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143
        Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1770
            Caused by: jakarta.persistence.PersistenceException at AbstractEntityManagerFactoryBean.java:421
                Caused by: org.hibernate.exception.JDBCConnectionException at SQLExceptionTypeDelegate.java:49
                    Caused by: java.sql.SQLNonTransientConnectionException at SQLError.java:111

이후, Redis에 Reconnecting 하려고 시도하지만 Connection이 Refused되면서 빌드에 실패합니다.

2025-08-21T08:34:32.560Z  INFO 2235 --- [xecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/127.0.0.1:32770
2025-08-21T08:34:32.570Z  WARN 2235 --- [ioEventLoop-8-2] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/<unresolved>:32770]: Connection closed prematurely
io.lettuce.core.RedisConnectionException: Connection closed prematurely
	at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:91) ~[lettuce-core-6.2.6.RELEASE.jar:6.2.6.RELEASE]

// 생략

로컬 환경과 AWS EC2 환경에서 동일하게 발생합니다.

 

해결 방법

gradle build를 5번 정도 시도했는데, 5번 중 4번은 SimpleEventListenerTest에서 테스트가 실패하고, 1번은 다른 Test에서 실패하였습니다.

그래서, SimpleEventListenerTest에 대해 개별 테스트를 진행해보니 통과하였습니다.

전체 테스트 진행에서는 JDBC Connection 관련 오류가 발생했고, 개별 테스트 진행에서는 문제가 발생하지 않는다는 점에서 커넥션 풀 설정 문제를 의심하였습니다.

 

spring:
  datasource:
    url: jdbc:mysql://${RDS_ENDPOINT:localhost}:3306/portfolio?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true&useSSL=false&rewriteBatchedStatements=true
    username: portfolio_user
    password: ${RDS_PASSWORD:portfolio1234}
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maximum-pool-size: 32
@TestConfiguration
public class TestDatabaseConfig {
    
    @Container
    private static final MySQLContainer<?> mysqlContainer;

application.yml 의 최대 풀 사이즈는 32로 설정되어 있고, mySQL 컨테이너는 전역으로 설정되어 있으므로 병렬 처리 과정에서 커넥션 풀이 부족할 수 있겠다는 판단하에, maximum-pool-size를 100으로 늘려보았습니다.

package ding.co.backendportfolio.config;

import jakarta.annotation.PreDestroy;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Container;

@TestConfiguration
public class TestDatabaseConfig {
    
    @Container
    private static final MySQLContainer<?> mysqlContainer;

    static {
        mysqlContainer = new MySQLContainer<>("mysql:8.0.33")
                .withDatabaseName("testdb")
                .withUsername("test")
                .withPassword("test");
        mysqlContainer.start();

        // A) 기본 설정 + rewriteBatchedStatements 옵션
        String originalJdbcUrl = mysqlContainer.getJdbcUrl() + "?rewriteBatchedStatements=true";

        // TODO: BulkInsert 모니터링 - 아래 주석을 해제해야함
//        originalJdbcUrl = originalJdbcUrl + "&profileSQL=true&logger=Slf4JLogger&maxQuerySizeToLog=2147483647";

        System.setProperty("spring.datasource.url", originalJdbcUrl);
        System.setProperty("spring.datasource.username", mysqlContainer.getUsername());
        System.setProperty("spring.datasource.password", mysqlContainer.getPassword());

        // 커넥션 풀 늘리기
        System.setProperty("spring.datasource.hikari.maximum-pool-size", "100");
        System.setProperty("spring.datasource.hikari.minimum-idle", "10");
    }

    @Bean
    public MySQLContainer<?> mySQLContainer() {
        return mysqlContainer;
    }

    @PreDestroy
    public void stop() {
        if (mysqlContainer != null && mysqlContainer.isRunning()) {
            mysqlContainer.stop();
        }
    }
} 

이후 테스트를 진행해보니, 기존에 작성해두신 커넥션 풀 테스트인 EventJoinWithExternalConnectionPoolTest를 제외하고 테스트에 통과하였습니다.

따라서, EventJoinWithExternalConnectionPoolTest이 테스트에만 작은 커넥션 풀을 적용하도록 하였습니다.

@Slf4j
@IntegrationTest
// 커넥션 설정
@TestPropertySource(properties = {
    "spring.datasource.hikari.maximum-pool-size=32",
    "spring.datasource.hikari.minimum-idle=5"
})
class EventJoinWithExternalConnectionPoolTest {
image.png

문제가 발생한 원인은, Gradle 병렬 테스트 진행 시 커넥션 풀이 부족하여 커넥션이 이뤄지지 않았던 것 같습니다.

사실 최대 커넥션 풀을 100개로 늘리는 건 임시방편인 것 같고, 테스트별로 독립적인 컨테이너 환경을 만들어주는게 좋을 것 같다고 생각합니다.

 

P.S.) GPT, 클로드코드, Cursor, ... 다 문제 원인을 파악하지 못하더라고요 ㅎㅎ

답변 3

0

딩코딩코님의 프로필 이미지
딩코딩코
지식공유자

안녕하세요 bebe님 좋은 문제 분석과 해결 과정을 공유해주셔서 감사합니다!!!!

아고 제가 통합테스트를 염두해두고 만들지 않고, 개별 학습 사항에 대한 테스트 묶음으로만 관리를 해왔던터라 전체 테스트 시 발생할 문제를 고려하지 않았습니다 ㅜㅠ

테스트별로 독립적인 컨테이너 환경을 구축하도록 변경해 학습에 불편함이 없도록 해보겠습니다

넘넘 딥한 해결방안 검토 및 분석 진행해주셔서 넘 감사합니다!! ㅎㅎㅎ 원인을 분석하고 해결하려고 하신 모습 넘넘 좋습니다!!

0

와....진짜 감사합니다... 진짜 계속 헤맸는데 ㅠㅜㅠ

0

안녕하세요, 인프런 AI 인턴입니다. bebe님.

현재 경험하고 계신 문제는 GitHub Actions와 관련한 빌드 실패로 보이며, 다양한 요인에 의해 발생할 수 있습니다. 말씀하신 에러 메시지를 통해 두 가지 주요 문제로 압축될 수 있습니다: 데이터베이스 연결 문제와 Redis 연결 문제입니다.

1. 데이터베이스 연결 문제:

에러 로그에 “JDBCConnectionException”이 반복적으로 나타나고 있어 데이터베이스 연결 문제를 의심할 수 있습니다.
- 로컬 설정 확인: application.yml 또는 application.properties 파일에서 데이터베이스 설정 정보를 다시 확인해 주세요. 특히, 데이터베이스 URL, 사용자, 비밀번호가 올바른지 확인해야 합니다.
- CI 환경 변수 설정: GitHub Actions에서 데이터베이스에 접근할 수 있도록 올바른 환경 변수가 설정되어 있는지 확인하세요. Repository secrets에 필요한 키(예: DB_URL, DB_USERNAME, DB_PASSWORD)를 사용한 설정을 검토해보세요.

참고자료: Spring Boot와 MySQL 연결 에러 해결

2. Redis 연결 문제:

Redis 연결이 실패하며 ‘Connection closed prematurely’ 에러가 발생하고 있습니다.
- Redis 서버 상태 확인: Redis 서버가 실행 중인지 확인하고, 포트가 제대로 노출되어 있는지 확인하세요. 컨테이너 간 연결이 필요한 경우 Docker Compose 파일에서 설정이 올바른지 재점검하세요.
- 올바른 호스트 사용: localhost 대신 Docker Compose에서 정의한 서비스 이름을 사용해보세요.

참고자료: Docker 내 Redis 서비스 간 통신

추가 팁:

  • GitHub Actions 로그: 자세한 로그를 확인하여 문제의 근본 원인을 더 구체적으로 파악할 수 있습니다.
  • 환경 일관성 유지: 로컬 및 서버 환경 간 설정이 일치하는지 확인하세요.

도움이 되셨길 바라며, 이 문제가 해결되기를 바랍니다! 추가적인 질문이 있으시면 언제든지 해 주세요. 😊

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

bebe님의 프로필 이미지
bebe

작성한 질문수

질문하기