2009-12-02 9 views
26

Sto provando a creare un jar eseguibile (usando maven) che contiene le classi del progetto e le sue dipendenze con un file manifest che ha la voce per la classe principale e la voce del percorso classe che punta alle dipendenze contenute nella radice di il vaso; qualcosa di simile:È possibile creare un jar "uber" contenente le classi del progetto e le dipendenze del progetto come jar con un file manifest personalizzato?

manifest File:

 
..... 
Main-Class : com.acme.MainClass 
Class-Path : dependecy1.jar dependecy2.jar 
..... 

Jar:

 
jar-root 
|-- .... 
|-- com/acme/../*.class 
|-- dependecy1.jar 
`-- dependecy2.jar 

sto usando il Maven-jar-plugin per creare il file manifesto e l'esperto-ombra -plugin per creare il "ub er "jar ma le dipendenze vengono decompresse e aggiunte come classi al mio jar.

risposta

56

In realtà, non ho verificato che cosa sta facendo esattamente lo maven-shade-plugin (o qualsiasi altro plugin) poiché maven 2 ha tutto incorporato per creare un megajar o un uberjar. Devi solo usare il plugin maven-assembly-con il descrittore jar-with-dependencies predefinito.

Basta aggiungere questo frammento al pom.xml per personalizzare il manifesto:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-assembly-plugin</artifactId> 
    <configuration> 
    <archive> 
     <manifest> 
     <mainClass>my.package.to.my.MainClass</mainClass> 
     </manifest> 
    </archive> 
    </configuration> 
</plugin> 

E il seguente comando genererà il vostro uberjar:

mvn assembly:assembly -DdescriptorId=jar-with-dependencies 

Ma, ancora una volta, il comportamento predefinito di questo descrittore è per decomprimere le dipendenze (come il plugin maven-shade-plugin). Per essere onesti, non capisco perché questo è un problema ma, se questo non è realmente quello che vuoi, puoi usare il tuo descrittore di assemblaggio personalizzato.

Per farlo, in primo luogo, creare il descrittore di assemblaggio, diciamo src/assembly/uberjar.xml, con il seguente contenuto:

<assembly> 
    <id>uberjar</id> 
    <formats> 
    <format>jar</format> 
    </formats> 
    <includeBaseDirectory>false</includeBaseDirectory> 
    <dependencySets> 
    <dependencySet> 
     <unpack>false</unpack> 
     <scope>runtime</scope> 
     <useProjectArtifact>false</useProjectArtifact> 
    </dependencySet> 
    </dependencySets> 
    <fileSets> 
    <fileSet> 
     <directory>${project.build.outputDirectory}</directory> 
     <outputDirectory>/</outputDirectory> 
    </fileSet> 
    </fileSets> 
</assembly> 

Poi, configurare l'esperto-assemblaggio-plugin per utilizzare questo descrittore e di aggiungere le dipendenze a la Class-Path ingresso del manifesto:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-assembly-plugin</artifactId> 
    <configuration> 
    <descriptors> 
     <descriptor>src/assembly/uberjar.xml</descriptor> 
    </descriptors> 
    <archive> 
     <manifest> 
     <mainClass>my.package.to.my.MainClass</mainClass> 
     <addClasspath>true</addClasspath> 
     </manifest> 
    </archive> 
    </configuration> 
    <!-- 
    <executions> 
    <execution> 
     <phase>package</phase> 
     <goals> 
     <goal>single</goal> 
     </goals> 
    </execution> 
    </executions> 
    --> 
</plugin> 

Infine gestita mvn assembly:assembly per produrre il vostro uberjar.

Facoltativamente, rimuovere il commento dall'elemento executions per associare il plug-in di assembly sulla fase package (e avere l'assembly prodotto come parte della build normale).

+4

+1, risposta incredibilmente utile. Potrei immaginare che alcuni produttori di software, specialmente al di fuori del sistema operativo, possano proibire il "disassemblaggio/decodificazione" del loro prodotto, o insistere sul fatto che il loro imballaggio sia mantenuto così com'è, incluso il nome del file, ecc. Assemblaggio –

+1

: il montaggio è stato sostituito dal montaggio : single di recente. (Sono su assembly-plugin versione 2.3) Il plug-in di assembly –

+0

è un plug-in proprio come il plug-in per l'ombra, quindi non è "build in" –

0

So di due prodotti che fanno questo:

  • Uno si chiama 'bigjar', ma questo è troppo generale un termine per essere utile in una ricerca su Google; Non ero in grado di trovarlo.
  • L'altro è chiamato 'onejar'. Ci sono alcuni riferimenti ad esso e afferma di fare ciò che ti serve.

Ecco un post da qualcuno che usa OneJar in un assieme di Maven:

http://5341.com/list/55/498657.html

2

Ho usato FatJar per questo in passato. http://fjep.sourceforge.net/

Avevo creato un'applicazione relativamente semplice, il client voleva fare doppio clic su un file eseguibile e farlo funzionare. Installatori o dipendenze sono fuori questione. Fatjar ha raggruppato le librerie del progetto e i file di riferimento di Eclipse in un vaso eseguibile da diversi megabyte. Flawless.

+0

È un plug-in di Eclipse? Se è così, non vedo come risponde alla domanda. L'OP sta chiedendo una soluzione Maven ... –

+0

Hai ragione, ho letto male quella parte. Credo che stavo pensando che potrebbe essere applicato ad altre aree, dal momento che tutti gli IDE sono poco più di wrapper di wrapper di script. – Karl