2015-01-30 17 views
8

Abbiamo bisogno di costruire un jar, usando Maven, in modo che tutte le sue dipendenze siano incluse, ma anche che tutte queste dipendenze vengano ridenominate (riposizionate).Maven - C'è un modo per creare facilmente un jar 'uber' con tutte le dipendenze trasferite?

Diciamo che i nostri pacchetti all iniziare con com.mycompagny.projectx.*". Vogliamo che le dipendenze del progetto per avere il loro pacchetto rinominato inizia con 'embedded', ma non le nostre classi.

Utilizzando maven-shade-plugin per esempio, io sono non è in grado di raggiungere questo obiettivo:.

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-shade-plugin</artifactId> 
    <version>2.3</version> 
    <configuration> 
     <shadedArtifactAttached>true</shadedArtifactAttached> 
     <createDependencyReducedPom>true</createDependencyReducedPom> 
     <artifactSet> 
      <includes> 
       <include>*.*</include> 
      </includes> 
     </artifactSet> 
     <relocations> 
      <relocation> 
       <pattern>*</pattern> 
       <shadedPattern>embedded.</shadedPattern> 
       <excludes> 
        <exclude>com.mycompagny.projectx.*</exclude> 
       </excludes> 
      </relocation> 
     </relocations> 
    </configuration> 
    <executions> 
     <execution> 
      <phase>package</phase> 
      <goals> 
       <goal>shade</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 

Qui <pattern>*</pattern> non è valido Inoltre, se uso <pattern></pattern> (stringa vuota), allora tutto è trasferito al pacchetto "embedded", anche le risorse (il "META -INF "di canonica)! Ovviamente vogliamo che le risorse rimangano alla radice del barattolo.

credo che potremmo creare più <relocation> elementi, uno per ogni pacchetto delle dipendenze, ma che sarebbe un sacco di lavoro: <relocation>com</relocation>, <relocation>net</relocation>, <relocation>javax</relocation>, ecc

Qualche idea su come trasferirsi facilmente tutte le dipendenze all'interno del jar uber, senza toccare le nostre classi, risorse e la directory "META-INF"?

risposta

6

AGGIORNAMENTO: questa soluzione non funziona, si prega di leggere fino alla fine.

Ho trovato una soluzione osservando il codice sorgente di maven-shade-plugin! Non sembra essere documentato da nessuna parte, ma c'è un parametro <rawString> che è possibile aggiungere a un elemento <relocation> quindi consideres la <pattern> e <shadedPattern> come normali modelli di espressione e non come nomi di pacchetto/file.

Il codice maven-shade-plugin utilizza poi qualcosa di simile:

path.replaceAll(pattern, shadedPattern) 

far fronte a tali modelli.

Esempio:

<relocation> 
    <pattern>^([^/]*\.properties)$</pattern> 
    <shadedPattern>embedded/$1</shadedPattern> 
    <rawString>true</rawString> 
</relocation> 

Questo è un esempio fittizio che trasferisce tutti i file .properties che sono nella radice. Usando questa tecnica, sarà possibile controllare esattamente cosa viene ricollocato e come, ne sono abbastanza sicuro.

Ecco un esempio migliore, che fa quello che mi serve (ancora un po 'di test a che fare però):

<relocation> 
    <pattern>^(?!(com/mycompagny/|META-INF))(.*/.*)$</pattern> 
    <shadedPattern>embedded/$2</shadedPattern> 
    <rawString>true</rawString> 
</relocation> 

UPDATE: Purtroppo, questo ultimo modello significa che tutto utilizzato sarà rinominato, ad eccezione di "com. mycompagny "e la cartella META-INF. Il problema è che cose come java.lang.Object saranno rinominate! E quando viene eseguito il codice, vengono lanciate eccezioni come questa:

java.lang.ClassNotFoundException: embedded.java.lang.Object 
+0

Mentre questo non risolveva il problema ... Questo _IS_ è una funzionalità non documentata estremamente utile.Ho risorse che dovevano essere spostate in una cartella diversa (non nel codice sorgente e non nella struttura del pacchetto). Grazie per la scrittura. – Lucas