[문제 해결] Gradle 빌드 실패: kaptGenerateStubsKotlin 오류와 Gradle Daemon 초기화
백엔드 서버를 빌드하는 과정에서 원인을 알기 힘든 Gradle 빌드 오류가 발생했습니다.
Bash
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':kaptGenerateStubsKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction
> Internal compiler error. See log for more details
Kotlin 코드를 처리하는 kapt 작업 중 컴파일러 내부에서 문제가 발생.
Amazon Corretto란?
OpenJDK의 장기 지원(LTS) 버전으로, Amazon에서 성능 개선 및 보안 패치를 추가한 신뢰성 높은 무료 OpenJDK 배포판입니다.
다음 단계를 통해 jenv로 Corretto 11을 정상적으로 설정했습니다.
jenv에 새로운 JDK 경로 추가
jenv add /Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
jenv에 등록된 JDK 버전 확인
jenv versions
현재 프로젝트(local)의 Java 버전 지정
jenv local corretto64-11.0.28
# jenv global corretto64-11.0.28
Gradle Daemon은 빌드 속도를 높이기 위해 백그라운드에서 실행되는 프로세스인데, 때로는 이전의 잘못된 설정이나 상태를 계속 붙잡고 있어 문제를 일으킬 수 있습니다.
따라서 다음과 같이 실행 중인 모든 Gradle Daemon 프로세스를 강제 종료하고, 프로젝트를 깨끗하게(clean) 정리한 후 다시 빌드를 시도했습니다.
# 시스템에 실행중인 모든 Gradle Daemon 중지
gradle --stop
# 프로젝트의 Gradle Wrapper Daemon 중지
./gradlew --stop
# 프로젝트 빌드 결과물 삭제
./gradlew clean
# 프로젝트 새로 빌드
./gradlew build
Kotlin 관련 빌드 오류 발생 시 JDK 호환성을 우선적으로 점검하는 것이 좋겠습니다.
환경 변수나 설정을 변경한 후에도 문제가 해결되지 않는다면, Gradle Daemon의 상태를 의심하고 --stop과 clean을 통해 초기화하는 것으로 해결이 될 수 있습니다.
추가적인 개념기록
1. Gradle 이란?
gradle은 CI/CD를 위해 다음의 작업들을 자동화해준다. 코드 컴파일, 테스트, 패키징, 의존성 관리, 배포
소스코드를 실행가능한 파일로 바꾸는 과정을 빌드라고 한다.
빌드 도구로는 Ant, Mave, Gradle 등이 있는데, 이 중 Gradle은 캐싱을 이용하기 때문에 비교적 빠른 속도로 빌드가 가능하다.
2. Gradle 의 작동 단계
gradle은 groovy언어를 기반으로 하며, 초기화->구성->실행으로 작동한다.
3. Gradle Daemon
위에 언급했다 시피, Gradle은 캐싱을 이용하는 데 이는 Gradle Daemon이 수행한다. Gradle Daemon은 빌드 간 정보를 유지하는 백그라운드 프로세스로, 빌드 시 필요한 데이터를 캐싱하며 후속 빌드에서 빌드 시간을 단축시킨다.
고로 빌드를 자주 수행하지 않는 경우 오히려 메모리를 잡아먹기에 다음과 같이 데몬없이 빌드도 가능하다.
/gradlew clean build --no-daemon
4. JVM 입장에서의 Gradle
JVM관점에서 Gradle 실행 시 사용자 요청을 아래와 같이 처리한다.

Gradle Client JVM에 사용자 요청이 전달되면, Gradle Daemon JVM에 요청을 보낸다. 데몬은 전달된 build script를 실행하고 결과를 gradle client jvm에 반환한다. build 실행 이후 gradle client jvm은 종료되지만 jvm은 일정시간동안 gradle을 계속 실행될 수 있게 데몬으로 실행된다.
5. Gradlew 이란?
Gradle Wrapper는 gradle/wrapper/gradle-wrapper.jar을 이용해 gradle daemon실행을 위한 프로세스를 올린다.
다운받아 사용하는 Gradle과 달리 jvm에서 프로세스가 실행되면 gradle/wrapper/gradle-wrapper.properties에 선언된 특정 버전의 gradle 배포를 찾아 다운로드하고, 동일하게 jvm내에서 빌드를 진행한다.
이전 데몬에게 빌드를 시키기에 환경변수 바꾸었을 때 못알아차린 것.