Maven-3 타임 스탬프 스냅 샷을 어떻게 효율적으로 처리합니까?


86

이제 maven-3이 스냅 샷 아티팩트에 대한 <uniqueVersion> false </ uniqueVersion>에 대한 지원 을 중단 했으므로 실제로 타임 스탬프가있는 SNAPSHOTS를 사용해야하는 것 같습니다. 특히 내부적으로 maven 3을 사용하는 m2eclipse는 영향을받는 것으로 보이며 SNAPSHOTS가 고유하지 않으면 업데이트-스냅 샷이 작동하지 않습니다.

모든 스냅 샷을 uniqueVersion = false로 설정 하기 전에는 모범 사례 처럼 보였습니다.

이제는 타임 스탬프 버전으로 전환하는 것이 큰 문제가 아닌 것 같습니다. 결국 정기적으로 오래된 스냅 샷을 삭제할 수있는 중앙 넥서스 저장소에 의해 관리되기 때문입니다.

문제는 로컬 개발자 워크 스테이션입니다. 그들의 로컬 저장소 는 고유 한 스냅 샷으로 빠르게 매우 커집니다.

이 문제를 처리하는 방법?

지금 나는 다음과 같은 가능한 해결책을 봅니다.

  • 개발자에게 정기적으로 저장소를 제거하도록 요청하십시오 (삭제하는 데 오랜 시간이 걸리고 필요한 모든 것을 다운로드하는 데 더 오랜 시간이 걸리기 때문에 많은 좌절로 이어집니다)
  • 로컬 저장소에서 모든 SNAPSHOT 디렉토리를 삭제하는 스크립트를 설정하고 개발자에게 때때로 해당 스크립트를 실행하도록 요청합니다 (첫 번째 것보다 더 좋지만 현재 스냅 샷을 실행하고 다운로드하는 데는 여전히 상당한 시간이 걸립니다).
  • dependency : purge-local-repository 플러그인 사용 (파일이 열려 있으므로 Eclipse에서 실행할 때 문제가 있으며 각 프로젝트에서 실행해야 함)
  • 모든 워크 스테이션에 nexus를 설정하고 오래된 스냅 샷을 정리하는 작업을 설정합니다 (최상의 결과이지만 50 개 이상의 nexus 서버를 유지하고 싶지 않으며 개발자 워크 스테이션에서는 메모리가 항상 부족함)
  • SNAPSHOTS 사용 중지

로컬 저장소가 하드 드라이브 공간을 채우는 것을 방지하는 가장 좋은 방법은 무엇입니까?

최신 정보:

동작을 확인하고 더 많은 정보를 제공하기 위해 작은 넥서스 서버를 설정하고 두 개의 프로젝트 (a 및 b)를 빌드하고 다음을 시도하십시오.

ㅏ:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.glauche</groupId>
  <artifactId>a</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <distributionManagement>
    <snapshotRepository>
        <id>nexus</id>
        <name>nexus</name>
        <url>http://server:8081/nexus/content/repositories/snapshots</url>
    </snapshotRepository>
  </distributionManagement>

</project>

비:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.glauche</groupId>
  <artifactId>b</artifactId>
  <version>0.0.1-SNAPSHOT</version>
    <distributionManagement>
    <snapshotRepository>
        <id>nexus</id>
        <name>nexus</name>
        <url>http://server:8081/nexus/content/repositories/snapshots/</url>
    </snapshotRepository>
  </distributionManagement>
 <repositories>
    <repository>
        <id>nexus</id>
        <name>nexus</name>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <url>http://server:8081/nexus/content/repositories/snapshots/</url>
    </repository>
 </repositories>
  <dependencies>
    <dependency>
        <groupId>de.glauche</groupId>
        <artifactId>a</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
  </dependencies>
</project>

이제 maven을 사용하고 "a"에서 "deploy"를 실행하면

a-0.0.1-SNAPSHOT.jar
a-0.0.1-20101204.150527-6.jar
a-0.0.1-SNAPSHOT.pom
a-0.0.1-20101204.150527-6.pom

로컬 저장소에서. 배포 대상을 실행할 때마다 새 타임 스탬프 버전을 사용합니다. 넥서스 서버에서 스냅 샷을 업데이트하려고 할 때도 마찬가지입니다 ( "a"프로젝트를 닫고 로컬 저장소에서 삭제하고 "b"를 빌드).

많은 스냅 샷이 빌드되는 환경 (허드슨 서버를 생각해보세요 ...)에서 로컬 리포지토리가 이전 버전으로 빠르게 채워집니다.

업데이트 2 :

이것이 실패하는 방법과 이유를 테스트하기 위해 더 많은 테스트를 수행했습니다. 각 테스트는 깨끗한 모든 항목에 대해 실행됩니다 (de / glauche는 시스템과 넥서스 모두에서 삭제됨)

  • maven 2.2.1로 mvn 배포 :

시스템 A의 로컬 저장소에 snapshot.jar + snapshot-timestamp.jar이 포함되어 있습니다.

하지만 넥서스에 타임 스탬프가있는 항아리 하나만 메타 데이터에 다음과 같이 표시됩니다.

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>de.glauche</groupId>
  <artifactId>a</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <versioning>
    <snapshot>
      <timestamp>20101206.200039</timestamp>

      <buildNumber>1</buildNumber>
    </snapshot>
    <lastUpdated>20101206200039</lastUpdated>
  </versioning>
</metadata>
  • m2eclipse (embedded m3 final)에서 업데이트 종속성 (시스템 B에서) 실행-> 로컬 저장소에 snapshot.jar + snapshot-timestamp.jar 포함 :(
  • 외부 maven 2.2.1로 패키지 목표 실행-> 로컬 저장소에 snapshot.jar + snapshot-timestamp.jar 포함 :(

좋아, 다음으로 maven 3.0.1로 시도하십시오 (프로젝트 a의 모든 흔적을 제거한 후)

  • 머신 A의 로컬 저장소가 더 좋아 보입니다. 타임 스탬프가없는 항아리 하나만

  • 넥서스에 타임 스탬프가있는 항아리가 하나 뿐이며 메타 데이터는 다음을 읽습니다.

    de.glauche a 0.0.1-SNAPSHOT

    <snapshot>
      <timestamp>20101206.201808</timestamp>
      <buildNumber>3</buildNumber>
    </snapshot>
    <lastUpdated>20101206201808</lastUpdated>
    <snapshotVersions>
      <snapshotVersion>
        <extension>jar</extension>
        <value>0.0.1-20101206.201808-3</value>
        <updated>20101206201808</updated>
      </snapshotVersion>
      <snapshotVersion>
        <extension>pom</extension>
        <value>0.0.1-20101206.201808-3</value>
        <updated>20101206201808</updated>
      </snapshotVersion>
    </snapshotVersions>
    

  • m2eclipse (embedded m3 final)에서 업데이트 종속성 (시스템 B에서) 실행-> 로컬 저장소에 snapshot.jar + snapshot-timestamp.jar 포함 :(

  • 외부 maven 2.2.1로 패키지 목표 실행-> 로컬 저장소에 snapshot.jar + snapshot-timestamp.jar 포함 :(

요약하자면, maven3의 "배포"목표는 2.2.1보다 더 잘 작동하며, 생성하는 머신의 로컬 저장소는 괜찮아 보입니다. 그러나 수신자는 항상 많은 타임 스탬프 버전으로 끝납니다 ...

내가 도대체 ​​뭘 잘못하고있는 겁니까 ?

업데이트 3

나는 또한 다양한 다른 구성을 테스트했고 먼저 nexus를 인공물-> 동일한 동작으로 대체했습니다. 그런 다음 linux maven 3 클라이언트를 사용하여 저장소 관리자에서 스냅 샷을 다운로드합니다.-> 로컬 저장소에는 여전히 타임 스탬프 스냅 샷이 있습니다.


로컬 .m2 \ repository 부분에 대한 관련 질문은 (Jenkins) 빌드 서버의 로컬 저장소 인 stackoverflow.com/q/9729076/223837 에 중점을 둡니다 .
MarnixKlooster ReinstateMonica

다음은 Apcahe Maven Comptability Notes에 대한 작업 링크입니다.- cwiki.apache.org
confluence

답변:


36

<uniqueVersion>구성 넥서스 같은 메이븐 저장소에 이러한 (MVN 배포를 통해) 배포 된 아티팩트인가.

Nexus에서이를 제거하려면 매일 SNAPSHOT 저장소를 제거하는 자동화 된 작업을 쉽게 생성 할 수 있습니다. 일정 수의 shapshot을 유지하거나 일정 기간 동안 유지하도록 구성 할 수 있습니다. 매우 쉽고 훌륭하게 작동합니다.

개발자 컴퓨터의 로컬 저장소에있는 아티팩트는 "설치"목표에서 가져 오며 이러한 타임 스탬프를 사용하지 않습니다. 개정 번호도 증가시키지 않는 한 유일한 SNAPSHOT 버전 (예 : 1.0.0- 1.0.1-SNAPSHOT로 SNAPSHOT).


1
문제는 "설치"목표가 많은 개발자와 함께 분산 된 환경에서 그렇게 많이 사용되지 않는다는 것입니다. 또한 매일 매우 자주 발생하는 모든 cvs 커밋에서 새 스냅 샷을 빌드 (및 배포)하는 허드슨 서버를 사용합니다. 넥서스 스냅 샷 삭제 mechainsm에 대해 알고 있으며 가능한 해결 방법 목록을 참조하십시오.
mglauche 2010

각 개발 시스템은 "로컬"저장소에서이 있어야 ~/.m2/repository하고 각 pom.xml저장소 정의를 가지고 있어야 당신 LAN에 넥서스의 단일 인스턴스를 가리키는. (당신이 보여주는 것처럼). 모든 Subversion 커밋을 기반으로하는 Hudson과 함께이 설정이 있으며 훌륭하게 작동합니다. SNAPSHOT 빌드는 Nexus에 "배포"되어 매주 수집되고 제거됩니다. 개발자 컴퓨터는 Nexus에서에 최신 SNAPSHOT을 자동으로 다운로드 ~/.m2/repository하고 이전에 다운로드 한 것을 대체합니다. 개발자는 자신의 Nexus 인스턴스를 가져서는 안됩니다.
HDave 2010

2
업데이트 내용을 읽고 추가 할 사항이 하나 더 있습니다. 타임 스탬프가 표시된 아티팩트는 로컬 (~ / .m2 / repository) 저장소 내부에서 볼 수 없습니다. 그렇다면 뭔가 잘못된 것입니다. Nexus 내부에서만 볼 수 있습니다. Nexus 내부에서는 예, 빠르게 수집됩니다. 잠재적으로 하루에 수백 MB. 넥서스 작업은 수량을 작게 유지하기 위해 매일 이들을 더 쉽게 제거 할 수 있습니다.
HDave 2010

6
그들은 확실히 로컬 저장소합니다 (~ / .m2 / 저장소 일), 그들이 거기에 "배포"대상을 실행 한 후 끝에서 생을 마감 할 MVN -U에 (즉, B 프로젝트)에 따라 프로젝트에 설치합니다. 나는 심지어 maven 2.2.1과 maven 3으로 테스트했지만 둘 다 동일한 동작을 가지고 있습니다.
mglauche 2010

2
나는 지금 그것을 얻는다고 생각한다. 그들은 개발이 "배포"할 때 거기에 나타나지 않고 오히려 개발자가 종속 프로젝트를 빌드 할 때 나타난다. 이때 업스트림 프로젝트의 최신 SNAPSHOT은 파일 이름의 일부로 타임 스탬프가 그대로 유지 된 상태로 Nexus에서 ~ / .m2 / repository로 다운로드됩니다. 이게 옳은 거니?
HDave 2010

13

이 플러그인은 로컬 저장소에서 프로젝트의 아티팩트를 제거합니다. 큰 로컬 스냅 샷의 복사본을 하나만 유지하는 데 유용합니다.

<plugin>         
    <groupId>org.codehaus.mojo</groupId>         
    <artifactId>build-helper-maven-plugin</artifactId>         
    <version>1.7</version>         
    <executions>           
        <execution>             
            <id>remove-old-artifacts</id>             
            <phase>package</phase>             
            <goals>               
                <goal>remove-project-artifact</goal>             
            </goals>            
            <configuration>  
                <removeAll>true</removeAll><!-- When true, remove all built artifacts including all versions. When false, remove all built artifacts of this project version -->             
            </configuration>          
        </execution>         
    </executions>       
</plugin>

7

저는 제안 된 솔루션 중 어떤 것도 마음에 들지 않았습니다. Maven 캐시를 삭제하면 종종 네트워크 트래픽이 크게 증가하고 빌드 프로세스가 느려집니다. build-helper-maven-plugin은 하나의 아티팩트에만 도움이되며, 하나의 간단한 명령으로 로컬 캐시에서 오래된 타임 스탬프 스냅 샷 아티팩트를 모두 제거 할 수있는 솔루션을 원했습니다. 며칠 동안 검색 한 후 포기하고 작은 프로그램을 작성하기로 결정했습니다. 최종 프로그램은 우리 환경에서 아주 잘 작동하는 것 같습니다. 그래서 그런 도구가 필요한 다른 사람들과 공유하기로 결정했습니다. 소스는 github에서 가져올 수 있습니다 : https://github.com/nadestin/tools/tree/master/MavenCacheCleanup


@HDave 여기에서 pom 조각을 올바르게 형식화하지 못했습니다 . https://github.com/nadestin/tools/wiki/m2cachecleanup-maven-plugin 에서 확인 하십시오 . Jenkins 슬레이브에서이 유틸리티는 매일 ~ 200Mb의 디스크 공간을 회수합니다.
yurinadestin

2

이것의 원격 저장소 부분에 관해서는 정기적으로 SNAPSHOT을 제거하는 것에 대해 논의한 이전 답변이 작동한다고 생각합니다. 그러나 아무도 귀하의 질문에서 로컬 개발자 워크 스테이션 동기화 부분을 다루지 않았습니다.

아직 Maven3 사용을 시작하지 않았으므로 아직 로컬 컴퓨터에서 SNAPSHOT이 빌드되기 시작하는 것을 보지 못했습니다.

그러나 우리는 m2eclipse에 대해 다른 문제가있었습니다. "작업 공간 해상도"를 활성화하고 프로젝트가 작업 공간 내에 존재하는 경우 소스 업데이트는 일반적으로 우리를 최첨단으로 유지합니다. 그러나 우리는 m2eclipse가 최근 Nexus에 게시 된 아티팩트로 자체적으로 업데이트하는 것이 매우 어렵다는 것을 발견했습니다. 우리 팀 내에서 유사한 문제가 발생하고 있으며 특히 프로젝트 그래프가 매우 크기 때문에 문제가 발생합니다. 작업 공간에는 없지만 SNAPSHOT이 자주 게시되는 종속성이 많이 있습니다.

나는 이것이 SNAPSHOT을 정확히 처리하지 않는 m2eclipse의 문제로 다시 돌아갈 것이라고 확신합니다. eclipse 내의 Maven 콘솔에서 m2eclipse가 캐시 된 버전이 있기 때문에 최근에 게시 된 SNAPSHOT의 업데이트를 건너 뛰고 있음을 알 수 있습니다. 실행 구성 또는 명령 줄에서 -U를 수행하면 Maven 이 메타 데이터 변경을 선택합니다. 그러나 "Update Snapshots ..."선택은 Maven이이 캐시를 만료하도록 m2eclipse에 알려야합니다. 전달되는 것 같지 않습니다. 투표에 관심이 있다면 여기에 버그가있는 것 같습니다 : https://issues.sonatype.org/browse/MNGECLIPSE-2608

당신은 어딘가에 주석에서 이것을 언급했습니다.

이 문제에 대한 최선의 해결 방법은 m2eclipse 내에서 문제가 발생하기 시작할 때 개발자가 로컬 워크 스테이션을 제거하도록하는 것 같습니다. 다른 문제에 대한 유사한 해결책 ... 다른 사람들은 Maven 2.2.1 및 3 지원 m2eclipse에 대한 문제를보고했으며 동일한 것을 보았습니다.

Maven3을 사용하는 경우 최신 SNAPSHOT 만 가져 오도록 구성하고 저장소가 말하는 시간 동안 (또는 수동으로 만료 될 때까지) 캐시 할 수 있기를 바랍니다. 그렇다면 로컬 저장소에 많은 SNAPSHOT이 필요하지 않기를 바랍니다.

수동으로 수행하는 빌드 서버에 대해 이야기하지 않는 한 mvn install그들에. SNAPSHOT이 빌드 서버와 같은 환경에서 빌드되는 것을 방지하는 방법에 관해서는 각 빌드가 자체 작업 공간과 로컬 저장소를 사용하도록하여 그 총알을 피했습니다 (Maven 2.2.1에서는 다음과 같은 특정 항목). POM은 항상 ~ / .m2 / repository에서 나오는 것 같습니다. 추가 SNAPSHOT은 실제로 단일 빌드에만 고정 된 다음 삭제됩니다 (그리고 처음부터 다시 다운로드 됨). 그래서 우리는이 접근 방식이 처음에는 더 많은 공간을 차지하지만 모든 것을 단일 저장소에서 해결하는 것보다 더 안정적으로 유지되는 경향이 있습니다. 이 옵션 (Hudson에서)은 "비공개 Maven 저장소 사용"이라고하며 Maven으로 빌드하도록 선택한 경우 프로젝트 구성에 대한 빌드 섹션의 고급 버튼 아래에 있습니다. 해당 옵션에 대한 도움말 설명은 다음과 같습니다.

일반적으로 Hudson은 Maven이 결정한 로컬 Maven 저장소를 사용합니다. 정확한 프로세스는 문서화되지 않은 것처럼 보이지만 ~ / .m2 / repository이며 ~ / .m2 / settings.xml에서 재정의 할 수 있습니다 (자세한 내용은 참조 참조). .) 이것은 일반적으로 동일한 노드에서 실행되는 모든 작업이 단일 Maven 저장소를 공유 함을 의미합니다. 이것의 장점은 디스크 공간을 절약 할 수 있다는 것입니다. 그러나 단점은 때때로 이러한 빌드가 서로 간섭 할 수 있다는 것입니다. 예를 들어, 로컬 저장소에 모든 종속성이 있기 때문에 POM의 저장소에 해당 종속성이 없다는 사실에도 불구하고 빌드가 잘못 성공할 수 있습니다.

동일한 로컬 저장소를 사용하려는 동시 Maven 프로세스와 관련하여보고 된 문제도 있습니다.

이 옵션을 선택하면 Hudson은 Maven에게 $ WORKSPACE / .repository를 로컬 Maven 저장소로 사용하도록 지시합니다. 즉, 각 작업은 자체적으로 격리 된 Maven 저장소를 갖게됩니다. 추가 디스크 공간 소비를 희생하면서 위의 문제를 해결합니다.

이 옵션을 사용할 때 원격 Maven 리포지토리를 너무 자주 방문 할 필요가 없도록 Maven 아티팩트 관리자를 설정하는 것이 좋습니다.

Hudson에서 실행되는 모든 Maven 작업에서이 모드를 활성화하려면 여기에 설명 된 기술을 참조하세요.

이것이 도움이되기를 바랍니다. 문제가 해결되지 않으면 내가 놓친 부분을 알려주세요.


위에서 언급 한 버그가 수정되었습니다 : bugs.eclipse.org/bugs/show_bug.cgi?id=339527
HDave 2013

1

groovy 에서 타임 스탬프가있는 파일을 삭제하는 artifact-0.0.1-20101204.150527-6.jar것은 매우 간단 할 수 있습니다.

root = 'path to your repository'

new File(root).eachFileRecurse {
  if (it.name.matches(/.*\-\d{8}\.\d{6}\-\d+\.[\w\.]+$/)) {
    println 'Deleting ' + it.name
    it.delete()
  }
}

Groovy를 설치 하고 스크립트를 파일에 저장하고 매주 실행을 예약하고 시작, 로그온 등 원하는대로 실행하십시오.

또는 gmavenplus-plugin을 사용하여 실행을 maven 빌드에 연결할 수도 있습니다 . maven이 속성에 설정 한 저장소 위치는 어떻게 settings.localRepository구성을 통해 변수에 바인딩 되는지 확인 하십시오 repository.

  <plugin>
    <groupId>org.codehaus.gmavenplus</groupId>
    <artifactId>gmavenplus-plugin</artifactId>
    <version>1.3</version>
    <executions>
      <execution>
        <phase>install</phase>
        <goals>
          <goal>execute</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <properties>
        <property>
          <name>repository</name>
          <value>${settings.localRepository}</value>
        </property>
      </properties>
      <scripts>
        <script><![CDATA[
          new File(repository).eachFileRecurse {
            if (it.name.matches(/.*\-\d{8}\.\d{6}\-\d+\.[\w\.]+$/)) {
              println 'Deleting snapshot ' + it.getAbsolutePath()
              it.delete()
            }
          }
        ]]></script>
      </scripts>
    </configuration>
    <dependencies>
      <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.3.7</version>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
  </plugin>  

0

POM 파일에 다음 매개 변수 추가

POM

<configuration>
<outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>
</configuration>

https://maven.apache.org/plugins/maven-dependency-plugin/copy-mojo.html

POM 예

<plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.10</version>
        <executions>
          <execution>
            <id>copy</id>
            <phase>package</phase>
            <goals>
              <goal>copy</goal>
            </goals>
            <configuration>
              <artifactItems>
                <artifactItem>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>3.8.1</version>
                  <type>jar</type>
                  <overWrite>false</overWrite>
                  <outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
                  <destFileName>optional-new-name.jar</destFileName>
                </artifactItem>
              </artifactItems>
              **<outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>**
              <outputDirectory>${project.build.directory}/wars</outputDirectory>
              <overWriteReleases>false</overWriteReleases>
              <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

Jenkins에서 구성 :

// copy artifact 
copyMavenArtifact(artifact: "commons-collections:commons-collections:3.2.2:jar", outputAbsoluteArtifactFilename: "${pwd()}/target/my-folder/commons-collections.jar")
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.