|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
[JAVA] Caricare dinamicamente un jar
Salve a tutti! Devo realizzare un sistema a "plugin". Finora ho sviluppato tutto in un'unica applicazione, separando in package differenti le classi che andranno a costituire il mio plugin.
Quindi nel flusso della mia applicazione principale ad un certo punto ho un a cosa del genere: Codice:
InputPlugin ip = new NomePlugin(parameters); InputPlugin è un'interfaccia NomePlugin è il nome della classe che implementa quell'interfaccia parameters è un'istanza di tipo Map<String, String> Ora mi trovo a dover staccare questi plugin e metterli ognuno in differenti jar. Ed in effetti ho fatto così. A questo punto nella mia applicazione principale non potrò più avere un'istruzione come quella riportata precedentemente, ma il caricamento dovrà essere dinamico in base al nome del plugin che intendo caricare. Ho fatto come segue (ho trovato il codice in rete): Codice:
String inputPluginJarPath = "jar:file://" + inputPluginPath + "!/";
ClassLoader inputPluginLoader = URLClassLoader.newInstance(new URL[] { new URL(inputPluginJarPath) });
Class<?> myclassloader = inputPluginLoader.loadClass(inputPluginName);
InputPlugin inputPlugin = (InputPlugin) myclassloader.newInstance();
Ho creato anche un costruttore vuoto e senza parametri nella classe che dovrei caricare, ma senza risolvere nulla... In sostanza, come posso avere nella variabile inputPlugin un'istanza della classe di cui conosco il nome (e il relativo nome del jar che la contiene)? Grazie. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Padova
Messaggi: 2342
|
Per un progetto universitario ho fatto una cosa molto simile (anzi praticamente uguale...).
Ho fatto una cosa del genere (le strane chiamate toURI toURL dipendono dal contesto in cui è sviluppato il codice, con librerie sviluppate internamente): Codice:
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{engineJarFile.toURI().toURL()}, this.getClass().getClassLoader()); //rispetto al tuo codice cambia che ho specificato il classloader
Class<?> engineToLoad = Class.forName(engine.getEngineClassPath(), false, classLoader); //ottengo la classe che mi interessa con il metodo forName
Constructor<?> constructor = engineContainer.getEngineClass().getConstructor(new Class[]{}); //ottengo il costruttore standard (senza parametri) della classe
IFace oggetto = (IFace) constructor.newInstance(new Object[]{}); //istanzio la classe usando il costruttore standard (senza parametri)
Vedi se riesci a cavarne fuori qualcosa, buona fortuna
__________________
CPU Ryzen 2600 @ 3,95Ghz + Bequiet Dark Rock TF / MB Asus X470-F Gaming / RAM 2x8GB DDR4 G.Skill FlareX 3200 CL14 / VGA Sapphire RX 7900 XT Nitro+ @ 3200Mhz / SSD Samsung 970 Pro 512GB + Sandisk 240GB Plus + Sandisk 960GB Ultra II PSU Seasonic Platinum P-660 / Headset Kingston HyperX Flight Ultima modifica di demos88 : 27-09-2012 alle 19:29. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
RISOLTO
Mi è bastato cambiare le seguenti righe... Da come mi sembra di capire il problema è la stringa del path del jar. Codice:
String inputPluginClassName = inputPluginPackage+"."+pluginName+"InputPlugin";
File inputPluginJarFile = new File(inputPluginPath);
ClassLoader classLoader = URLClassLoader.newInstance(new URL[] { inputPluginJarFile.toURI().toURL() });
inputPlugin = (InputPlugin) classLoader.loadClass(inputPluginClassName).newInstance();
inputPlugin.initialize(parameters);
|
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Jul 2012
Messaggi: 91
|
Immagino che tu abbia cambiato anche il costruttore della tua classe plugin, inserendo un costruttore di default.
Il metodo Class.newInstance() funziona solo se la classe ha un costruttore di default, altrimenti lancia un InstantiationException. Per istanziare tramite reflection una classe con un costruttore che prende degli argomenti devi prima ottenere il costruttore giusto tramite Class.getConstructor(...) e su questo puoi eseguire Constructor.newInstance(...) passando un'array di oggetti che rappresentano gli argomenti del costruttore. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 18:04.



















