2010-03-13 11 views
7

Ho un programma che ha bisogno di diverse librerie di terze parti, e in questo momento è confezionato in questo modo:Qual è la procedura migliore per includere file jar di terze parti in un programma Java?

 
zerobot.jar (my file) 
libs/pircbot.jar 
libs/mysql-connector-java-5.1.10-bin.jar 
libs/c3p0-0.9.1.2.jar 

Per quanto ne so il modo "migliore" per gestire librerie di terze parti è quello di mettere loro sul classpath nel file manifest del mio file jar, che funzionerà su più piattaforme, non rallenterà il lancio (che potrebbe raggrupparli) e non incorrerà in problemi legali (quale potrebbe essere il riconfezionamento).

Il problema è per gli utenti che forniscono loro stessi le librerie di terze parti (esempio, caso d'uso, aggiornamento per correggere un bug). Due delle librerie hanno il numero di versione nel file, il che aggiunge fastidio.

La mia soluzione attuale è che il mio programma ha un processo di bootstrap che rende un nuovo classloader e crea un'istanza del programma che lo utilizza. Questo classloader personalizzato aggiunge tutti i file .jar in lib/al suo classpath.

mio attuale modo funziona bene, ma ora ho due classloader personalizzati nella mia richiesta e una recente modifica al codice ha causato problemi che sono difficili da eseguire il debug, quindi se c'è un modo migliore vorrei rimuovere questo complessità. Sembra anche un eccesso di ingegneria per quello che sono sicuro sia una situazione molto comune.

Quindi la mia domanda è, come dovrei fare questo?

+0

@ZoFrex: perché utilizzare un nuovo caricatore di classe? Perché non utilizzare semplicemente il caricatore di classi predefinito che è sempre un URLClassLoader (AFAIK)? In questo modo avresti solo un caricatore di classe. Ecco come lo sto facendo e sto distribuendo su centinaia di macchine OS X e Windows (nel caso in cui colpisca la ventola, cambierei il modo in cui la sto facendo;) – SyntaxT3rr0r

+0

In realtà uso un URLClassLoader . Ne creo uno nuovo per iniettare il classpath dinamico, non puoi modificare quello predefinito. Il secondo classloader che ho scritto in precedenza, per il sistema di plugin. – ZoFreX

risposta

5

Forniamo file di script con il jar. Per esempio. some.bat, some.sh ecc.

E come per Java6, è possibile utilizzare il carattere jolly per specificare i percorsi di classe.

Ecco un buon articolo che spiega questo approccio: https://blogs.oracle.com/mr/entry/class_path_wildcards_in_mustang

+1

@Zwei steinen: vuole essere multipiattaforma. Java 6 significa che ti taglierai da una parte enorme della base utente OS X che ha Mac che non avranno mai ufficialmente Java 6 (CPU Mac a 32 bit). – SyntaxT3rr0r

+0

Ehhhh per questo progetto La compatibilità con OS X non è molto grossa, e comunque ho compilato la versione 1.6. Grazie comunque per il suggerimento, dovrò verificare che i miei altri progetti funzionino su 1.5! – ZoFreX

+0

Ho intenzione di specificare il classpath nel manifest jar e di richiedere che l'utente finale denomini correttamente le librerie di terze parti quando le aggiornano. Tuttavia, sto contrassegnando questo come accettato come se avesse le informazioni più interessanti. – ZoFreX

0

Puoi provare la soluzione Fat-Jar, funziona perfettamente con il 'Fat Jar Eclipse Plug-In'. Ho usato per alcuni progetti senza problemi. Il principio di ciò sembra essere lo stesso della tua attuale soluzione.

+0

Se sto leggendo correttamente, gestisce solo la confezione per la mia distribuzione e non per gli utenti che aggiornano le loro librerie esterne? – ZoFreX

+0

@bpfurtado: +1, o usa "izpack" ... O fai lo stesso, non è difficile. – SyntaxT3rr0r

+0

fat-jar è solo una questione di packaging e non fornisce un meccanismo di aggiornamento per le librerie incluse. Per quanto riguarda le tue difficoltà nel dubug usando un Classloader personalizzato, eseguo tutto lo sviluppo/debug all'interno del mio IDE e, successivamente, utilizzo fat-jar per effettuare la distribuzione, tutti i test lasciati a fare con il solitario "packed" sarebbero correlati a "ClassNotFoundException" , cosa non succede mai, dal momento che "barattolo di grasso" funziona piuttosto bene. – sysoutnull

0

penso che ho intenzione di andare via manifesto. Dichiarare il classpath nel manifesto per il vaso di ingresso, e hanno voci per:

 
libs/pircbot.jar 
libs/mysql-connector-java-5-bin.jar 
libs/c3p0.jar 

Poi, se gli utenti vogliono aggiornare alle ultime versioni della libreria, dovranno rinominare loro di corrispondere a quanto dichiarato nel manifesto. Non penso che sia una seccatura troppo grande, e rende le cose molto più semplici internamente.

Inoltre, in genere non mi piace l'idea di caricare tutto in ./lib/ automaticamente, che sembra potenzialmente pericoloso.

1

Se il pubblico è tecnico (e sembra che lo siano se è disposto a inserire nuovi file jar), allora potresti fornire i file .sh e .bat che possono essere modificati per modificare il classpath? Ciò sarà più trasparente per loro rispetto a un classloader personalizzato.

+0

Questo non è un approccio negativo, ma complica le cose quando aggiornano il jar del programma principale, in quanto le modifiche dovrebbero essere rifatte. Penso che in generale chiedere loro di rinominare i file sia l'approccio migliore, ma se ci sono dei reclami, probabilmente andrò su questa strada. – ZoFreX

Problemi correlati