Ahora que maven-3 eliminó el soporte para <uniqueVersion> false </uniqueVersion> para artefactos de instantáneas, parece que realmente necesita usar SNAPSHOTS con marca de tiempo. Especialmente m2eclipse, que usa maven 3 internamente parece verse afectado por él, las instantáneas de actualización no funcionan cuando las instantáneas no son únicas.
Parecía una buena práctica antes establecer todas las instantáneas en uniqueVersion = false
Ahora, no parece un gran problema cambiar a la versión con marca de tiempo, después de todo, son administrados por un repositorio central nexus, que puede eliminar instantáneas antiguas en intervalos regulares.
El problema son las estaciones de trabajo de los desarrolladores locales. Su repositorio local rápido aumenta muy grande con instantáneas únicas.
¿Cómo lidiar con este problema?
Ahora mismo veo las siguientes posibles soluciones:
- Pida a los desarrolladores que depuren el repositorio a intervalos regulares (lo que genera mucha frustración, ya que lleva mucho tiempo eliminarlo e incluso más tiempo descargar todo lo necesario)
- Configure un script que elimine todos los directorios SNAPSHOT del repositorio local y solicite a los desarrolladores que ejecuten ese script de vez en cuando (mejor que el primero, pero aún lleva bastante tiempo ejecutar y descargar las instantáneas actuales)
- use la dependencia: plugin purge-local-repository (tiene problemas cuando se ejecuta desde eclipse, debido a archivos abiertos, debe ejecutarse desde cada proyecto)
- configurar nexus en cada estación de trabajo y configurar un trabajo para limpiar instantáneas antiguas (el mejor resultado, pero no quiero mantener más de 50 servidores nexus, además de que la memoria siempre es escasa en las estaciones de trabajo de los desarrolladores)
- dejar de usar SNAPSHOTS en absoluto
¿Cuál es la mejor manera de evitar que su repositorio local llene el espacio de su disco duro?
Actualizar:
Para verificar el beaviour y dar más información, configuro un pequeño servidor nexus, construyo dos proyectos (ayb) e intento:
una:
<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>
segundo:
<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>
Ahora, cuando uso maven y ejecuto "deploy" en "a", tendré
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
en el repositorio local. Con una nueva versión de marca de tiempo cada vez que ejecuto el destino de implementación. Lo mismo sucede cuando trato de actualizar Snapshots desde el servidor nexus (cerrar "a" Project, eliminarlo del repositorio local, construir "b")
En un entorno donde la gran cantidad de instantáneas consiguen acumulación (creo servidor Hudson ...), el reposioty locales se llena de versiones antiguas rápidas
Actualización 2:
Para probar cómo y por qué esto falla, hice algunas pruebas más. Cada prueba se ejecuta contra todo limpio (de / glauche se elimina de ambas máquinas y nexus)
- Implementación de mvn con maven 2.2.1:
El repositorio local en la máquina A contiene snapshot.jar + snapshot-timestamp.jar
PERO: solo un jar con marca de tiempo en nexus, los metadatos dicen:
<?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>
- ejecutar las dependencias de actualización (en la máquina B) en m2eclipse (m3 final incrustado) -> el repositorio local tiene snapshot.jar + snapshot-timestamp.jar :(
- ejecutar el objetivo del paquete con maven externo 2.2.1 -> el repositorio local tiene snapshot.jar + snapshot-timestamp.jar :(
Ok, siguiente intento con maven 3.0.1 (después de eliminar todos los rastros del proyecto a)
el repositorio local en la máquina A se ve mejor, solo un jar sin marca de tiempo
solo un jar con marca de tiempo en nexus, los metadatos dicen:
de.glauche a 0.0.1-INSTANTÁNEA
<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>
ejecutar las dependencias de actualización (en la máquina B) en m2eclipse (m3 final incrustado) -> el repositorio local tiene snapshot.jar + snapshot-timestamp.jar :(
ejecutar el objetivo del paquete con maven externo 2.2.1 -> el repositorio local tiene snapshot.jar + snapshot-timestamp.jar :(
Entonces, para recapitular: el objetivo de "implementación" en maven3 funciona mejor que en 2.2.1, el repositorio local en la máquina creadora se ve bien. Pero, el receptor siempre termina con muchas versiones cronometradas ...
Qué estoy haciendo mal ?
Actualización 3
También probé varias otras configuraciones, primero reemplacé nexus con artifactory -> mismo comportamiento. Luego use clientes linux maven 3 para descargar las instantáneas del administrador del repositorio -> el repositorio local todavía tiene instantáneas con marca de tiempo :(
Respuestas:
La
<uniqueVersion>
configuración aplicada a los artefactos que se implementaron (a través de la implementación de mvn) en un repositorio de Maven como Nexus.Para eliminarlos de Nexus, puede crear fácilmente un trabajo automatizado para purgar el repositorio SNAPSHOT todos los días. Puede configurarse para retener una cierta cantidad de instantáneas o conservarlas durante un cierto período de tiempo. Es súper fácil y funciona muy bien.
Los artefactos en el repositorio local en una máquina de desarrollador llegan desde el objetivo de "instalación" y no usan estas marcas de tiempo ... simplemente siguen reemplazando la única versión SNAPSHOT a menos que también esté incrementando el número de revisión (por ejemplo, 1.0.0- SNAPSHOT a 1.0.1-SNAPSHOT).
fuente
~/.m2/repository
y cada unapom.xml
debe tener una definición de repositorio que apunte a una única instancia de Nexus en su LAN. (como muestra). Tenemos esta configuración, junto con Hudson que se basa en cada confirmación de Subversion y funciona muy bien. Las compilaciones SNAPSHOT se "implementan" en Nexus, donde se recopilan y depuran semanalmente. Las máquinas de desarrollo descargan automáticamente el último SNAPSHOT de Nexus~/.m2/repository
y reemplaza el descargado previamente. Los desarrolladores nunca deben tener su propia instancia de Nexus.Este complemento elimina los artefactos del proyecto del repositorio local. Útil para mantener solo una copia de una instantánea local grande.
<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>
fuente
Bueno, no me gustó ninguna de las soluciones propuestas. Eliminar la caché de Maven a menudo aumenta significativamente el tráfico de la red y ralentiza el proceso de compilación. build-helper-maven-plugin solo ayuda con un artefacto, quería una solución que pudiera purgar todos los artefactos de instantáneas con marca de tiempo obsoletos de la memoria caché local con un simple comando. Después de unos días de búsqueda, me di por vencido y decidí escribir un pequeño programa. El programa final parece estar funcionando bastante bien en nuestro entorno. Entonces decidí compartirlo con otras personas que puedan necesitar dicha herramienta. Las fuentes se pueden extraer de github: https://github.com/nadestin/tools/tree/master/MavenCacheCleanup
fuente
En cuanto a la parte del repositorio remoto de esto, creo que las respuestas anteriores que discuten una purga de SNAPSHOTs en un intervalo regular funcionarán. Pero nadie ha abordado la parte de su pregunta sobre la sincronización de la estación de trabajo del desarrollador local.
Todavía no hemos comenzado a usar Maven3, por lo que aún no hemos visto SNAPSHOTs comenzando a acumularse en las máquinas locales.
Pero hemos tenido diferentes problemas con m2eclipse. Cuando tenemos la "Resolución del área de trabajo" habilitada y el proyecto existe dentro de nuestro espacio de trabajo, las actualizaciones de fuentes generalmente nos mantienen a la vanguardia. Pero hemos descubierto que es muy difícil conseguir que m2eclipse se actualice con los artefactos publicados recientemente en Nexus. Estamos experimentando problemas similares dentro de nuestro equipo y es particularmente problemático porque tenemos un gráfico de proyecto muy grande ... hay muchas dependencias que no estarán en su espacio de trabajo, pero que se publicarán SNAPSHOT con frecuencia.
Estoy bastante seguro de que esto se reduce a un problema en m2eclipse en el que no maneja SNAPSHOT exactamente como debería. Puede ver en la consola de Maven dentro de eclipse donde m2eclipse le dice que se está saltando la actualización de un SNAPSHOT publicado recientemente porque tiene una versión en caché. Si hace una -U desde una configuración de ejecución o desde la línea de comando, Maven recogerá el cambio de metadatos. Pero una selección de "Actualizar instantáneas ..." debería indicarle a m2eclipse que Maven expire este caché. No parece que se esté transmitiendo. Parece haber un error que se archivó para esto si está interesado en votar por él: https://issues.sonatype.org/browse/MNGECLIPSE-2608
Mencionaste esto en un comentario en alguna parte.
La mejor solución para este problema parece ser que los desarrolladores depuren sus estaciones de trabajo locales cuando las cosas comiencen a fallar dentro de m2eclipse. Solución similar a un problema diferente ... Otros han informado problemas con Maven 2.2.1 y 3 m2eclipse de respaldo, y yo he visto lo mismo.
Espero que, si está utilizando Maven3, pueda configurarlo para que solo extraiga el último SNAPSHOT y lo almacene en caché durante el tiempo que dice el repositorio (o hasta que lo expire manualmente). Con suerte, entonces no necesitará tener un montón de SNAPSHOT en su repositorio local.
Eso es a menos que esté hablando de un servidor de compilación que está haciendo manualmente un
mvn install
en ellos. En cuanto a cómo evitar que SNAPSHOTs se acumule en un entorno como un servidor de compilación, hemos esquivado esa bala haciendo que cada compilación use su propio espacio de trabajo y repositorio local (aunque, en Maven 2.2.1, ciertas cosas como Parece que los POM siempre salen del repositorio ~ / .m2 /) Los SNAPSHOT adicionales realmente solo se quedan para una sola compilación y luego se eliminan (y se descargan nuevamente desde cero). Entonces, hemos visto que este enfoque termina consumiendo más espacio para empezar, pero tiende a permanecer más estable que tener todo resuelto desde un solo repositorio. Esta opción (en Hudson) se llama "Usar repositorio privado de Maven" y está debajo del botón Avanzado de la sección Compilar en configuraciones de proyectos cuando ha seleccionado compilar con Maven. Aquí está la descripción de ayuda para esa opción:Espero que esto ayude; si no soluciona su problema, avíseme dónde me perdí
fuente
En groovy , eliminar archivos con marca de tiempo como
artifact-0.0.1-20101204.150527-6.jar
puede ser muy simple: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 Groovy , guarde el script en un archivo y programe la ejecución cada semana, comience, inicie sesión, lo que más le convenga.
O incluso puede conectar la ejecución a la compilación de maven, utilizando gmavenplus-plugin . Observe, ¿cómo se establece la ubicación del repositorio por maven en la propiedad
settings.localRepository
y luego se vincula a través de la configuración en la variablerepository
:<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>
fuente
Agregue el siguiente parámetro en su archivo POM
POM
<configuration> <outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename> </configuration>
https://maven.apache.org/plugins/maven-dependency-plugin/copy-mojo.html
Ejemplo de 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>
Configurar en Jenkins:
// copy artifact copyMavenArtifact(artifact: "commons-collections:commons-collections:3.2.2:jar", outputAbsoluteArtifactFilename: "${pwd()}/target/my-folder/commons-collections.jar")
fuente