|
| HOMEPAGE | INDICE FORUM | REGOLAMENTO | ::. | NEI PREFERITI | .:: | RSS Forum | RSS News | NEWS web | NEWS software | |
| PUBBLICITA' | | | ARTICOLI | WIN XP | VISTA | WIN 7 | REGISTRI | SOFTWARE | MANUALI | RECENSIONI | LINUX | HUMOR | HARDWARE | DOWNLOAD | | | CERCA nel FORUM » | |
![]() |
#1 |
Gold Member
Top Poster
Registrato: 18-07-2002
Messaggi: 6.399
![]() |
[Java] Caricare dinamicamente un jar e usare tutte le sue classi
![]() E' da un po' che sto cercando di risolvere questo problema ma non ne vengo a capo ![]() Ho un programma Java che ha bisogno di usare delle classi contenute in dei file jar, e fin qui niente di male: basta mettere il file jar nel CLASSPATH e tutto funziona tranquillamente. Il fatto è che devo caricare il jar a runtime, perchè questo si può trovare in un qualsiasi percorso del file system locale, quindi niente posizionamento fisso nella variabile d'ambiente CLASSPATH. Ho provato modificando il java.class.path così: Codice:
String oldPath = System.getProperty("java.class.path"); String newPath = oldPath + "ilMioFileJar.jar;"; System.setProperty("java.class.path", newPath); Ho quindi ben pensato di usare la classe URLClassLoader. Finchè devo caricare una sola classe niente di male, il problema viene propio con i jar. Ecco il codice che ho usato: Codice:
File f = new File("ilMioFileJar.jar"); //creo un array contenente l'url del mio file jar URL[] url = new URL[]{f.toURL()}; //lo do in pasto al classloder URLClassLoader mioCL = new URLClassLoader(url); //piglio la classe che mi serve istanziare Class c = mioCL.loadClass("ClasseCheMiServe"); //prendo un'istanza della classe TipoDellaClasse tdc = (TipoDellaClasse)c.newInstance() //e adesso uso la classe! Mi viene restituito un errore del tipo "mi manca la classe pack1.pack2.ClasseX" e allora ho provato anche a fare il loading preventivo di questa classe: Codice:
//piglio la classe che mi serve istanziare Class c = mioCL.loadClass("ClasseCheMiServe"); //piglio la classe che mi viene segnalata nell'errore Class d = mioCL.loadClass("pack1.pack2.ClasseX"); //prendo un'istanza della classe TipoDellaClasse tdc = (TipoDellaClasse)c.newInstance() //e adesso uso la classe! Come faccio? C'è un modo per fare il loading "completo" di un jar, o un modo per fare caricare dinamicamente le classi presenti nel jar in caso di necessità? Oppure il problema va affrontato con l'uso di altre classi? Resta sempre il vincolo che il .jar non può essere specificato nella variabile di sistema CLASSPATH, poichè l'utente (bastardo) può decidere di metterlo dove vuole sul proprio disco e me lo indica con una bella finestrella di dialogo durante l'esecuzione del programma. Se non avete capito qualcosa perchè mi sono espresso male (sicuro!) chiedetemi pure ![]() Grazie a tutti ![]() ![]() |
![]() |
![]() |
![]() |
#2 |
Gold Member
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
![]() |
Ciao Dav,
complimenti per le soluzioni che hai cercato ed utilizzato... anch'io spesso ho questo tipo di problemi e non mi è mai piaciuto il sistema di "deploy" di Java (se devo essere proprio sincero...) Quindi volevo cheiderti: In che momento l'utente ti specifica questo Jar? .. All'inizio dell'esecuzione del tuo programma? .. In fase di installazione? .. oppure proprio mentre lo sta usando?... E anche un'altra cosa: E' possibile spezzare il programma in due... ? Poi ti spiego cosa ho in mente... Bye ![]() |
![]() |
![]() |
![]() |
#3 |
Gold Member
Top Poster
Registrato: 18-07-2002
Messaggi: 6.399
![]() |
Ciao Web, grazie
![]() Il programma principale parte, l'utente può, tramite menu, indicarmi il file jar da utilizzare (un programma esterno a cui devo dare in pasto dei dati e che mi fornisce, ovviamente, delle risposte), e io da quel punto in poi devo poter utilizzare il jar indicatomi. Nel mio programma sono già presenti le classi che gestiscono le classi del jar: in sostanza, per ogni jar che l'utente può caricarmi, ho una classe GestoreJarX che sa come utilizzare il jar; sono presenti quindi tanti piccoli plugin implemenati dalle classi GestoreJarX che possono essere utilizzati una volta indicato il jar da utilizzare per il plugin specifico (io ovviamente in fase di compilazione ho tutti i jar impostati nelle variabili d'ambiente di NetBeans, quindi non ho problemi di sorta). Una volta che l'utente mi indica il percorso dove trovare il jar, me lo salvo in un file di configurazione e al successivo riavvio dell'applicazione uso sempre lo stesso percorso. L'utente può cambiare anche il percorso di un jar per uno dei plugin, e io devo adattarmi al cambiamento. Che cosa intendi per "spezzare il programma in due"? Perchè così è, volendo, già spezzettato: c'è il programma principale con le sue funzionalità, il gestore di tutti i plugin GestorePlugin che si integra nel programma principale, e i vari plugin GestoreJarX che si "registrano" presso il GestorePlugin. Io posso intervenire da GestorePlugin in giù, perchè mi occupo solo di questo. Grazie ![]() Ultima modifica di Dav82 : 19-11-2004 alle ore 17.20.24 |
![]() |
![]() |
![]() |
#4 |
Gold Member
Top Poster
Registrato: 18-07-2002
Messaggi: 6.399
![]() |
Adesso funziona
![]() ![]() ![]() Giuro, non ho cambiato niente ![]() La cosa bella è invece che ho un attributo privato di una classe che viene posto uguale a un certo valore nel costruttore, nella classe non ci sono altre istruzioni che toccano sto attributo privato, eppure a un certo punto me lo ritrovo cambiato! Beh... tolto assegnamento nel costruttore, messo nella dichiarazione dell'attributo e aggiunto un bel final all'attributo stesso e adesso non cambia più... Sembra... sembra funzionare! Adesso provo a farlo girare un po' (leggasi: testing alla carlona ![]() ![]() Web, tieniti pronto che fra un po' sicuramente mi crasha tutto e sono ancora qui! ![]() |
![]() |
![]() |
![]() |
#5 |
Gold Member
Top Poster
Registrato: 18-07-2002
Messaggi: 6.399
![]() |
No scherzavo, non funziona. C'era una bella cartella scompattata in un percorso che avevo nel classpath
![]() Cmq, nel mio jar c'è sta roba: Codice:
mioJar.jar | |---- pack1 | |----sottopack1 | |---- customException.class java.lang.NoClassDefFoundError: pack1/sottopack1/customException Però l'operazione di loading della classe customException con mioCL.loadClass("pack1.sottopack1.customException" ) va a buon fine, non mi solleva eccezioni: quindi il mioCL riesce a "vedere" che la classe esiste... |
![]() |
![]() |
![]() |
#6 |
Gold Member
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
![]() |
Ok bene,
se ho capito bene, l'utente sceglie il jar da utilizzare e tu scrivi la preferenza in un file di configurazione che poi vai ad utilizzare nelle successive sessioni... Volendo essere sbrigativi e un po' grezzi, potrei suggerirti due metodi: 1 - "spezzi" il programma, ovvero, la parte in cui l'utente decide il jar da utilizzare termina la sua esecuzione una volta che è stata effettuata la scelta eseguendo due operazioni: scrivendo il file di configurazione (come già fa) e creando uno startup (ad esempio un .bat) ad hoc per lanciare l'altra parte del programma con il classpath corretto, infine si preoccupa di lanciare il bat appena creato dando all'utente la sensazione di "continuità" del programma, mentre in realtà il vero e proprio applicativo parte ora... 2 - Dopo la selezione dell'utente prelevi il jar dal path che ti ha indicato e lo estrai in una tua cartella temporanea settata in maniera statica nel tuo classpath oppure caricando le classi dinamicamente come hai già fatto nel tuo esempio; questo ti permette di usare un percorso fisso e di non dover utilizzare il jar ma solo i .class così estratti. Quando l'utente cambia la preferenza, tu svuoti la cartella temporanea per poterci estrarre dentro un altro jar... Tutto questo, posto per assodato che io abbia afferrato il tuo ragionamento ![]() Per altre soluzioni più "professionali" ti rimando a domani, dopo una sana dormita... ![]() Bye ![]() |
![]() |
![]() |
![]() |
#7 |
Gold Member
Top Poster
Registrato: 18-07-2002
Messaggi: 6.399
![]() |
Grazie Web (Y)
Devo pensar bene come applicare le due soluzioni... la prima è forse più problematica... la seconda è forse più semplice.... ma è tardi, una bella dormita fa sicuramente bene anche a me ![]() Così riesco anche a spiegarti meglio sta architettura del cavolo! ![]() |
![]() |
![]() |
![]() |
#8 |
Gold Member
Top Poster
Registrato: 18-07-2002
Messaggi: 6.399
![]() |
Mo ti spiego!
Facciamo conto che l'applicazione più grande abbia a disposizione un testo scritto in italiano. Io mi occupo dello strumento "Traduzione", che consta di molti plugin: traduzione in inglese, tedesco, francese, spagnolo, latino ecc ecc. Io ho una classe per ogni traduttore, e ognuna di queste classi sa come utilizzare un determinato jar (di terze parti) per ottenere la traduzione di un testo nella lingua supportata dal jar. L'applicazione viene però distribuita senza i jar, è l'utente che si deve preoccupare di reperirli e indicare al mio strumento "Traduzione" dove beccare i jar corretti. Mettiamo che l'utente abbia indicato allo strumento dove trovare i jar per Inglese, Tedesco e Francese. In fase di esecuzione, può chiedere la traduzione anche solamente con Tedesco e Francese: tutti i plugin di cui è stato indicato il jar devono però essere attivi per poter essere richiamati. Quindi potrei fare così: siccome so, in fase di startup, quanti plugin al massimo sono supportati, posso riservarmi di impostare un classpath così: SET CLASSPATH = %CLASSPATH%; C:\MioProg\Traduzione\plug1.jar; C:\MioProg\Traduzione\plug3.jar; C:\MioProg\Traduzione\plug2.jar; C:\MioProg\Traduzione\plug4.jar;Ecc.Ecc; e per ogni jar che l'utente mi indica io piglio il jar e lo copio rinominato come plugX.jar e a sto punto lo posso usare. E' un po' dispendioso perchè devo copiarmi un bel po' di file, e poi il bello è che alcuni plugin sono composti da più jar... e non saprei come fare ![]() Posso anche seguire un'altra strategia: nel classpath, al posto di riservarmi i jar, mi riservo delle cartelle, una per ogni plugin, in cui copiare e scompattare i jar e da lì usarli, come mi hai detto tu... devo vedere se è una cosa fattibile come dimensioni in MB: tutto il programma occupa 3MB di Jar, e rischio con questa tecnica di usare qualche decina di MB per i Jar dei plugin scompattati... edit: ho appena provato con uno dei plugin che consta di 19 jar ( ![]() riedit: non ho dormito abbastanza! ![]() ![]() Dai, adesso (dopo pranzo) provo a vedere quanto tempo ci mette su un pc dalle prestazioni decenti e non come il mio portatile, e vediamo se sono accettabili ![]() Ultima modifica di Dav82 : 20-11-2004 alle ore 13.07.23 |
![]() |
![]() |
![]() |
#9 | |
Gold Member
Top Poster
Registrato: 18-07-2002
Messaggi: 6.399
![]() |
Quota:
![]() Ci sono due plugin diversi che hanno un jar chiamato con lo stesso nome ![]() Ok, faccio così: creo tante cartelle C:\MioProg\Traduzione\PluginX, in ognuna ci copio tutti i jar di un plugin e inserisco nel classpath tanti C:\MioProg\Traduzione\PluginX\JarPadrePluginX.jar E che cavolo!!! |
|
![]() |
![]() |
![]() |
#10 |
Gold Member
Top Poster
Registrato: 18-07-2002
Messaggi: 6.399
![]() |
Webbbbbbbbbbbbb, mi ero scordato che ho risolto!
![]() Siccome con i classloader non sono riuscito a cavarci niente, ho usato la reflection e via ![]() Grassie mille (Y) ![]() |
![]() |
![]() |
![]() |
Utenti attualmente attivi che stanno leggendo questa discussione: 1 (0 utenti e 1 ospiti) | |
Strumenti discussione | |
|
|
![]() |
||||
Discussione | Autore discussione | Forum | Risposte | Ultimo messaggio |
posso usare un disco di ripristino di un parkard bell su un altro parkard bell? | ilveroenk1 | Windows 7/Vista/XP/ 2003 | 6 | 07-12-2007 12.33.58 |
posso usare un disco di ripristino di un parkard bell su un altro parkard bell? | ilveroenk1 | Linux e altri Sistemi Operativi | 1 | 07-12-2007 10.17.58 |
posso usare un disco di ripristino di un parkard bell su un altro parkard bell? | ilveroenk1 | Software applicativo | 1 | 07-12-2007 10.17.46 |
usare solo il browser | backgroundit | Windows 7/Vista/XP/ 2003 | 10 | 10-09-2007 12.02.04 |
Dubbio su quale cd usare per ripristino sistema: cd drivers o i cd di ripristino?? | Fabius250485 | Windows 7/Vista/XP/ 2003 | 2 | 31-05-2006 12.23.11 |