일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 리눅스
- MongoDB
- smart cast
- 파이썬 소스
- 자바
- jsp
- JVM
- 파이썬
- 알고리즘
- 유사코드
- resilience4j
- auto configure
- 오라클
- 자바 프로젝트
- gradle
- 오라클 디비
- K6
- 프로젝트
- 백준 알고리즘
- 초대장
- 운영체제
- dynamic query
- 티스토리
- spring
- 문법 정리
- 학점
- SQL
- oracle
- c#
- hyperledger
- Today
- Total
모종닷컴
멀티 모듈 프로젝트에서는 아카이브 이름도 조심해야 합니다. 본문
오늘은 정말 간단한 글 하나를 올려보려고 합니다. 내용은 멀티 모듈 프로젝트에서 모듈의 겹치는 이름으로 인해 겪은 삽질기입니다. 상황을 재현해보기 간단하게 세팅을 먼저 해보도록 하겠습니다.
프로젝트 구조
- 프로젝트는 projectA, projectB 두 개로 만들어져 있습니다.
- projectA는 app, domain 모듈을 지니고 있고, projectB는 domain 모듈만 지니고 있습니다.
projectA 빌드스크립트
- war 관련 파일 설정이 추가되어있습니다.
apply plugin: 'war'
bootWar {
mainClassName = "com.example.projectA.app.MainAppKt" // 코틀린 파일이 자바로 해석되면서 클래스명 뒤에 'Kt'가 붙는다
archiveName("${project.name}.war")
}
dependencies {
implementation project(":projectA:app")
}
subprojects {
bootJar.enabled = false
jar.enabled = true
}
project(":projectA:domain") {
}
project(":projectA:app") {
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation project(":projectA:domain")
implementation project(":projectB:domain")
}
}
Project-a:domain 모듈
@Component
class Coffee { val name = "coffee" }
Project-a:app 모듈
- 패키지 스캔에 주의
@SpringBootApplication(scanBasePackages = ["com.example.projectA.domain", "com.example.projectB.domain", "com.example.projectA.app"])
class MainApp
fun main(args: Array<String>) {
runApplication<MainApp>(*args)
}
@Component
class ReadyEventHandler(
val coffee: Coffee,
val donut: Donut
): CommandLineRunner {
override fun run(vararg args: String) {
println(coffee.name)
println(donut.name)
}
}
projectB 빌드 스크립트
project(":projectB:domain") {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
}
}
allprojects {
bootJar.enabled = false
jar.enabled = true
}
Project-b:domain 모듈
@Component
class Donut { val name = "donut" }
실행 결과
WAR를 실행
gradle build를 하거나 bootWar 태스크를 통해 war 파일을 만들고 해당 파일을 실행시켜보도록 하겠습니다. 저는 bootWar를 실행시켰고, 그 결과 아래 사진과 같은 경로에서 war 파일이 생성되었음을 알 수 있습니다.
그럼 이제 이 WAR를 실행시켜보겠습니다. 명령어는 java -jar projectA.jar입니다.
실행을 시키면 오류가 좀 길게 나올 텐데 주된 원인은 아래 사진과 같이 클래스를 찾을 수 없다입니다.
왜 클래스가 없다는 걸까 하고 war 파일의 압축을 풀어보았습니다. 그랬더니 굉장히 이상한 점이 있었습니다. projectA와 projectB의 domain 모듈을 의존하고 있는데 그 두 개의 파일 이름이 똑같다는 것이었습니다. 따라서 WAR를 만드는 과정에서 이름이 domain.jar인 파일이 두 개가 생성되었고, 그중 한 개가 덮어 쓰이는 바람에 클래스 정보가 없다고 하게 된 것이죠..
해결
해결법은 너무 간단합니다. jar 파일을 만들 때 네이밍 규칙을 정해주는 겁니다. jar.enabled = true 부분을 아래처럼 수정해주게 된다면 {부모 프로젝트의 이름}-{모듈 이름}. jar와 같은 형식으로 jar 파일이 만들어지게 됩니다. 예를 들면 projectA-domain.jar , projectB-domain.jar 와 같은 식으로요
jar {
archiveName("${parent.name}-${project.name}.jar")
setEnabled(true)
}
다음과 같은 방식으로 파일 이름을 정해주고 다시 bootWar로 생성 및 압축을 풀어보겠습니다. 그러면 아래 사진과 같이 정상적으로 domain.jar가 두 개가 보입니다.
다시 실행
그렇다면 이제 war를 다시 한번 실행해보도록 하겠습니다. 이제는 정상적으로 뜨고 있는 모습을 볼 수 있습니다.
'Programming > Spring' 카테고리의 다른 글
Spring MongoDB Transaction Support (0) | 2022.10.23 |
---|---|
테스트 코드에서 클래스 생성에 필요한 모든 클래스를 mocking (0) | 2022.10.10 |
멀티 모듈 프로젝트에서 다중 프로퍼티 파일 다루기 (0) | 2022.09.11 |
Mock Layer (0) | 2022.08.17 |
Quartz Job Scheduling 1편 - 소개 및 간단한 예제 (0) | 2022.08.14 |