Agora que o maven-3 eliminou o suporte para <uniqueVersion> false </uniqueVersion> para artefatos de instantâneo, parece que você realmente precisa usar SNAPSHOTS com carimbo de data / hora. Especialmente m2eclipse, que usa maven 3 internamente parece ser afetado com ele, update-snapshots não funcionam quando os SNAPSHOTS não são únicos.
Antes, parecia uma prática recomendada definir todos os instantâneos como uniqueVersion = false
Agora, não parece um grande problema mudar para a versão com carimbo de data / hora, afinal eles são gerenciados por um repositório nexus central, que é capaz de deletar snapshots antigos em intervalos regulares.
O problema são as estações de trabalho do desenvolvedor local. Seu repositório local rapidamente cresce muito com instantâneos exclusivos.
Como lidar com esse problema?
No momento, vejo as seguintes soluções possíveis:
- Peça aos desenvolvedores para limpar o repositório em intervalos regulares (o que leva a muita frustração, pois leva muito tempo para excluir e ainda mais para baixar tudo o que é necessário)
- Configure algum script que exclua todos os diretórios SNAPSHOT do repositório local e peça aos desenvolvedores para executar esse script de vez em quando (melhor do que o primeiro, mas ainda leva algum tempo para executar e baixar os instantâneos atuais)
- use a dependência: plug-in purge-local-repository (tem problemas quando executado a partir do eclipse, devido a arquivos abertos, precisa ser executado a partir de cada projeto)
- configurar nexus em cada estação de trabalho e configurar um trabalho para limpar instantâneos antigos (melhor resultado, mas não quero manter mais de 50 servidores nexus, além disso, a memória está sempre apertada nas estações de trabalho do desenvolvedor)
- pare de usar SNAPSHOTS em tudo
Qual é a melhor maneira de evitar que seu repositório local ocupe espaço no disco rígido?
Atualizar:
Para verificar o comportamento e fornecer mais informações, eu configurei um pequeno servidor Nexus, construa dois projetos (aeb) e tente:
uma:
<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>
Agora, quando eu usar o maven e executar "deploy" em "a", terei
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
no repositório local. Com uma nova versão de carimbo de data / hora cada vez que executo o destino de implantação. O mesmo acontece quando tento atualizar os Snapshots do servidor Nexus (feche o Projeto "a", exclua-o do repositório local, compilação "b")
Em um ambiente onde muitos instantâneos são construídos (pense no servidor hudson ...), o repositório local se enche de versões antigas rapidamente
Atualização 2:
Para testar como e por que isso está falhando, fiz mais alguns testes. Cada teste é executado para limpar tudo (de / glauche é excluído de ambas as máquinas e nexo)
- mvn deploy com maven 2.2.1:
o repositório local na máquina A contém snapshot.jar + snapshot-timestamp.jar
MAS: apenas um jar com carimbo de data / hora no nexo, os metadados lêem:
<?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>
- execute dependências de atualização (na máquina B) em m2eclipse (m3 final integrado) -> o repositório local tem snapshot.jar + snapshot-timestamp.jar :(
- execute o objetivo do pacote com maven externo 2.2.1 -> o repositório local tem snapshot.jar + snapshot-timestamp.jar :(
Ok, próxima tentativa com maven 3.0.1 (depois de remover todos os vestígios do projeto a)
repositório local na máquina A parece melhor, apenas um jar sem registro de data e hora
apenas um jar com carimbo de data / hora no nexo, os metadados lêem:
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>
execute dependências de atualização (na máquina B) em m2eclipse (m3 final integrado) -> o repositório local tem snapshot.jar + snapshot-timestamp.jar :(
execute o objetivo do pacote com maven externo 2.2.1 -> o repositório local tem snapshot.jar + snapshot-timestamp.jar :(
Então, para recapitular: o objetivo "implantar" no maven3 funciona melhor do que no 2.2.1, o repositório local na máquina de criação parece bom. Mas, o receptor sempre termina com muitas versões com data e hora ...
O que estou fazendo errado ?
Atualização 3
Eu também testei várias outras configurações, primeiro substitua nexus por artifactory -> mesmo comportamento. Em seguida, use os clientes Linux maven 3 para baixar os instantâneos do gerenciador de repositório -> o repositório local ainda tem instantâneos com carimbo de data / hora :(
Respostas:
A
<uniqueVersion>
configuração aplicada a artefatos que foram implantados (via mvn deploy) em um repositório Maven como o Nexus.Para removê-los do Nexus, você pode criar facilmente um trabalho automatizado para limpar o repositório SNAPSHOT todos os dias. Ele pode ser configurado para reter um certo número de shapshots ou mantê-los por um determinado período de tempo. É super fácil e funciona muito bem.
Artefatos no repositório local em uma máquina de desenvolvedor chegam lá a partir do objetivo "instalar" e não usam esses carimbos de data / hora ... eles apenas continuam substituindo a única versão do SNAPSHOT, a menos que você também esteja incrementando o número de revisão (por exemplo, 1.0.0- SNAPSHOT para 1.0.1-SNAPSHOT).
fonte
~/.m2/repository
e cada umapom.xml
deve ter uma definição de repositório que aponta para uma única instância do Nexus em sua LAN. (assim como você mostra). Nós temos isso configurado, junto com o Hudson que se baseia em cada commit do Subversion e funciona muito bem. As compilações SNAPSHOT são "implementadas" no Nexus, onde são coletadas e eliminadas semanalmente. As máquinas do desenvolvedor baixam automaticamente o SNAPSHOT mais recente do Nexus para~/.m2/repository
e ele substitui o anteriormente baixado. Os desenvolvedores nunca devem ter sua própria instância Nexus.Este plugin remove os artefatos do projeto do repositório local. Útil para manter apenas uma cópia de um grande instantâneo local.
<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>
fonte
Bem, eu não gostei de nenhuma das soluções propostas. A exclusão do cache do maven geralmente aumenta significativamente o tráfego de rede e retarda o processo de construção. build-helper-maven-plugin ajuda apenas com um artefato, eu queria uma solução que pudesse limpar todos os artefatos de instantâneo com carimbo de data / hora desatualizados do cache local em um comando simples. Após alguns dias de pesquisa, desisti e decidi escrever um pequeno programa. O programa final parece estar funcionando muito bem em nosso ambiente. Então, decidi compartilhar com outras pessoas que possam precisar dessa ferramenta. As fontes podem ser extraídas do github: https://github.com/nadestin/tools/tree/master/MavenCacheCleanup
fonte
Quanto à parte do repositório remoto disso, acho que as respostas anteriores que discutem uma limpeza de SNAPSHOTs em um intervalo regular funcionarão. Mas ninguém abordou a parte de sincronização da estação de trabalho do desenvolvedor local de sua pergunta.
Ainda não começamos a usar o Maven3, portanto, ainda não vimos SNAPSHOTs começando a se acumular nas máquinas locais.
Mas tivemos problemas diferentes com m2eclipse. Quando temos a "Resolução do espaço de trabalho" ativada e o projeto existe dentro do nosso espaço de trabalho, as atualizações de código-fonte geralmente nos mantêm atualizados. Mas descobrimos que é muito difícil fazer com que o m2eclipse se atualize com artefatos publicados recentemente no Nexus. Estamos enfrentando problemas semelhantes em nossa equipe e isso é particularmente problemático porque temos um gráfico de projeto muito grande ... há muitas dependências que não estarão em sua área de trabalho, mas obterão SNAPSHOTs publicados com frequência.
Tenho certeza de que isso volta a ser um problema no m2eclipse onde ele não lida com SNAPSHOTs exatamente como deveria. Você pode ver no console Maven dentro do eclipse onde m2eclipse diz que está pulando a atualização de um SNAPSHOT publicado recentemente porque tem uma versão em cache. Se você fizer um -U a partir de uma configuração de execução ou da linha de comando, o Maven pegará a mudança de metadados. Mas uma seleção "Atualizar instantâneos ..." deve informar ao m2eclipse para que o Maven expire este cache. Não parece estar sendo transmitido. Parece haver um bug arquivado para isso se você estiver interessado em votar nele: https://issues.sonatype.org/browse/MNGECLIPSE-2608
Você fez menção a isso em um comentário em algum lugar.
A melhor solução para esse problema parece ser fazer com que os desenvolvedores limpem suas estações de trabalho locais quando as coisas começarem a quebrar de dentro do m2eclipse. Solução semelhante para um problema diferente ... Outros relataram problemas com Maven 2.2.1 e 3 m2eclipse de apoio, e eu vi o mesmo.
Espero que, se você estiver usando o Maven3, você possa configurá-lo para obter apenas o SNAPSHOT mais recente e armazená-lo em cache pelo período de tempo que o repositório diz (ou até que você o expire manualmente). Com sorte, você não precisará ter um monte de SNAPSHOTs em seu repositório local.
A menos que você esteja falando sobre um servidor de compilação que está fazendo manualmente um
mvn install
neles. No que diz respeito a como evitar que SNAPSHOTs se acumulem em um ambiente como um servidor de compilação, meio que evitamos esse ponto fazendo com que cada compilação use seu próprio espaço de trabalho e repositório local (embora, no Maven 2.2.1, certas coisas como Os POMs parecem sempre sair do repositório ~ / .m2 /). Os SNAPSHOTs extras só ficam por aí em uma única construção e depois são descartados (e baixados novamente do zero). Portanto, vimos que essa abordagem acaba consumindo mais espaço para começar, mas tende a permanecer mais estável do que ter tudo resolvido em um único repositório. Esta opção (no Hudson) é chamada de "Usar repositório privado Maven" e está no botão Avançado da seção Construir nas configurações do projeto quando você selecionou construir com Maven. Aqui está a descrição de ajuda para essa opção:Espero que isso ajude - se não resolver o seu problema, me avise onde perdi.
fonte
No groovy , excluir arquivos com carimbo de data / hora como
artifact-0.0.1-20101204.150527-6.jar
pode ser muito simples: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() } }
Instale o Groovy , salve o script em um arquivo e agende a execução a cada semana, inicie, faça logon, o que for mais conveniente para você.
Ou você pode até conectar a execução à compilação do maven, usando o gmavenplus-plugin . Observe, como o local do repositório é definido pelo maven na propriedade
settings.localRepository
e, em seguida, vinculado por meio da configuração à variávelrepository
:<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>
fonte
Adicione o seguinte parâmetro em seu arquivo POM
POM
<configuration> <outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename> </configuration>
https://maven.apache.org/plugins/maven-dependency-plugin/copy-mojo.html
Exemplo 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>
Configure no Jenkins:
// copy artifact copyMavenArtifact(artifact: "commons-collections:commons-collections:3.2.2:jar", outputAbsoluteArtifactFilename: "${pwd()}/target/my-folder/commons-collections.jar")
fonte