hvis din applikation er en helt normal applikation så vil forskellen på min og java.class.path propertyen kun være at min har Java RT med (hvilket jo næppe er interessant)
men hvis din klasse er loadet af en speciel classloader så kan forskellen være endda meget stor, fordi min tager de classloadere som faktisk bruges mens propertyen kun angiver status ved start af java kommandoen
Tak for de hurtige inputs! Jeg har brugt Arnes metode of får det ønskede. Egentlig en stump kode, der er rar at have i sin eget utility-pakke :-) Smid gerne et svar.
->arne_v: Jeg bevæger mig måske ud på lidt tynd is her, men jeg prøver alligevel..
Lad os sige, at jeg ønsker at loade en ny klasse, som er placeret i "mitdirectory".Hertil bruger jeg en classloader: ClassLoader cl=new URLClassLoader(new URL[]{(new File("mitdirectory")).toURL()}); Class c=cl.loadClass("klasse");
Antag videre at der i den klasse, der skal load'es er referencer til klasser, som IKKE er indeholdt i classpath'en for den kørende Java-session (og antag at disse klasser findes i classpath_extra). I så fald vil klassen ikke load'e men kaste en ClassNotFoundException.
Hvordan får jeg i den situation alligevel load'et klassen, hvis ikke classpath'en for den kørende Java-session indeholder classpath_extra? Med andre ord: Hvordan får jeg føjet classpath_extra til på run-time?
Den load'ede klasse "klasse" implementerer interface't Interface1. Så langt så godt.
Jeg prøver nu at erstatte Class.forName() med en specifik classloader: o1=(new URLClassLoader(new URL[]{(new File("c:/...")).toURL().loadClass("klasse").newInstance(); Object o2=(Interface1)o1;
Nu får jeg en ClassCastException i linie 2, mens linie 1 ikke fejler.
->arne_v: Jeg har sågar forsøgt lidt debug mellem linie 1 og 2: Class[] cl=o.getClass().getInterfaces(); for (int i=0;i<cl.length;i++) { System.out.println("Interface: "+cl[i].getName()); } - og output er: Interface1
->arne_v: Ja, problemet er ganske rigtigt, at samme interface loades af to forskellige classloader'e. Jeg har nu noget at arbejde videre med. Tak for din hjælp i denne sene time!
->arne_v: Problemet her er vist, at jeg arbejder i et "lokalt" miljø (inde i NetBeans), hvor alle klasser er load'et af en custom NetBeans classloader. Når jeg så kommer med min egen URLClassLoader går det galt, idet min URLClassLoader (og dens parents) ikke omfatter NetBeans-classloader'en. Med andre ord vil jeg reload'e interface't, idet min classloader ikke kan se, at dette allerede er load'et. Hvis jeg skal have det til at virke, skal jeg nok føje NetBeans-classloader'en til min egen URLClassLoader.
Givet at jeg står for at skulle definere min URLClassLoader med efterfølgende kald til Class.forName(), skal jeg vel blot føje this.getClass().getClassLoader() til min URLClassLoader. Det kan man vel godt, tænker jeg.
->arne_v: Jo, det gør den, men jeg opererer i NetBeans IDE-JVM'en.
NetBeans er udover at være en IDE også en udviklingsplatform, som er modulært opbygget. Man kan selv skrive moduler, som tilføjer funktionalitet til platformen (måske ved du alt dette i forvejen), og det er i sådant et modul jeg arbejder, idet jeg har en eksisterende applikation, som jeg ønsker at bygge ind i NetBeans.
Tingene kompliceres af, at jeg bruger en del dynamisk kompilering/class-loading (ud fra et input fra brugeren, som modtages og "parses" gennem editoren), så jeg er lidt i tvivl om, jeg skal integrere hele applikationen i et NetBeans-modul (som dermed kører i samme JVM som NetBeans) - eller om jeg skal starte en ny JVM (som NetBeans gør, når et program afvikles på normal vis).
Integration som modul i samme JVM letter kommunikationen applikationen og NetBeans men der kræves nogen "housekeeping" for alligevel at holde tingene adskilt, bla. skal applikationen operere med egne classloadere, men det har jeg nu efterhånden fået til at virke bla. med hjælp fra din hånd :-)
Med en løsning med to JVM'er, er det nemmere at holde tingene adskilt (specielt omkring classloading), men omvendt er kommunikationen mellem JVM'erne så en anden udfordring. Her skal jeg måske overveje at bruge RMI som "grænseflade" mellem de to JVM'er i fald jeg vælger denne løsning.
Dette var super-nemt, idet URLClassLoader har en constructor, der præcis kan tilføje en anden classloader: URLClassLoader(URL[] urls, ClassLoader parent),
- hvor ClassLoader parent blot her er: this.getClass().getClassLoader()
På denne måde sikres forbindelsen mellem de allerede load'ede klasser og de klasser, der load'es dynamisk. URLClassLoader'en er blot en udvidelse af classloader'en for den aktuelle klasse (this.getClass()). Egentlig helt oplagt, når man ved det :-)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.