Как вы эффективно справляетесь с моментальными снимками с метками времени maven-3? - PullRequest
83 голосов
/ 25 ноября 2010

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

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

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

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

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

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

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

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

Обновление:

Чтобы проверить beaviour и дать больше информации, я настроил небольшой сервер Nexus, собрал два проекта (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 и запускаю «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 ...), локальное хранилище заполняется старыми версиями fast

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

Чтобы проверить, как и почему это не помогает, я провел еще несколько тестов. Каждый тест выполняется для очистки всего (de / glauche удаляется как с компьютеров, так и с Nexus)

  • mvn deploy с maven 2.2.1:

локальный репозиторий на компьютере 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>
  • запустить обновление зависимостей (на компьютере B) в m2eclipse (встроенный финал m3) -> в локальном репозитории есть snapshot.jar + snapshot-timestamp.jar: (
  • запуск цели пакета с внешним maven 2.2.1 -> в локальном репозитории есть snapshot.jar + snapshot-timestamp.jar: (

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

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

  • только одна метка времени в нексусе, метаданные гласят:

    de.glauche 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>
    

  • запустить обновление зависимостей (на компьютере B) в m2eclipse (встроенный финал m3) -> в локальном репозитории есть snapshot.jar + snapshot-timestamp.jar: (

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

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

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

Обновление 3

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

Ответы [ 6 ]

34 голосов
/ 01 декабря 2010

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

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

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

13 голосов
/ 06 сентября 2011

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

<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 голосов
/ 08 июля 2013

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

2 голосов
/ 19 января 2011

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

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

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

Я почти уверен, что это сводится к проблеме в m2eclipse, где он не обрабатывает SNAPSHOT точно так, как должен. Вы можете увидеть в консоли Maven в eclipse, где m2eclipse сообщает, что пропускает обновление недавно опубликованного SNAPSHOT, потому что у него есть кэшированная версия. Если вы выполните -U из конфигурации запуска или из командной строки, Maven обнаружит изменение метаданных. Но выбор «Обновить снимки ...» должен сообщить m2eclipse, чтобы Maven истек этот кеш. Это, кажется, не проходит мимо. Кажется, есть ошибка, которая подана для этого, если вы хотите проголосовать за нее: 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 /). Дополнительные SNAPSHOT действительно останавливаются только для одной сборки, а затем они сбрасываются (и загружаются снова с нуля). Итак, мы видели, что этот подход в конечном итоге потребляет больше места, но он остается более стабильным, чем решение всех задач из одного репозитория. Этот параметр (в Hudson) называется «Использовать частный репозиторий Maven» и находится под кнопкой «Дополнительно» раздела «Сборка» в конфигурациях проекта, когда вы выбрали сборку с Maven. Вот описание справки для этой опции:

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

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

Когда эта опция включена, Хадсон скажет Maven использовать $ WORKSPACE / .repository в качестве локального репозитория Maven.Это означает, что каждая работа получит свой отдельный репозиторий Maven только для себя.Это устраняет вышеуказанные проблемы за счет дополнительного использования дискового пространства.

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

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

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

1 голос
/ 23 января 2015

В 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-plugin . Обратите внимание, как местоположение хранилища задается 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 голосов
/ 27 июля 2016

Добавьте следующий параметр в файл 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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...