Domanda

Prima di tutto, questo è Java 1.4 (restrizioni di progetto). Sto cercando di creare un gestore applicazione. Si carica classe principale di ogni applicazione che utilizza il proprio istanza di un classloader personalizzato. Dopo di che, si crea un'istanza della classe principale utilizzando la riflessione. Ogni implementa applicazioni un'interfaccia comune così dopo viene creata l'istanza, viene eseguito un metodo predefinito dell'applicazione.

Comunque, sto avendo qualche problema a Punto di collisione (codice vedi) 1. La classe non è riconosciuta come un'implementazione di essa dell'interfaccia. Se io coment questo codice pezzo, ho ClassCastException a CRASH PUNTO 2.

suppongo sia gli errori sono legati alla stessa questione (ovviamente).

chiunque aiutare

Can me? La parte rilevante del codice segue (le importazioni sono rimossi) ...

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'output per il codice di debug nel file AppManager.java è:

0 interfaces for AppInstance.class:
1 interfaces for appClass instance:
   0 - AppInstance (CustomClassLoader@480457)
È stato utile?

Soluzione

La classe AppInstance probabilmente è caricata separatamente da ciascun classloader personalizzato. Dal momento che oggetti di classe dipendono dalla classe reale e sul programma di caricamento classe, sono le classi in realtà diverse. Così AppInstance dal classloader 1 non è lo stesso di AppInstance dal classloader 2.

Quello che dovete fare è utilizzare la gerarchia dei classloader di serie: utilizzare un classloader principale per l'applicazione, e assicurarsi maschile che AppInstance è caricabile dal classloader. Poi fare la vostra abitudine di caricamento classe i bambini dalla radice. Ogni volta che hanno bisogno di accedere alla classe AppInstance, useranno ciò che viene caricato dalla radice.

Così, invece di questo:

public CustomClassLoader(URL[] paths) { super(paths, null); }

È necessario dare un genitore al tuo CustomClassLoader

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top