일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
- Kafka
- group by group by rollup 차이
- IntelliJ
- 쓰기지연저장소
- dto매핑우선순위
- 컬럼명중복
- 쿼리실행사이트
- 자바
- 스트림
- Java
- 쿼리테스트사이트
- 쿼리실행순서
- JPA
- 설치없이쿼리실행
- 오라클쿼리테스트사이트
- Stream
- Oracle
- spring cloud stream
- Flush
- 쓰기지연sql저장소 쿼리실행순서
- hibernate 쿼리실행 순서
- 포트앤어댑터 아키텍처
- ls -lgaf
- port&adapter architecture
- error 2002 (hy000): can't connect to local mysql server through socket '/tmp/mysql.sock' (2)
- 중복컬럼dto매핑
- spring kakfa
- sql사이트
- sql 테스트 사이트
- 쿼리사이트
- Today
- Total
개린이 탈출기
[Maven/Gradle]라이브러리 버전 관리 시 Snapshot 과 release 의 처리 방식 차이 본문
최근에 maven 을 사용하는 프로젝트에서 갑자기 빌드가 되지 않는 문제를 마주했다.
조금 당황했지만, 문제가 되는 라이브러리에 대응되는 버전의 폴더를 삭제하고 maven 프로젝트를 새로고침한 뒤 재실행 하니 문제가 감쪽같이 해결되었다.
왜...?
SNAPSHOT 과 RELEASE의 차이
우선 SNAPSHOT 과 RELEASE 의 가장 큰 차이점 중 하나는 변경 가능성 이라고 생각한다.
SNAPSHOT은 개발 단계에서 주로 사용하는 버전으로, 보통 변경 가능성이 높은 경우 SNAPSHOT으로 배포한다.
동일한 버전으로 스냅샷을 배포하면 1.0.0-SNAPSHOT. 20241212.123456-1 와 같이 타임스탬프와 일련번호를 섞어 스냅샷 버전을 구분할 수 있도록 한다.
RELEASE 는 보통 변경 가능성이 크지 않은 경우이므로, 스냅샷과 같이 타임스탬프가 추가되거나 하지는 않는다.
의존성 라이브러리 관리
Maven
Maven은 프로젝트의 의존성을 가져올 때, 로컬 리포지토리, 원격 리포지토리(Nexus 등), Maven 중앙 리포지토리 순서로 가져온다.
여기서 SNAPSHOT과 RELEASE 버전에 따라 의존성 버전 처리 방식에 조금 차이가 발생한다.
RELEASE
RELEASE 버전의 경우 다음과 같다
우선적으로 로컬 리포지토리를 탐색한다.
로컬 리포지토리 경로 디폴트 위치(윈도우 기준)는 C:\Users\<사용자 이름>\.m2\repository 이며, 위치를 수정할 수 있다
해당 경로로 해당 되는 버전의 라이브러리가 존재한다면 더 이상 탐색하지 않고 기존에 다운받아놓은 jar 파일을 사용한다.
만일 해당하는 버전을 찾지 못한 경우 순차적으로 원격 리포지토리(Nexus 같은 원격 저장소), 중앙 Maven 리포지토리에서 찾는다.
SNAPSHOT
SNAPSHOT 버전은 변경 가능성이 있는 개발 버전이라 탐색 방식에 차이가 발생한다.
우선 해당하는 버전이 있는지 로컬 리포지토리를 먼저 확인한다. 없다면 원격 리포지토리에서 해당 스냅샷 최신 버전을 다운받아 사용한다.
만일 존재한다면, 설정해놓은 updatePolicy의 설정에 따라 원격 리포지토리에서 스냅샷 최신 버전을 찾아 비교한다.
원격 리포지토리의 버전이 더 최신 버전이라면 다시 다운받아 로컬에 덮어쓴다.
updatePolicy 의 설정 방법은 다음과 같다.
<profiles>
<profile>
<id>default</id>
<repositories>
<repository>
<id>repository1</id>
<url>http://repository1.sample.com/repository/snapshots</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
always | 항상 원격 리포지토리에서 최신 SNAPSHOT과 비교 |
daily | 하루에 한 번 원격 리포지토리에서 최신 SNAPSHOT과 비교 |
interval:정수 | (정수)분 간격으로 원격 리포지토리에서 최신 SNAPSHOT과 비교 |
never | 원격 리포지토리와 최신 SNAPSHOT을 비교하지 않음 |
Gradle
gradle은 maven과 약간 차이가 있다.
첫번째는 gradle은 기본적으로 라이브러리를 24시간동안 캐싱한다는 점이고,
두번째는 라이브러리 의존성을 가져올 리포지토리 순서를 build.gradle에 명시할 수 있다는 것이다.
다음은 build.gradle 의 예시이다
// 중략 //
allprojects {
group 'com.sample.poject'
version serviceVersion
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
}
def useMavenLocalFirst = false
subprojects {
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'java-library'
apply plugin: 'maven-publish'
apply plugin: 'signing'
apply plugin: 'io.spring.dependency-management'
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
repositories {
if (useMavenLocalFirst) {
mavenLocal()
}
maven {
credentials {
username System.getenv('NEXUS_ID') ?: nexususer
password System.getenv('NEXUS_PASSWORD') ?: nexuspassword
}
url "${nexusBaseUrl}/${nexusPublicRepository}"
allowInsecureProtocol = true
}
if (!useMavenLocalFirst) {
mavenLocal()
}
mavenCentral()
}
// 중략 //
RELEASE
해당 버전으로 캐싱되어 있는 라이브러리가 있다면 빌드 시, 원격 저장소를 방문하지 않는다
없다면 지정한 순서에 따라 원격 -> 로컬 -> 중앙 리포지토리 순서로 라이브러리를 가져올 것이다.
SNAPSHOT
해당 버전으로 캐싱되어 있는 라이브러리가 있다면 빌드 시, 원격 저장소를 방문하지 않는다.
그러나 상단에서 캐싱을 0초간 하겠다고 지정하였으므로
( configurations.all { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } )
캐싱된 라이브러리를 찾을 수 없어 매번 새롭게 라이브러리를 가져와야 할 것이다.
참고로 seconds, minutes, hours 등 다양하게 시간을 지정할 수 있다.
이때, build.gradle 에 명시한 순서에 따라원격 -> 로컬 -> 중앙 이므로 원격 리포지토리에 우선적으로 접근할 것이다.
문제가 어떻게 해결되었던 것인지 이제야 알았다.
문제가 되었던 라이브러리를 release 버전으로 종속성을 갖고 있었고, 해당 라이브러리에 버전업 없이 수정사항(클래스 추가 등)이 존재했기 때문이었다.
참고
Introduction to Repositories – Maven
Internal Repositories When using Maven, particularly in a corporate environment, connecting to the internet to download dependencies is not acceptable for security, speed or bandwidth reasons. For that reason, it is desirable to set up an internal reposito
maven.apache.org
Dependency Caching
The --offline command-line switch instructs Gradle to use dependency modules from the cache, regardless of whether they are due to be checked again. When running with offline, Gradle will not attempt to access the network for dependency resolution. If the
docs.gradle.org