Теперь, когда maven-3 отказался от поддержки <uniqueVersion> false </uniqueVersion> для артефактов моментальных снимков, кажется, что вам действительно нужно использовать SNAPSHOTS с отметками времени. В частности, m2eclipse, который использует maven 3 внутри, кажется, затронут этим, снимки обновлений не работают, когда SNAPSHOTS не уникальны.
Раньше казалось лучшей практикой установить для всех снимков значение uniqueVersion = false.
Теперь, кажется, нет большой проблемы переключиться на версию с отметкой времени, в конце концов, они управляются центральным репозиторием nexus, который может удалять старые снимки через регулярные интервалы.
Проблема в местных рабочих станциях разработчиков. Их локальный репозиторий быстро становится очень большим с уникальными снимками.
Как справиться с этой проблемой?
Сейчас я вижу следующие возможные решения:
- Попросите разработчиков регулярно очищать репозиторий (что приводит к большому разочарованию, так как удаление занимает много времени и еще больше времени для загрузки всего необходимого)
- Настройте сценарий, который удаляет все каталоги 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 и запускаю "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 сервер ...), локальная reposioty заполняется со старыми версиями быстро
Обновление 2:
Чтобы проверить, как и почему это не удается, я провел еще несколько тестов. Каждый тест запускается для очистки всего (de / glauche удаляется как с машин, так и с нексуса)
- 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 final) -> в локальном репозитории есть snapshot.jar + snapshot-timestamp.jar :(
- запустить цель пакета с внешним maven 2.2.1 -> в локальном репозитории есть snapshot.jar + snapshot-timestamp.jar :(
Хорошо, следующая попытка с maven 3.0.1 (после удаления всех следов проекта a)
локальный репозиторий на машине A выглядит лучше, только одна банка без метки времени
только один jar с отметкой времени в нексусе, метаданные читают:
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>
запустить зависимости обновления (на машине B) в m2eclipse (встроенный m3 final) -> в локальном репозитории есть snapshot.jar + snapshot-timestamp.jar :(
запустить цель пакета с внешним maven 2.2.1 -> в локальном репозитории есть snapshot.jar + snapshot-timestamp.jar :(
Итак, резюмируем: цель «развертывание» в maven3 работает лучше, чем в 2.2.1, локальный репозиторий на машине создания выглядит нормально. Но получатель всегда заканчивает с множеством версий с временными метками ...
Что я делаю не так ?
Обновление 3
Я также тестировал различные другие конфигурации, сначала заменил nexus на artifactory -> такое же поведение. Затем используйте клиенты linux maven 3 для загрузки снимков из диспетчера репозитория -> в локальном репозитории все еще есть снимки с отметкой времени :(
Ответы:
<uniqueVersion>
Конфигурация применяется к артефактам , которые были развернуты (через MVN развертывания) в Maven хранилища , такие как Nexus.Чтобы удалить их из Nexus, вы можете легко создать автоматическое задание для ежедневной очистки репозитория SNAPSHOT. Его можно настроить на сохранение определенного количества шепшотов или на сохранение их в течение определенного периода времени. Это очень просто и отлично работает.
Артефакты в локальном репозитории на машине разработчика попадают туда из цели «установить» и не используют эти временные метки ... они просто продолжают заменять единственную и неповторимую версию SNAPSHOT, если вы также не увеличиваете номер версии (например, 1.0.0- SNAPSHOT в 1.0.1-SNAPSHOT).
источник
~/.m2/repository
и каждаяpom.xml
должна иметь определение репозитория, указывающее на один экземпляр Nexus в вашей локальной сети. (прямо как вы показываете). У нас есть эта настройка вместе с Hudson, которая строится на каждом коммите Subversion, и она отлично работает. Сборки SNAPSHOT «развертываются» в Nexus, где они собираются и очищаются еженедельно. Машины разработчика автоматически загружают последний снимок SNAPSHOT с Nexus~/.m2/repository
и заменяют ранее загруженный. Разработчики никогда не должны иметь собственный экземпляр Nexus.Этот плагин удаляет артефакты проекта из локального репозитория. Полезно хранить только одну копию большого локального снимка.
<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
источник
Что касается части удаленного репозитория, я думаю, что предыдущие ответы, в которых обсуждается очистка SNAPSHOTs на регулярной основе, будут работать. Но никто не обратился к части вашего вопроса, касающейся синхронизации рабочих станций локального разработчика.
Мы еще не начали использовать Maven3, поэтому нам еще предстоит увидеть, как снимки SNAPSHOT начинают накапливаться на локальных машинах.
Но с m2eclipse у нас были другие проблемы. Когда у нас включено «Разрешение рабочего пространства» и проект существует в нашей рабочей области, обновления исходного кода обычно держат нас на передовой. Но мы обнаружили, что очень сложно заставить m2eclipse обновлять себя недавно опубликованными артефактами в Nexus. Мы сталкиваемся с аналогичными проблемами в нашей команде, и это особенно проблематично, потому что у нас очень большой график проекта ... есть много зависимостей, которые не будут в вашей рабочей области, но будут часто публиковать SNAPSHOTs.
Я почти уверен, что это восходит к проблеме в m2eclipse, где он не обрабатывает снимки в точности так, как должен. Вы можете увидеть в консоли Maven в eclipse, где m2eclipse сообщает вам, что он пропускает обновление недавно опубликованного SNAPSHOT, потому что у него есть кешированная версия. Если вы выполните -U из конфигурации запуска или из командной строки, Maven подхватит изменение метаданных. Но выбор «Обновить снимки ...» должен указать m2eclipse, что Maven должен истечь этот кеш. Похоже, это не проходит. Похоже, что для этого есть ошибка, если вы хотите проголосовать за нее: https://issues.sonatype.org/browse/MNGECLIPSE-2608
Вы упомянули об этом где-то в комментарии.
Лучшее решение этой проблемы - это очистить локальные рабочие станции разработчиков, когда что-то начинает ломаться в m2eclipse. Аналогичное решение другой проблемы ... Другие сообщали о проблемах с Maven 2.2.1 и 3, поддерживающими m2eclipse, и я видел то же самое.
Я надеюсь, что если вы используете Maven3, вы можете настроить его так, чтобы он извлекал только последний снимок SNAPSHOT и кэшировал его на время, указанное в репозитории (или пока вы не истечете его вручную). Надеюсь, тогда вам не понадобится куча снимков в вашем локальном репозитории.
Это если вы не говорите о сервере сборки, который вручную выполняет
mvn install
на них. Что касается того, как предотвратить создание снимков SNAPSHOT в среде, такой как сервер сборки, мы как бы избежали этой пули, заставив каждую сборку использовать свое собственное рабочее пространство и локальный репозиторий (хотя в Maven 2.2.1 некоторые вещи, такие как Кажется, что POM всегда выходят из репозитория ~ / .m2 /). Дополнительные снимки остаются только для одной сборки, а затем они сбрасываются (и загружаются снова с нуля). Итак, мы видели, что этот подход в конечном итоге занимает больше места, но он, как правило, остается более стабильным, чем когда все решается из одного репозитория. Этот параметр (на Hudson) называется «Использовать частный репозиторий 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-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>
источник
Добавьте следующий параметр в свой файл 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")
источник