Come specificare la distribuzione di Maven in tutta l'organizzazione?


110

Sto cercando di capire come organizzare molti (circa 50+) progetti maven2, in modo che possano essere distribuiti in un repository nexus centrale. Quando si utilizza l' mvn deployobiettivo, è necessario specificare l'obiettivo nel tag distributionManagement in questo modo:

<distributionManagement>
   <repository>
      <id>nexus-site</id>
        <url>http://central_nexus/server</url>
   </repository>
</distributionManagement>

Ora, non voglio che ogni singolo pom.xml (di quei 50+) contenga questo blocco più e più volte. Il mio primo pensiero sarebbe il settings.xmlfile, ma sembra che non sia possibile (in base alla progettazione) definirlo lì. Quindi, la prima domanda sarebbe: perché è così? Se fosse possibile, potrei specificarlo nel settings.xml nella distribuzione di maven2, che potrebbe essere distribuito a tutti gli sviluppatori.

L'unica soluzione possibile che ho trovato è stata creare un progetto master-pom a livello di organizzazione, che contenga queste impostazioni e fare in modo che tutti gli altri pom.xml dipendano da questo master-pom tramite <parent>tag. Ma questo sembra un po 'strano nelle build multi-modulo:

- master configuration POM (pm)
- Project 1 parent pom (p1 with module 1 and module 2 as modules)
    - Project 1 module pom (with pm as parent)
    - Project 2 module pom (with pm as parent)

Di solito leggo in tutta la documentazione che il modulo poms dovrebbe usare il genitore pom, non uno diverso. Ma dopo aver letto il sito web di Maven su Inheritance v. Aggregation è scritto che è davvero possibile.

Un problema che ho riscontrato è stato con la generazione del sito Maven, che sembra avere problemi con questa configurazione (i moduli non vengono collegati correttamente se non hanno un riferimento a ritroso diretto)

Quindi è un approccio valido? Qualche altra soluzione, più ovvia e più semplice al problema?



5
@OhadR: Scrivono solo come scriverlo in un progetto. Il punto è che non volevo duplicarlo circa 500 volte ...
mglauche

1
Vedo. punto preso. così come ha detto colui che ha risposto, puoi avere un pom principale per il progetto, che conterrà il 'distribMngmnt' ...
OhadR

Risposte:


144

La soluzione migliore per questo è creare un semplice progetto di file pom genitore (con packaging 'pom') genericamente per tutti i progetti della tua organizzazione.

<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>your.company</groupId>
    <artifactId>company-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <distributionManagement>
        <repository>
            <id>nexus-site</id>
            <url>http://central_nexus/server</url>
        </repository>
    </distributionManagement>

</project>

Questo può essere creato, rilasciato e distribuito al tuo nesso locale in modo che tutti abbiano accesso al suo artefatto.

Ora per tutti i progetti che desideri utilizzarlo, includi semplicemente questa sezione:

<parent>
  <groupId>your.company</groupId>
  <artifactId>company-parent</artifactId>
  <version>1.0.0</version>
</parent>

Questa soluzione ti consentirà di aggiungere facilmente altre cose comuni a tutti i progetti della tua azienda. Ad esempio, se volessi standardizzare l'utilizzo di JUnit su una versione specifica, questo sarebbe il posto perfetto per questo.

Se hai progetti che utilizzano strutture multi-modulo che hanno il loro genitore, Maven supporta anche il concatenamento dell'ereditarietà, quindi è perfettamente accettabile che il file pom genitore del tuo progetto si riferisca al pom genitore della tua azienda e che i moduli figlio del progetto non siano nemmeno a conoscenza del tuo capogruppo dell'azienda.

Vedo dalla struttura del tuo progetto di esempio che stai tentando di mettere il tuo progetto genitore allo stesso livello del tuo aggregatore pom. Se il tuo progetto necessita del proprio genitore, l'approccio migliore che ho trovato è quello di includere il genitore allo stesso livello del resto dei moduli e avere il tuo file aggregatore pom.xml alla radice di dove esistono tutte le directory dei tuoi moduli.

- pom.xml (aggregator)
    - project-parent
    - project-module1
    - project-module2

Quello che fai con questa struttura è includere il tuo modulo genitore nell'aggregatore e costruire tutto con un mvn installdalla directory principale.

Usiamo questa soluzione esatta nella mia organizzazione e ha superato la prova del tempo e ha funzionato abbastanza bene per noi.


Ecco un'altra risposta in cui descrivo l'ereditarietà del progetto in modo più dettagliato e come gestirne la complessità ereditaria, scusate il gioco di parole. ;) stackoverflow.com/questions/6347913
Jesse Webb

7
Solo una piccola nota: per i motivi per cui la società madre è la soluzione migliore, vedere la discussione Can't specify distributionManagement in settings.xml dall'elenco degli utenti di Maven.
Premek Brada

Nel modello di consulenza classico, in cui "il cliente possiede il codice", il mio team di sviluppo dovrà lavorare sul progetto fuori sede, quindi portare il codice più recente sul sito del cliente e crearlo di nuovo. Nella mia situazione, lavorando con un progetto multi-modulo, se faccio riferimento alla POM aziendale nella POM madre del progetto, dovrò aggiornare quel riferimento in modo che punti alla POM dell'azienda del cliente. Preferisco sforzarmi di mantenere tutte le impostazioni specifiche dell'ambiente in settings.xml se posso aiutarlo. Qual è l'approccio consigliato per la mia situazione?
Utente Web

2
@WebUser Il tuo problema suona più come una situazione in cui hai bisogno di valori diversi nei tuoi file POM rispetto a ciò che questa risposta risolve: evitare impostazioni duplicate su più moduli. Penso che dovresti provare a inserire le proprietà tramite un file settings.xml . Se questo non ti aiuta, fai una nuova domanda qui su SO, collegalo qui e cercherò di aiutarti ulteriormente.
Jesse Webb

Grazie @JesseWebb Ho finito per provarlo ed è utile astrarre quei valori dal POM per la situazione che ho descritto. Per le mie esigenze, ho aggiunto proprietà rilevanti sotto il profilo attivo e quelle risolte nel POM.
Utente Web

36

Non è necessario un POM genitore.

Puoi omettere completamente la parte di gestione della distribuzione nei tuoi poms e impostarla sul tuo server di compilazione o in settings.xml.

Per farlo sul server di compilazione, basta passare al mvncomando:

-DaltSnapshotDeploymentRepository=snapshots::default::https://YOUR_NEXUS_URL/snapshots
-DaltReleaseDeploymentRepository=releases::default::https://YOUR_NEXUS_URL/releases

Vedere https://maven.apache.org/plugins/maven-deploy-plugin/deploy-mojo.html per i dettagli sulle opzioni che possono essere impostate.

È anche possibile impostarlo nel tuo file settings.xml.

Basta creare un profilo lì che è abilitato e contiene la proprietà.

Settings.xml di esempio:

<settings>
[...]
  <profiles>
    <profile>
      <id>nexus</id>
      <properties>
        <altSnapshotDeploymentRepository>snapshots::default::https://YOUR_NEXUS_URL/snapshots</altSnapshotDeploymentRepository>
        <altReleaseDeploymentRepository>releases::default::https://YOUR_NEXUS_URL/releases</altReleaseDeploymentRepository>
      </properties>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>nexus</activeProfile>
  </activeProfiles>

</settings>

Assicurati che le credenziali per "snapshot" e "release" siano nella <servers>sezione del tuo settings.xml

Le proprietà altSnapshotDeploymentRepository e altReleaseDeploymentRepository sono state introdotte con maven-deploy-plugin versione 2.8. Le versioni precedenti non funzioneranno con il messaggio di errore

Deployment failed: repository element was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter

Per risolvere questo problema, puoi applicare una versione più recente del plug-in:

        <build>
          <pluginManagement>
            <plugins>
              <plugin>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8</version>
              </plugin>
            </plugins>
          </pluginManagement>
        </build>

Sto provando continuamente questa soluzione ma funziona solo la proprietà altDeploymentRepository . altReleaseDeploymentRepository e altSnapshotDeploymentRepository non vengono riconosciuti e ottengo questo errore: Distribuzione non riuscita: l'elemento del repository non è stato specificato nell'elemento POM all'interno di distributionManagement o in -DaltDeploymentRepository = id :: layout :: url paramete. Qualsiasi suggerimento aiuterebbe. Grazie
Shabirmean

@Shabirmean Il motivo è una versione troppo vecchia del plug-in di distribuzione. Ho esteso la mia risposta con una soluzione.
Michael Wyraz

Sì, l'ho capito. Grazie mille :)
Shabirmean
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.