Theme:

Pipeline에서 NoSuchFieldError가 발생했다면, Jenkins가 프로젝트와 다른 JDK 버전으로 빌드하고 있을 가능성이 높습니다.

문제 상황

Jenkins Pipeline 빌드 중 아래와 같은 에러가 발생했습니다.

PLAINTEXT
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile
(default-compile) on project $project_name: Fatal error compiling:
java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport
does not have member field 'com.sun.tools.javac.tree.JCTree qualid' -> [Help 1]

이 에러는 컴파일러 내부 API(com.sun.tools.javac)의 구조가 변경되었음을 의미합니다. 프로젝트가 의존하는 라이브러리(특히 Lombok 등)가 사용 중인 JDK 버전의 내부 API 변경을 반영하지 못할 때 발생합니다.

원인 분석

Jenkins에는 JDK 11, 17, 21 등 여러 버전이 등록되어 있을 수 있습니다. Pipeline 스크립트에서 JDK 버전을 명시하지 않으면, Jenkins 에이전트의 기본 JDK(예: JDK 21)로 빌드가 실행됩니다.

상황프로젝트 JDKJenkins 빌드 JDK결과
정상JDK 17JDK 17빌드 성공
문제JDK 17JDK 21 (기본값)내부 API 불일치로 빌드 실패

** 핵심 원인:** 프로젝트가 JDK 17 기반인데, Jenkins가 JDK 21로 빌드를 시도하면서 Lombok 등이 의존하는 JDK 내부 API 구조가 달라져 NoSuchFieldError가 발생한 것입니다.

해결 방법

1. Jenkins에 등록된 JDK 별칭(Name) 확인

Manage Jenkins > Tools > JDK installations 에서 사용하려는 JDK의 Name 값을 확인합니다.

예시:

NameJAVA_HOME
OpenJDK11/app/jdk-11
OpenJDK17/app/jdk-17
OpenJDK21/app/jdk-21

2. Pipeline 스크립트에 tools 블록 추가

Jenkinsfile의 tools 블록에서 프로젝트에 맞는 JDK 버전을 명시합니다.

GROOVY
pipeline {
    agent any

    tools {
        // Jenkins 관리 > Tools > JDK installations에서 등록한 Name 사용
        jdk 'OpenJDK17'
    }

    stages {
        stage('Verify JDK') {
            steps {
                sh 'java -version'
                sh 'echo $JAVA_HOME'
            }
        }

        stage('Build') {
            steps {
                sh 'mvn clean package -DskipTests'
            }
        }
    }
}

tools 블록에 지정한 JDK Name은 Jenkins의 JDK installations에 등록된 Name과 ** 정확히 일치 **해야 합니다. 대소문자도 구분하므로 주의하세요.

예방 방법

방법설명
tools 블록 항상 명시모든 Jenkinsfile에 JDK 버전을 명시하여 암묵적 버전 사용 방지
Lombok 버전 업데이트Lombok을 최신 버전으로 유지하면 상위 JDK 호환성 확보 가능
빌드 JDK 검증 단계 추가java -version 출력 단계를 추가하여 빌드 JDK 확인

Lombok과 같이 JDK 내부 API에 의존하는 라이브러리를 사용하는 프로젝트는 JDK 버전 관리에 특히 주의가 필요합니다. JDK 메이저 버전을 올릴 때는 반드시 해당 라이브러리의 호환성을 확인하세요.


정리

항목설명
근본 원인Pipeline에서 JDK 버전을 명시하지 않으면 Jenkins 에이전트 기본 JDK 사용
해결tools { jdk 'Name값' } 블록으로 JDK 버전 명시
Name 매칭Jenkins Tools의 JDK installations Name과 정확히 일치 (대소문자 구분)
예방모든 Jenkinsfile에 JDK 버전 명시 + Lombok 최신 버전 유지
댓글 로딩 중...