우리가 스프링 부트를 멀티 모듈로 설계하고 처음으로 루트 모듈을 빌드하다 보면 다음과 같은 에러를 흔하게 접한다.
Main class name has not been configured and it could not be resolved from classpath
루트 모듈에서는 실행할 스프링 부트 애플리케이션을 실행할 main 함수가 없기 때문이다.
이에 관한 예외를 해결하는 3가지 방법을 알아보자.
실습을 진행한 모듈은 다음과 같다.
1. 직접적인 mainClassName 지정
루트 모듈 build.gradle 또는 build.gradle.kts에 아래와 직접적으로 mainClassName을 지정한다.
//build.gradle의 경우
bootJar {
mainClassName = 'template.api.ApiApplication'
mainClassName = 'template.batch.BatchApplication'
}
//build.gradle.kts의 경우
springBoot {
mainClass.set("template.api.ApiApplication")
mainClass.set("template.batch.BatchApplication")
}
실행을 해보면 잘 돌아가는 것을 확인할 수 있다.
./gradlew :application:api:bootRun
./gradlew :application:batch:bootRun
실행할 애플리케이션은 api, batch 2개다.
직접 테스트를 해보니 ApiApplication을 적지 않아도 api 모듈을 bootRun할 때 실패하지는 않았다.
그래도 소통을 위해 2개의 애플리케이션을 모두 작성하는게 맞다고 생각하며 개발자가 관리해야할 포인트라고 볼 수 있다.
2. bootJar와 jar 명령어 활용
tasks.getByName("bootJar") {
enabled = false
}
tasks.getByName("jar") {
enabled = true
}
루트 모듈의 build.gradle.kts 다음을 추가한다.
마찬가지로 루트 모듈을 빌드를 한 후 실행을 해도 잘 동작한다.
3. 스프링 부트 플러그인 적용 false 처리
먼저 해결 방법을 살펴보자. 아래와 같은 코드를 build.gradle, build.gradle.kts에 추가한다.
스프링 부트 플러그인은 종속성 관리, 애플리케이션 실행, 패키징, 테스트와 같은 다양한 사용할 수 있게 한다.
//build.gradle
id 'org.springframework.boot' version '3.3.2' apply(false)
//build.gradle.kts
id("org.springframework.boot") version "3.3.2" apply false
Spring Boot 플러그인을 루트 레벨에 적용하면 루트 모듈은 Spring Boot 애플리케이션으로 인식된다.
정확하게 말하면 루트 모듈은 Spring Boot 애플리케이션이 아니므로 apply를 false로 적용하는게 올바르다고 생각한다.
필자는 본인의 프로젝트에 3번째 방법을 적용했다.
2번째 방법을 선택하지 않은 이유는 루트 모듈이 애초에 Spring Boot 애플리케이션이 아니라 택하지 않았다.
여담이지만 우리가 주제로 하고 있는 예외는 org.springframework.boot.gradle.plugin 패키지에서 발생한 것이다.
여기서부터 플러그인과 관련한 문제라고 추론할 수 있다..!
이상으로 포스팅을 마칩니다. 감사합니다.
댓글