JDK 21과 Gradle 호환성 에러: 원인 분석과 실질적 해결 방안

2023. 12. 21. 17:36Gradle

728x90

문제 상황

최근 Oracle OpenJDK 21을 사용하여 프로젝트를 구축하던 중, 예상치 못한 에러가 발생했습니다.

아래는 해당 에러의 스크린샷입니다.

Unsupported class file major version

알고 가는 기본 개념

1. Gradle 이란 무엇인가?

Gradle helps teams build, automate and deliver better software, faster.
[출처] : https://gradle.org

Gradle은 "Build 자동화 도구"로 정의될 수 있습니다.

간단히 말해, 소프트웨어 개발 과정에서 반복되는 빌드 작업을 자동화하여

개발자가 더 빠르고 효율적으로 소프트웨어를 제작할 수 있게 돕습니다.

 

2. 그렇다면 Build 란?

build is the process of converting source code files into standalone software artifact(s)
that can be run on a computer, or the result of doing so.

[의역] : 소스 코드들을 컴퓨터에서 독립적으로 실행시킬 수 있는 아티팩트로 만드는 과정
[출처] : https://en.wikipedia.org/wiki/Software_build

빌드(build)란 소스 코드와 기타 필요한 파일들을 컴퓨터가 실행할 수 있는 형태로 변환하는 과정을 말합니다.

Java 의 경우 .jar 파일이 Build 를 거친 후의 형태이죠.

 

3. JDK란 무엇인가?

The Java Development Kit (JDK) is a cross-platformed software development environment that
offers a collection of tools and libraries necessary for developing Java-based software applications and applets.

[의역] : 
[출처] : https://www.geeksforgeeks.org/jdk-in-java/

JDK(Java Development Kit)는 Java 프로그래밍 언어로 소프트웨어를 개발하는 데 필요한 소프트웨어 개발 키트입니다.

주요 구성 요소로는 다음과 같습니다.

  1. Java 컴파일러(javac)  - .java -> .class 로 번역
  2. Java 런타임 환경(JRE) - JVM + JRE 에서 사용하는 기타 라이브러리
  3. 클래스 라이브러리 및 여러 도구

들이 포함됩니다.

문제의 원인 분석

이 에러를 이해하기 위해서는 Gradle이 컴파일 과정에서 어떻게 동작하는지, 그리고 JDK와의 상호 작용을 이해할 필요가 있습니다.

Gradle이 JDK의 버전을 알아야 하는 이유는 Gradle이 Java 프로젝트를 빌드하는 과정에서 JDK의 도구와 기능을 사용하기 때문입니다. 이해를 돕기 위해 몇 가지 핵심 포인트를 정리해보겠습니다:

  • 컴파일러 호환성: Gradle은 Java 소스 코드를 컴파일하기 위해 JDK에 포함된 Java 컴파일러(javac)를 사용합니다. 각 JDK 버전은 특정 버전의 Java 언어 사양을 지원합니다. 예를 들어, JDK 11은 Java 11의 새로운 언어 기능을 지원합니다. Gradle이 JDK의 버전을 알아야 하는 이유는, Gradle이 프로젝트를 올바르게 컴파일하려면 사용 중인 Java 코드와 호환되는 JDK 버전을 사용해야 하기 때문입니다.
  • API 및 기능 사용: Gradle은 빌드 과정에서 JDK가 제공하는 다양한 API와 기능을 사용합니다. 예를 들어, 파일 시스템 작업, 네트워크 통신, XML 파싱 등 JDK가 제공하는 기능들이 빌드 스크립트에 사용될 수 있습니다. JDK의 새 버전은 새로운 API와 기능을 제공하며, 이는 Gradle이 최신 Java 기능을 사용하는 프로젝트를 지원하기 위해 해당 JDK 버전을 알아야 함을 의미합니다.
  • 성능 최적화 및 보안 개선: JDK의 새로운 버전들은 보통 성능 개선과 보안 강화를 포함합니다. Gradle이 이러한 개선 사항을 활용하기 위해서는 최신 JDK 버전과 호환되는지 확인해야 합니다. 
  • 바이트코드 호환성: JDK Java 소스 코드를 바이트코드로 컴파일합니다. JDK 버전은 특정 포맷의 클래스 파일과 바이트코드를 생성합니다. 이러한 바이트코드는 JDK 런타임 환경(JRE)에서만 실행될 있으며, 때로는 버전의 JDK에서만 실행되는 새로운 바이트코드 형식이 도입됩니다. Gradle 올바른 JDK 버전을 사용함으로써, 생성된 바이트코드가 예상대로 실행될 있도록 보장합니다.

그렇기 때문에 Gradle 버전마다 지원하는 JDK 버전이 다르며, 구 버전의 Gradle은 새로운 버전의 JDK를 지원하지 않습니다.

제 경우, "Unsupported class file major version 65"라는 에러가 발생합니다.

 

본 프로젝트에서 사용되는 JDK 21은 현재 사용 중인 Gradle 8.0 버전과 호환되지 않습니다.

다시 말해 Gradle 8.0 은 JDK 21 을 가지고 빌드를 못한다! 라고 볼 수 있습니다.

해결 방안

해결책은 JDK 21을 지원하는 Gradle 버전으로 업그레이드하는 것입니다.

(또는 JDK 21 를 사용해서 Build 를 할 줄 아는 Gradle 로 업그레이드 하기)

 

현재 프로젝트의 Gradle 버전은 [project root directory]/gradle/wrapper/gradle-wrapper.properties 에서 확인할 수 있습니다.

distributionUrl 에 8.0 임을 알 수 있다.

JDK 21을 지원하는 Gradle 버전은 8.4 이상입니다.

Gradle 8.4 Release Notes 링크에서 확인할 수 있습니다.

gradle-wrapper.properties 파일의 distributionUrl 값을 수정하면 IDE가 자동으로 필요한 버전을 다운로드하도록 설정할 수 있습니다.

8.0 -> 8.5 로 변경

변경 후에는 Gradle refresh 버튼을 클릭하여 업데이트를 진행합니다.

우측 상단 업데이트 버튼

이러한 변경 후 프로젝트를 다시 실행하면 정상적으로 작동하는 것을 확인할 수 있습니다.

에러없이 잘 작동이 된다.

결론: Gradle JDK 버전의 중요성

이 문서를 통해 우리는 Gradle과 JDK의 상호 작용과 그 중요성에 대해 깊이 이해할 수 있었습니다.

특히, Gradle이 JDK의 버전을 알고 있어야 하는 이유를 중점적으로 살펴보았습니다.

  • 컴파일러 호환성: Gradle은 Java 소스 코드를 컴파일하기 위해 JDK의 javac를 사용합니다. JDK의 각 버전은 해당 버전의 Java 언어 사양을 지원하므로, Gradle이 올바른 JDK 버전을 사용하는 것은 프로젝트의 성공적인 컴파일을 보장하는 데 중요합니다.
  • API 및 기능 활용: JDK의 새로운 버전들은 새로운 API와 기능을 제공합니다. Gradle이 이러한 최신 기능을 활용하기 위해서는 호환되는 JDK 버전을 사용해야 합니다.
  • 성능 최적화 및 보안 개선: JDK의 새 버전은 성능 개선과 보안 강화를 제공합니다. Gradle이 이러한 개선을 활용하기 위해서는 최신 JDK 버전과의 호환성이 필요합니다.
  • 바이트코드 호환성: JDK는 Java 소스 코드를 바이트코드로 컴파일하고, 이 바이트코드는 JDK의 런타임 환경에서 실행됩니다. Gradle이 적절한 JDK 버전을 사용함으로써 생성된 바이트코드가 올바르게 실행되도록 보장합니다.

이러한 이유로, Gradle이 JDK의 버전을 정확히 파악하고 사용하는 것은

Java 프로젝트의 빌드 과정에서 매우 중요합니다.

 

"Unsupported class file major version" 에러의 경우도 JDK 21과 호환되지 않는 Gradle 버전 때문에 발생한 것으로,

JDK 버전과 Gradle 버전 간의 호환성이 중요한 역할을 한다는 것을 알 수 있습니다.

 

728x90