[QueryDSL] Q클래스 생성 오류 해결 (Error, Unsupported Java)
1. 개요
최근 QueryDSL 개발 중 Q 클래스 생성 오류 문제에 직면했는데, 해결해서 지금은 잘 작동을 하게 되었습니다.
그런데 골칫덩어리 빌드 생성 문제가 계속 나타날 것 같아 히스토리를 남기고 해결 방법을 공유하고자 합니다.
2. 오류
unsupported java. your build is currently configured to use java 21.0.1 and gradle 8.4.
- 위 오류 발생으로 Q 클래스 빌드 안됨
3. 해결과정
- 오류 스펙 : Java 21 (zulu 21) + Gradle 8.5 + lombok 1.8.30 스펙에서 빌드가 안돼서 구글링을 해보니 아래 스펙들의 버전이나 호환문제로 QueryDSL Q파일 생성 방법이 다르다고 하여 몇 차례 해결 시도 내용을 적어봅니다.
Spring boot
Java
Gradle
Lombok
IntelliJ
🤔 정말 위 스펙들의 버전이나 호환성 문제인가? 일단 구글링을 통해서 해결을 하고 찾을 수 있는 원인은 알아가보자!
3.1. 1차
- Gradler과 lombok 버전의 문제가 있을 수도 있다 해서, 아래 버전으로 맞춰서 빌드를 해봤다.
- Java 21 (zulu 21) + Gradle 8.4 + lombok 1.8.30
나이스 성공적~!
3.2. 2차
- 개발 수정으로 Q 클래스 다시 빌드해야 되는데, 빌드 과정에서 상위에 기입한 unsupported java. your build is currently configured to use java 21.0.1 and gradle 8.4. 빌드 오류가 났다.
갑자기 또 왜 안돼? ㅋㅋㅋㅋ
clean 누르고, 캐시도 비우고, 프로젝트 껐다 반복도 하고, 난리를 치다가 안돼서 결국 퇴근했다.
퇴근 후 헬스하고 단백질 섭취 한 다음에 TDD 수행을 했다.
- TDD 팝콘 섭취 수행 이후, 다시 검색을 해봤다.
- 인프런에서 영한님 답변 + 여러 수강생분들이 해결한 사례를 토대로 설정 변경도 해봤지만 빌드 실패했다.
3.3. 3차
- 아침에 출근 후 차분히 구글링을 하다가 stack overflow에서 QueryDSL 릴리스 노트의 힌트를 얻었다는 답변을 보게 되었다.
- 내용 보니깐 querydsl-apt가 querydsl-jpa에 종속성으로 포함되어 있어 두 버전을 맞춰줘야 한다는 내용이었다.
- dependencyManagement에서 querydsl 버전을 가져오지 못하는 것 같다.
- jpa 버전에 맞춰서 apt 버전을 명시해 주니 다시 빌드가 잘됐다.ㅎㅎㅎㅎ
릴리스 노트 :
http://querydsl.com/releases.html
https://github.com/querydsl/querydsl/issues/373
matthewadams님, mr.cat님 덕분에 해결해서 정말 다행이다.
querydsl 좀 예민해서 빌드 생성 오류 문제가 종종 발생할 것 같은데, 해결하게 되면 해당 포스팅 글에 계속 업데이트할 예정이다.
실질적인 상세 해결 방법은 4번 항목을 참고해 주세요.
4. 해결방법
현재 나의 프로젝트 기술 스펙에는 아래와 같은 버전과 설정으로 사용하는 게 맞다는 걸 알게 되어 공유합니다.
- Java 21 (zulu-21)
- Spring boot 3.2.1
- Gradle 8.5
- Querydsl 5.0
- Lombok 1.18.30
- IntelliJ Idea
- Build and Run : IntelliJ
- Run tests using : IntelliJ
- 설정을 Gradle로 변경하고 빌드해 보라는 블로그 글을 봤었는데, 안돼서 IntelliJ로 설정해 줬다.
build.gradle 의존성 교체 🌟
# 기존
dependencies {
.. 생략
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
.. 생략
}
# 수정
dependencies {
.. 생략
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
.. 생략
}
- 의존성을 간략하게 보겠습니다.
- Querydsl 사용하려면 Q 클래스를 생성해야 하는데, 소스 코드 레벨에서 Querydsl 관련 어노테이션들을 처리하고 쿼리 타입 클래스들을 생성해 주는 역할을 querydsl-apt가 해줍니다.
- gradle 프로젝트에서는 Querydsl 처리를 위해 annotationProcessor가 필요하고 com.querydsl:querydsl-apt 그룹 및 아티팩트를 dsl 버전 기입, :jakarta는 QueryDSL이 사용하는 모듈 시스템을 지정합니다. (java ee -> jakarta ee로 명칭을 변경했죠)
build.gradle (상세 - Querydsl 빌드 옵션 포함)
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.1'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.exflyer'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '21'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
// Web
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.googlecode.json-simple:json-simple:1.1.1'
// DB
//implementation 'com.mysql:mysql-connector-j:8.2.0'
runtimeOnly 'com.mysql:mysql-connector-j:8.2.0' // 8.x 버전 이상
runtimeOnly 'com.h2database:h2'
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// QueryDSL
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" // 수정
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// Api Docs
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
// Slack
implementation 'com.slack.api:slack-api-client:1.36.1'
// Amazon SES
implementation 'com.amazonaws:aws-java-sdk-ses:1.12.472'
implementation 'com.amazonaws:aws-java-sdk-sesv2:1.12.512'
implementation 'javax.mail:mailapi:1.4.3'
// Amazon SQS
implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.1")
implementation 'io.awspring.cloud:spring-cloud-aws-starter-sqs'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-aws-messaging', version: '2.2.6.RELEASE'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-aws-autoconfigure', version: '2.2.6.RELEASE'
//kafka
implementation 'org.springframework.kafka:spring-kafka'
testImplementation 'org.springframework.kafka:spring-kafka-test'
implementation 'org.springframework.cloud:spring-cloud-stream'
implementation 'org.springframework.cloud:spring-cloud-stream-binder-kafka'
implementation 'org.springframework.kafka:spring-kafka'
testImplementation 'org.springframework.cloud:spring-cloud-stream-test-binder'
testImplementation 'org.springframework.kafka:spring-kafka-test'
}
ext {
set('springCloudVersion', "2023.0.0")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
// QueryDSL 빌드 옵션 (선택) ~
def querydslSrcDir = 'src/main/generated'
clean {
delete file(querydslSrcDir)
}
tasks.withType(JavaCompile) {
options.generatedSourceOutputDirectory = file(querydslSrcDir)
}
// ~ Querydsl
gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
마무리
Q파일 빌드 실패 시, QueryDSL 연관된 의존성 lib 종속성도 확인해야 한다는 것을 알았다.
관련 오류가 나는 분들이라면 jpa랑 apt 버전을 동일하게 맞추거나 호환 버전을 확인 후에 수정해 보시는 것도 해결하는데 도움이 되지 않을까 싶습니다. 도움이 되길 바라며 이상 글 마무리 하겠습니다. 😀