Maintenant que maven-3 a supprimé la prise en charge de <uniqueVersion> false </uniqueVersion> pour les artefacts de snapshot, il semble que vous ayez vraiment besoin d'utiliser des SNAPSHOTS horodatés. Surtout m2eclipse, qui utilise maven 3 en interne semble être affecté par lui, update-snapshots ne fonctionne pas lorsque les SNAPSHOTS ne sont pas uniques.
Il semblait préférable avant de définir tous les instantanés sur uniqueVersion = false
Maintenant, cela ne semble pas un gros problème de passer à la version horodatée, après tout, ils sont gérés par un référentiel central nexus, qui est capable de supprimer les anciens instantanés dans des intervalles réguliers.
Le problème, ce sont les postes de travail des développeurs locaux. Leur référentiel local devient rapidement très volumineux avec des instantanés uniques.
Comment faire face à ce problème?
En ce moment, je vois les solutions possibles suivantes:
- Demandez aux développeurs de purger le référentiel à intervalles réguliers (ce qui conduit à beaucoup de frustration, car il faut beaucoup de temps pour supprimer et encore plus pour télécharger tout le nécessaire)
- Configurez un script qui supprime tous les répertoires SNAPSHOT du référentiel local et demandez aux développeurs d'exécuter ce script de temps en temps (mieux que le premier, mais prend encore un certain temps à exécuter et télécharger les instantanés actuels)
- utiliser la dépendance: plugin purge-local-repository (a des problèmes lors de l'exécution à partir d'éclipse, en raison de fichiers ouverts, doit être exécuté à partir de chaque projet)
- configurer nexus sur chaque poste de travail et configurer un travail pour nettoyer les anciens instantanés (meilleur résultat, mais je ne veux pas maintenir plus de 50 serveurs nexus, plus la mémoire est toujours restreinte sur les postes de travail des développeurs)
- arrêter d'utiliser SNAPSHOTS du tout
Quelle est la meilleure façon d'empêcher votre dépôt local de remplir votre espace disque dur?
Mise à jour:
Pour vérifier le beaviour et pour donner plus d'informations, j'ai configuré un petit serveur nexus, construisez deux projets (a et b) et essayez:
une:
<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>
Maintenant, quand j'utilise maven et que j'exécute "deploy" sur "a", j'aurai
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
dans le référentiel local. Avec une nouvelle version d'horodatage à chaque fois que j'exécute la cible de déploiement. La même chose se produit lorsque j'essaye de mettre à jour des instantanés à partir du serveur nexus (fermez "un" projet, supprimez-le du référentiel local, construisez "b")
Dans un environnement où beaucoup de clichés get build (pensez serveur hudson ...), la reposioty locale se remplit avec les anciennes versions rapides
Mise à jour 2:
Pour tester comment et pourquoi cela échoue, j'ai fait d'autres tests. Chaque test est exécuté contre tout nettoyer (de / glauche est supprimé des deux machines et du nexus)
- mvn deploy avec maven 2.2.1:
le référentiel local sur la machine A contient snapshot.jar + snapshot-timestamp.jar
MAIS: un seul pot horodaté dans nexus, les métadonnées se lisent:
<?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>
- exécuter les dépendances de mise à jour (sur la machine B) dans m2eclipse (intégré m3 final) -> le référentiel local a snapshot.jar + snapshot-timestamp.jar :(
- Lancer l'objectif du package avec maven externe 2.2.1 -> le référentiel local a snapshot.jar + snapshot-timestamp.jar :(
Ok, essayez ensuite avec maven 3.0.1 (après avoir supprimé toutes les traces du projet a)
le référentiel local sur la machine A est meilleur, un seul fichier jar non horodaté
un seul pot horodaté dans nexus, les métadonnées se lisent:
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>
exécuter les dépendances de mise à jour (sur la machine B) dans m2eclipse (intégré m3 final) -> le référentiel local a snapshot.jar + snapshot-timestamp.jar :(
Lancer l'objectif du package avec maven externe 2.2.1 -> le référentiel local a snapshot.jar + snapshot-timestamp.jar :(
Donc, pour récapituler: l'objectif "déployer" dans maven3 fonctionne mieux que dans 2.2.1, le référentiel local sur la machine de création semble bien. Mais, le récepteur se termine toujours avec beaucoup de versions horodatées ...
Qu'est-ce que je fais mal ?
Mise à jour 3
J'ai également testé diverses autres configurations, d'abord remplacer le nexus par un artificiel -> même comportement. Ensuite, utilisez les clients linux maven 3 pour télécharger les instantanés à partir du gestionnaire de référentiel -> le référentiel local a toujours des instantanés horodatés :(
Réponses:
La
<uniqueVersion>
configuration appliquée aux artefacts qui ont été déployés (via mvn deploy) dans un référentiel Maven tel que Nexus.Pour les supprimer de Nexus, vous pouvez facilement créer une tâche automatisée pour purger le référentiel SNAPSHOT chaque jour. Il peut être configuré pour conserver un certain nombre de shapshots ou les conserver pendant un certain temps. C'est super facile et fonctionne très bien.
Les artefacts dans le référentiel local sur une machine de développeur y arrivent à partir de l'objectif "installer" et n'utilisent pas ces horodatages ... ils continuent juste à remplacer la seule et unique version SNAPSHOT à moins que vous n'incrémentiez également le numéro de révision (par exemple 1.0.0- INSTANTANÉ à 1.0.1-INSTANTANÉ).
la source
~/.m2/repository
et chacunpom.xml
doit avoir une définition de référentiel qui pointe vers une seule instance de Nexus sur votre LAN. (comme vous le montrez). Nous avons cette configuration, avec Hudson qui s'appuie sur chaque commit Subversion et cela fonctionne très bien. Les builds SNAPSHOT sont «déployés» sur Nexus où ils sont collectés et purgés chaque semaine. Les machines de développement téléchargent automatiquement le dernier SNAPSHOT de Nexus vers~/.m2/repository
et il remplace celui précédemment téléchargé. Les développeurs ne devraient jamais avoir leur propre instance Nexus.Ce plugin supprime les artefacts du projet du référentiel local. Utile pour ne conserver qu'une seule copie du grand instantané 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>
la source
Eh bien, je n'ai aimé aucune des solutions proposées. La suppression du cache maven augmente souvent considérablement le trafic réseau et ralentit le processus de construction. build-helper-maven-plugin n'aide qu'avec un seul artefact, je voulais une solution capable de purger tous les artefacts de snapshot horodatés obsolètes du cache local en une seule commande. Après quelques jours de recherche, j'ai abandonné et j'ai décidé d'écrire un petit programme. Le programme final semble fonctionner assez bien dans notre environnement. J'ai donc décidé de le partager avec d'autres personnes qui pourraient avoir besoin d'un tel outil. Les sources peuvent être extraites de github: https://github.com/nadestin/tools/tree/master/MavenCacheCleanup
la source
En ce qui concerne le dépôt distant, je pense que les réponses précédentes qui traitent d'une purge des SNAPSHOTs à intervalle régulier fonctionneront. Mais personne n'a abordé la partie de la synchronisation des postes de travail des développeurs locaux de votre question.
Nous n'avons pas encore commencé à utiliser Maven3, nous n'avons donc pas encore vu les SNAPSHOTs commencer à se développer sur les machines locales.
Mais nous avons eu différents problèmes avec m2eclipse. Lorsque la "Résolution de l'espace de travail" est activée et que le projet existe dans notre espace de travail, les mises à jour des sources nous maintiennent généralement à la pointe de la technologie. Mais nous avons trouvé qu'il est très difficile de faire en sorte que m2eclipse se mette à jour avec des artefacts récemment publiés dans Nexus. Nous rencontrons des problèmes similaires au sein de notre équipe et c'est particulièrement problématique car nous avons un très grand graphe de projet ... il y a beaucoup de dépendances qui ne seront pas dans votre espace de travail mais qui recevront des SNAPSHOTs publiés fréquemment.
Je suis presque sûr que cela revient à un problème dans m2eclipse où il ne gère pas les SNAPSHOTs exactement comme il se doit. Vous pouvez voir dans la console Maven dans eclipse où m2eclipse vous dit qu'il saute la mise à jour d'un SNAPSHOT récemment publié car il a une version en cache. Si vous effectuez un -U à partir d'une configuration d'exécution ou de la ligne de commande, Maven récupérera le changement de métadonnées. Mais une sélection "Mettre à jour les instantanés ..." devrait indiquer à m2eclipse que Maven expire ce cache. Cela ne semble pas être transmis. Il semble y avoir un bug là-bas qui est classé pour cela si vous êtes intéressé à voter pour cela: https://issues.sonatype.org/browse/MNGECLIPSE-2608
Vous en avez fait mention dans un commentaire quelque part.
La meilleure solution de contournement à ce problème semble être de demander aux développeurs de purger leurs postes de travail locaux lorsque les choses commencent à se détériorer à partir de m2eclipse. Solution similaire à un problème différent ... D'autres ont signalé des problèmes avec Maven 2.2.1 et 3 supportant m2eclipse, et j'ai vu la même chose.
J'espère que si vous utilisez Maven3, vous pouvez le configurer pour ne tirer que le dernier SNAPSHOT et le mettre en cache pendant la durée indiquée par le référentiel (ou jusqu'à ce que vous l'expiriez à la main). J'espère que vous n'aurez pas besoin d'avoir un tas d'instantanés assis dans votre référentiel local.
À moins que vous ne parliez d'un serveur de build qui effectue manuellement un
mvn install
sur eux. En ce qui concerne la façon d'empêcher les SNAPSHOTs de se développer sur un environnement comme un serveur de build, nous avons en quelque sorte esquivé cette balle en demandant à chaque build d'utiliser son propre espace de travail et son référentiel local (bien que, dans Maven 2.2.1, certaines choses telles que Les POM semblent toujours sortir du ~ / .m2 / repository) Les SNAPSHOTs supplémentaires ne restent vraiment que pour une seule construction, puis ils sont supprimés (et téléchargés à nouveau à partir de zéro). Nous avons donc vu que cette approche finit par consommer plus d'espace au départ, mais elle a tendance à rester plus stable que de tout résoudre à partir d'un seul référentiel. Cette option (sur Hudson) s'appelle «Utiliser le référentiel Maven privé» et se trouve sous le bouton Avancé de la section Construire sur les configurations de projet lorsque vous avez choisi de construire avec Maven. Voici la description de l'aide pour cette option:J'espère que cela vous aidera - si cela ne résout pas votre problème, veuillez me faire savoir où j'ai manqué.
la source
Dans groovy , supprimer des fichiers horodatés comme
artifact-0.0.1-20101204.150527-6.jar
peut être très 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() } }
Installez Groovy , enregistrez le script dans un fichier et planifiez l'exécution à chaque semaine, démarrez, connectez-vous, ce qui vous convient.
Ou, vous pouvez même câbler l'exécution dans maven build, en utilisant gmavenplus-plugin . Remarquez, comment l'emplacement du référentiel est-il défini par maven dans la propriété
settings.localRepository
, puis lié via la configuration à 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>
la source
Ajoutez le paramètre suivant dans votre fichier POM
POM
<configuration> <outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename> </configuration>
https://maven.apache.org/plugins/maven-dependency-plugin/copy-mojo.html
Exemple 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>
Configurer dans Jenkins:
// copy artifact copyMavenArtifact(artifact: "commons-collections:commons-collections:3.2.2:jar", outputAbsoluteArtifactFilename: "${pwd()}/target/my-folder/commons-collections.jar")
la source