Как вы эффективно справляетесь с моментальными снимками maven-3?


теперь, когда maven-3 сделал падение поддержки дляfalse для артефактов моментальных снимков кажется, что вам действительно нужно использовать снимки с отметками времени. Особенно m2eclipse, который использует maven 3 внутренне, похоже, влияет на него, update-snapshots не работает, когда снимки не уникальны.

казалось, что лучше практика перед чтобы установить для всех снимков значение uniqueVersion=false

теперь, кажется, нет большой проблемы чтобы переключиться на версию с отметкой времени, в конце концов они управляются центральным репозиторием nexus, который способен удалять старые снимки в обычных интервалах.

проблема заключается в локальных рабочих станциях разработчиков. Их локальный репозиторий быстро растет очень большой с уникальными снимками.

как справиться с этой проблемой ?

прямо сейчас я вижу следующие возможные решения:

  • попросите разработчиков, чтобы очистить репозиторий через регулярные промежутки времени (что приводит к большому количеству fustration, так как требуется много времени для удаления и еще больше времени для загрузки всего необходимого)
  • настроить какой-то скрипт, который не удалить снимок каталоги из локального репозитория и попросите разработчиков время от времени запускать этот скрипт (лучше, чем первый, но все же занимает довольно много времени для запуска и загрузки текущих снимков)
  • используйте зависимость: очистить-локальный-репозиторий плагин (делает есть проблемы при запуске из eclipse, из-за открытых файлов, должен быть запущен из каждого проекта)
  • настройка nexus на каждой рабочей станции и настроить задание для очистки старых снимков (лучший результат, но я не хочу поддерживать 50 + nexus серверов, плюс память всегда плотно на рабочих станциях разработчиков)
  • прекратите использовать снимки вообще

каков наилучший способ сохранить ваш локальный репозиторий от заполнения вашего места на жестком диске ?

обновление:

чтобы проверить beaviour и дать дополнительную информацию, я настраиваю небольшой сервер nexus, создаю два проекта (a и b) и пытаюсь:

a:

<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>

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>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 и запускаю " deploy "на" a", у меня будет

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

в локальном репозитории. С новой версией метки времени каждый раз, когда я запускаю цель развертывания. То же самое происходит, когда я пытаюсь обновить снимки с сервера nexus (закрыть проект " a, удалите его из локального репозитория, постройте "b")

в среде, где много снимков получить построить (думаю, hudson server ...), местная репозиота заполняется старыми версиями быстро

обновление 2:

чтобы проверить, как и почему это не я сделал еще несколько тестов. Каждый тест выполняется против clean everything (de / glauche получает удаление с обеих машин и nexus)

  • mvn развертывание с maven 2.2.1 :

локальный репозиторий на машине A содержит снимок.jar + snapshot-метка времени.банку

но: только один раз помеченный jar в nexus, метаданные читает:

<?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>
  • запуск зависимостей обновления (на машине B) в m2eclipse (embedded m3 final) - > локальный репозиторий имеет снимок.jar + snapshot-метка времени.кувшин :(
  • выполнить цель пакета с внешней помощью Maven 2.2.1 -> локальное хранилище моментального снимка.jar + snapshot-метка времени.сосуд : (

ОК, следующая попытка с maven 3.0.1 (после удаления всех следов проекта a)

  • локальный репозиторий на машине A выглядит лучше, только один не помеченный временем jar

  • только один раз помеченный jar в nexus, метаданные читает:

    де.glauche один 0.0.1-снимок

    <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>
    

  • запустить зависимости обновления (на машине B) в m2eclipse (встроенный M3 final) -> локальное хранилище моментального снимка.jar + snapshot-метка времени.кувшин :(

  • выполнить цель пакета с внешней помощью Maven 2.2.1 -> локальное хранилище моментального снимка.jar + snapshot-метка времени.кувшин :(

Итак, напомним: цель "развернуть" в maven3 работает лучше, чем в 2.2.1, локальный репозиторий на машине создания выглядит нормально. Но, приемник всегда заканчивается с большим количеством версий timestamed ...

что я делаю не так ?

обновление 3

Я также тестировал различные другие конфигурации, сначала заменил nexus на artifactory - > такое же поведение. Затем используйте клиенты linux maven 3 для загрузки снимков из диспетчера репозиториев - > локальный репозиторий все еще имеет снимки с отметкой времени: (

6 81

6 ответов:

на <uniqueVersion> конфигурация применяется к артефактам, которые были развернуты (через mvn deploy) в хранилище Maven, таком как Nexus.

чтобы удалить их из Nexus, вы можете легко создать автоматическое задание для очистки хранилища моментальных снимков каждый день. Он может быть настроен на сохранение определенного количества shapshots или сохранить их в течение определенного периода времени. Его супер легко и отлично работает.

артефакты в локальном репозитории на машине разработчика попадают туда из "установите" цель и не используйте эти метки времени...они просто продолжают заменять одну и только версию моментального снимка, если вы также не увеличиваете номер версии (например, 1.0.0-SNAPSHOT до 1.0.1-SNAPSHOT).

этот плагин удаляет артефакты проекта из локального репозитория. Полезно хранить только одну копию Большого локального снимка.

<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>

Ну мне не понравилось ни одно из предложенных решений. Удаление кэша maven часто значительно увеличивает сетевой трафик и замедляет процесс сборки. build-helper-maven-plugin помогает только с одним артефактом, я хотел решение, которое может очистить все устаревшие артефакты моментального снимка с отметкой времени из локального кэша в одной простой команде. После нескольких дней поиска, я сдался и решил написать небольшую программу. Заключительная программа, кажется, работает довольно хорошо в нашей среде. Поэтому я решил поделиться им с другими, кому может понадобиться такой инструмент. Источники можно извлечь из github:https://github.com/nadestin/tools/tree/master/MavenCacheCleanup

что касается удаленной части репозитория, я думаю, что предыдущие ответы, которые обсуждают очистку снимков на регулярном интервале, будут работать. Но никто не обращался к части синхронизации рабочей станции локального разработчика вашего вопроса.

мы еще не начали использовать Maven3, поэтому нам еще предстоит увидеть снимки, начинающие создаваться на локальных машинах.

но у нас были разные проблемы с m2eclipse. Когда у нас включено "разрешение рабочей области" и проект существует в нашем рабочем пространстве, исходные обновления обычно держат нас на краю кровотечения. Но мы обнаружили, что очень трудно заставить m2eclipse обновить себя недавно опубликованными артефактами в Nexus. Мы испытываем аналогичные проблемы в нашей команде, и это особенно проблематично, потому что у нас очень большой график проекта... есть много зависимостей, которые не будут в вашей рабочей области, но будут получать снимки, опубликованные часто.

я почти уверен, что это кипит вернемся к проблеме в m2eclipse, где он не обрабатывает снимки точно так, как должен. Вы можете увидеть в консоли Maven в eclipse, где m2eclipse сообщает вам, что он пропускает обновление недавно опубликованного снимка, потому что у него есть кэшированная версия. Если вы делаете a-U из конфигурации запуска или из командной строки, Maven будет забрать изменения метаданных. Но " обновление снимков..."выбор должен сказать m2eclipse, чтобы Maven истек этот кэш. Кажется, это не так как-то все прошло. Там, кажется, есть ошибка, которая подана для этого, если вы заинтересованы в голосовании за него: https://issues.sonatype.org/browse/MNGECLIPSE-2608

Вы упомянули об этом в комментарии где-то.

лучшим обходным путем для этой проблемы, по-видимому, является то, что разработчики очищают свои локальные рабочие станции, когда все начинает ломаться изнутри m2eclipse. Аналогичное решение другой проблемы... Другие сообщили: проблемы с Maven 2.2.1 и 3 backing m2eclipse, и я видел то же самое.

Я надеюсь, что если вы используете Maven3, вы можете настроить его только для извлечения последнего снимка и кэшировать его в течение времени, указанного в репозитории (или до истечения срока его действия вручную). Надеюсь, тогда вам не нужно будет иметь кучу снимков, сидящих в вашем локальном репозитории.

то есть, если вы не говорите о сервере сборки, который вручную делает mvn install на них. Насколько это возможно предотвратите создание моментальных снимков в среде, такой как сервер сборки, мы как бы уклонились от этой пули, поскольку каждая сборка использует свою собственную рабочую область и локальный репозиторий (хотя в Maven 2.2.1 некоторые вещи, такие как POMs, похоже, всегда выходят из ~/.m2 / repository) дополнительные снимки действительно остаются только для одной сборки, а затем они удаляются (и снова загружаются с нуля). Таким образом, мы видели, что этот подход в конечном итоге съедает больше места для начала, но он имеет тенденцию оставайтесь более стабильными, чем когда все решается из одного репозитория. Этот параметр (на Hudson) называется "использовать частный репозиторий Maven" и находится под кнопкой дополнительно раздела сборка в конфигурациях проекта, когда вы выбрали сборку с помощью Maven. Вот описание справки для этой опции:

обычно Хадсон использует локальный Maven репозиторий, определенный Maven - точный процесс, кажется, недокументированный, но это ~/.м2 / хранилище и может быть переопределен в ~/.м2/настройки.xml (см. ссылку более подробный.) Это обычно означает что все задания, которые выполняются на тот же узел акций одного Мэйвен хранилище. Положительная сторона этого заключается в том, что вы можете сохранить дисковое пространство, но недостатком этого является то, что иногда эти сборки могут мешать друг другу другой. Например, вы можете в конечном итоге имея сборки неправильно преуспеть, просто потому, что у всех зависимости в локальном репозитории, несмотря на то, что ни один из репозитории в POM могут иметь их.

есть также некоторые проблемы относительно наличия параллельного Maven процессы, пытающиеся использовать один и тот же локальный хранилище.

когда эта опция включена, Hudson будет сказать Maven для использования $РАБОЧАЯ ОБЛАСТЬ./хранилище как локальный репозиторий Maven. Это означает, что каждое задание получит свой собственный изолированный Maven репозиторий только для себя. Это исправляет вышеуказанные проблемы, за счет дополнительное потребление дискового пространства.

при использовании этой опции, рассмотреть настройка менеджера артефактов Maven так что вам не нужно нажимать дистанционно Репозитории Maven слишком часто.

Если вы предпочитаете активировать этот режим во всех заданиях Maven, выполненных на Хадсон, обратитесь к методике описанный здесь.

надеюсь, что это помогает - если это не решает вашу проблему, пожалуйста, дайте мне знать, где я пропустил.

в 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, сохраните скрипт в файл и запланируйте выполнение на каждую неделю, запуск, вход в систему, что вам подходит.

или вы даже можете подключить выполнение в сборку maven, используя gmavenplus-плагин. Обратите внимание, как расположение хранилища, установленные законодателем в собственность 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>  

добавьте следующий параметр в ваш 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")