Prima di tutto, questo è Java 1.4 (limitazioni del progetto). Sto provando a creare un gestore applicazioni. Carica la classe principale di ogni applicazione utilizzando la propria istanza di un classloader personalizzato. Successivamente, crea un'istanza della classe principale utilizzando la riflessione. Ogni applicazione implementa un'interfaccia comune, quindi dopo aver creato l'istanza, esegue un metodo predefinito dell'applicazione.ClassCastException durante la creazione di un'istanza di una classe utilizzando reflection e ClassLoaders
Tuttavia, sto riscontrando dei problemi in CRASH POINT 1 (vedere codice). La classe non è riconosciuta come un'implementazione della sua interfaccia. Se inserisco questo chunk di codice, ottengo ClassCastException in CRASH POINT 2.
Suppongo che entrambi gli errori siano correlati allo stesso problema (ovviamente).
Qualcuno può aiutarmi? Segue la parte pertinente del codice (le importazioni vengono rimosse) ...
Grazie mille.
Marcus
// AppManager.java
public class AppManager {
public ThreadGroup threadGroup;
private Class appClass;
private AppInstance appInst;
public AppContextImpl context;
private AppManager(CustomClassLoader cl, String mainClass) throws ClassNotFoundException {
final String className = mainClass;
final CustomClassLoader finalLoader = cl;
appClass = cl.loadClass(mainClass);
// DEBUG CODE:
Class[] k1 = AppInstance.class.getInterfaces();
System.out.println(k1.length + " interfaces for AppInstance.class:");
for (int ii = 0; ii < k1.length; ii++) {
System.out.println(" " + ii + " - " + k1[ii].getName() + " (" + k1[ii].getClassLoader() + ")");
}
Class[] k2 = appClass.getInterfaces();
System.out.println(k2.length + " interfaces for appClass instance:");
for (int ii = 0; ii < k2.length; ii++) {
System.out.println(" " + ii + " - " + k2[ii].getName() + " (" + k2[ii].getClassLoader() + ")");
}
// CRASH POINT 1
if (!(AppInstance.class.isAssignableFrom(appClass))) {
throw new IllegalArgumentException("Attempt to run a non-AppInstance class: " + appClass);
}
context = new AppContextImpl(mainClass, this);
cl.setAppManager(this);
Constructor m;
try {
m = appClass.getConstructor(new Class[0]);
// CRASH POINT 2
appInst = (AppInstance) m.newInstance(new Object[0]);
appInst.init(context);
} catch (Exception e) {
System.out.println("Got ClassCastException here!\n");
e.printStackTrace();
}
}
public static void main(String[] args) {
App app1;
String path1 = "/home/user/workspace/MultiTaskTest/bin/";
String app1Name = "App1";
Vector v1 = new Vector();
try {
v1.add(new URL(path1));
} catch (MalformedURLException e1) {
final File file1 = new File(path1);
try {
URL path1aux = (URL) AccessController.doPrivileged(
new PrivilegedExceptionAction() {
public Object run() throws IOException {
if (!file1.exists()) {
System.out.println("Warning: \"" + file1.getPath() + "\" not found");
return null;
}
return file1.toURI().toURL();
}
});
if (path1aux != null) {
v1.add(path1aux);
}
} catch (PrivilegedActionException e) {
e.getException().printStackTrace();
}
}
final URL[] array1 = (URL[]) v1.toArray(new URL[v1.size()]);
CustomClassLoader cl1 = (CustomClassLoader) AccessController.doPrivileged(
new PrivilegedAction() { public Object run() {
return new CustomClassLoader(array1);
}});
System.out.println("ClassLoader 1 created: " + cl1);
try {
app1 = new App(cl1, app1Name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("Cannot find class App1.");
}
}
}
// AppInstance.java
public interface AppInstance {
public void init(ContextImpl context);
}
// App1.java
public class App1 implements AppInstance {
private AppContextImpl contextObj;
public void init(AppContextImpl context) {
this.contextObj = context;
System.out.println("Running App1...");
}
}
// AppContextImpl.java
public class AppContextImpl {
public String mainClass;
public AppManager app;
public AppContextImpl(String mainClass, AppManager app) {
this.mainClass = mainClass;
this.app = app;
}
}
// CustomClassLoader.java
public class CustomClassLoader extends URLClassLoader {
AppManager appInst;
public CustomClassLoader(URL[] paths) { super(paths, null); }
public void setAppManager(AppManager app) { this.appInst = app; }
}
L'uscita per il codice di debug nel file AppManager.java è:
0 interfaces for AppInstance.class:
1 interfaces for appClass instance:
0 - AppInstance ([email protected])
sembra che sia un problema di class loader. È necessario assicurarsi che la classe che si carica e l'interfaccia di AppInstance stessa siano stati caricati con lo stesso programma di caricamento classe, altrimenti Java li considera totalmente indipendenti. –
Che cosa è l'output di Class.getGenericInterfaces() e Class.getInterfaces()? – TheLQ
Lord.Quackstar: Controlla di nuovo la domanda.Ho inserito alcuni commenti per fornire le informazioni richieste. – Marcus