È possibile specificare un Java classpath
che include un file JAR contenuto in un altro file JAR?
È possibile specificare un Java classpath
che include un file JAR contenuto in un altro file JAR?
Risposte:
Se stai cercando di creare un singolo jar che contenga la tua applicazione e le sue librerie richieste, ci sono due modi (di cui sono a conoscenza) per farlo. Il primo è One-Jar , che utilizza uno speciale caricatore di classi per consentire l'annidamento di vasetti. Il secondo è UberJar , (o Shade ), che esplode le librerie incluse e mette tutte le classi nel barattolo di livello superiore.
Vorrei anche menzionare che UberJar e Shade sono plugin per Maven1 e Maven2 rispettivamente. Come menzionato di seguito, puoi anche usare il plugin assembly (che in realtà è molto più potente, ma molto più difficile da configurare correttamente).
NON si desidera utilizzare quelle soluzioni "esplodi contenuti JAR". Rendono sicuramente più difficile vedere le cose (dal momento che tutto è esploso allo stesso livello). Inoltre, potrebbero esserci conflitti di denominazione (non dovrebbe accadere se le persone usano pacchetti adeguati, ma non puoi sempre controllarlo).
La caratteristica che desideri è una delle 25 migliori RFE Sun : RFE 4648386 , che Sun, nella sua infinita saggezza, ha designato come di bassa priorità. Possiamo solo sperare che Sun si svegli ...
Nel frattempo, la migliore soluzione che ho trovato (che vorrei che Sun copiasse nel JDK) è usare il caricatore di classi personalizzato JarClassLoader .
activation.jar
).
Dopo alcune ricerche ho trovato un metodo che non richiede maven o alcuna estensione / programma di terze parti.
Puoi usare "Class-Path" nel tuo file manifest.
Per esempio:
Creare il file manifest MANIFEST.MF
Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass
Compila tutte le tue lezioni ed esegui jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar
c
sta per creare archivio
f
indica che si desidera specificare il file
v
è per input dettagliato
m
significa che passeremo un file manifest personalizzato
Assicurati di aver incluso lib nel pacchetto jar. Dovresti essere in grado di eseguire jar in modo normale.
basato su: http://www.ibm.com/developerworks/library/j-5things6/
tutte le altre informazioni di cui hai bisogno sul percorso di classe che trovi qui
custom_lib.jar
allontanato, il vaso non può più essere eseguito :(
Usa il tag zipgroupfileset (usa gli stessi attributi di un tag fileset ); decomprimerà tutti i file nella directory e li aggiungerà al nuovo file di archivio. Ulteriori informazioni: http://ant.apache.org/manual/Tasks/zip.html
Questo è un modo molto utile per aggirare il problema jar-in-a-jar - lo so perché ho cercato su Google questa esatta domanda StackOverflow mentre cercavo di capire cosa fare. Se vuoi impacchettare un barattolo o una cartella di vasetti nel tuo unico barattolo con Ant, allora dimentica tutto questo percorso di classe o plugin di terze parti, tutto ciò che devi fare è questo (in Ant):
<jar destfile="your.jar" basedir="java/dir">
...
<zipgroupfileset dir="dir/of/jars" />
</jar>
Se stai costruendo con la formica (sto usando la formica da eclissi), puoi semplicemente aggiungere i file jar extra dicendo a formica di aggiungerli ... Non necessariamente il metodo migliore se hai un progetto gestito da più persone ma funziona per il progetto di una persona ed è facile.
per esempio il mio obiettivo che stava costruendo il file .jar era:
<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
<manifest>
<attribute name="Author" value="ntg"/>
................................
<attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
</manifest>
</jar>
Ho appena aggiunto una riga per farlo:
<jar ....">
<zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
<manifest>
................................
</manifest>
</jar>
dove
<property name="external-lib-dir"
value="C:\...\eclipseWorkspace\Filter\external\...\lib" />
era il dir con i barattoli esterni. E questo è tutto ...
È necessario creare un caricatore di classi personalizzato per eseguire questa o una libreria di terze parti che supporti questo. La soluzione migliore è estrarre il jar dal runtime e aggiungerli al percorso di classe (o averli già aggiunti al percorso di classe).
Uso maven per le mie build java che ha un plugin chiamato plugin assembly maven .
Fa quello che stai chiedendo, ma come alcuni degli altri suggerimenti descrivono - essenzialmente esplodendo tutti i barattoli dipendenti e ricombinandoli in un singolo barattolo
Se disponi di IDE eclpise, devi solo esportare il tuo JAR e scegliere "Librerie di pacchetti richiesti in JAR generato". eclipse aggiungerà automaticamente i JAR dipendenti richiesti nel JAR generato, oltre a generare un caricatore di classi personalizzate eclipse che carica automaticamente questi JAR.
Winstone è abbastanza buono http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/ . Ma non per siti complessi. E questo è un peccato perché tutto ciò che serve è includere il plugin.
Bene, c'è un modo molto semplice se stai usando Eclipse.
Esporta il tuo progetto come file Jar "eseguibile" (fai clic con il pulsante destro del mouse sulla cartella del progetto da Eclipse, seleziona "Esporta ..."). Quando si configurano le impostazioni di esportazione, assicurarsi di selezionare "Estrai le librerie richieste nel Jar generato". Ricorda, seleziona "Estrai ..." e non "Librerie richieste dal pacchetto ...".
Inoltre : è necessario selezionare una configurazione di esecuzione nelle impostazioni di esportazione. Quindi, potresti sempre creare un main () vuoto in qualche classe e usarlo per la tua configurazione di esecuzione.
Ad ogni modo, non è garantito che funzioni il 100% delle volte, poiché noterai un messaggio pop-up che ti dice di assicurarti di controllare le licenze dei file Jar che stai includendo e qualcosa sul non copiare i file delle firme. Tuttavia, lo faccio da anni e non ho mai riscontrato problemi.
L'estrazione in una Uber-dir funziona per me come dovremmo tutti usare root: \ java e avere il codice delle uscite nei pacchetti con controllo delle versioni. Vale a dire ca.tecreations-1.0.0. La firma va bene perché i barattoli sono intatti dalla loro posizione scaricata. Firme di terze parti intatte, estratto in c: \ java. C'è il mio dir di progetto. eseguito dal programma di avvio, quindi java -cp c: \ java Launcher