Spring Boot가 아닌 바닐라 Java로 만든 프로젝트를 빌드하다보니 생긴 오류들이있다.
오랜만에 다시 겪어보니 Spring Boot, Intellij가 참 많은 것들을 내부적으로 해주고 있구나 싶었음
1. .jar에 기본 Manifest 속성이 없습니다.
JAR 파일을 실행할 때 어느 클래스가 진입점인지 모르기 때문에 발생한다. 자신의 애플리케이션의 진입점이 되는 클래스를 'Main-Class' 옆에 적어주자. 이때 패키지명을 함께 적어야 한다. 나의 경우 webserver 패키지의 WebServer.java 여서 아래와 같이 적었다.
jar {
manifest {
attributes 'Main-Class': 'webserver.WebServer'
}
2. 외부 의존성을 찾을 수 없는 에러가 발생하는 경우
나의 경우 java.lang.ClassNotFoundException: org.slf4j.LoggerFactory 이런 식으로 slf4j의 logger factory를 찾을 수 없다고 나왔다. 인텔리제이에서 실행했을 때는 이상없다가 gradle build 성공하고 java -jar로 실행시키니까 에러가 발생해서 다소 황당했다.
알고보니 그냥 Gradle Build할 경우 외부 의존성들이 JAR 파일 안에 들어가지 않는다. 이런 외부 의존성이 모두 포함되어 바로 실행가능한 Jar 파일을 Fat-JAR라고 한다. Spring Boot의 경우 이를 알아서 잘 딱 맞게 빌드해준다. 하지만 그냥 빌드하는 경우는 그런 거 없다.
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
- configurations.runtimeClasspath.collect가 필요한 모든 라이브러리 경로를 가져와준다.
- 이후 it.isDirectory() ? it : zipTree(it)로 디렉토리인 경우 그대로, 파일인 경우 압축 파일로 변환해서 사용하게 하고
- duplicatesStrategy = DuplicatesStrategy.EXCLUDE 이 전략이 중복된 라이브러리가 불러와질 경우 제외하는 방식으로 하여 충돌을 피했다. (is a duplicate but no duplicate handling strategy has been set 에러가 뜨면 추가해주자)