konto usunięte

Temat: Zmiana defaultowego ClassLoadera

Czy nie wiecie może w jaki sposób zadeklarować mój własny ClassLoader, tak aby był odpytywany w pierwszej kolejności ? Tzn aby spełniał rolę podstawowego ClassLoadera zamiast np. AppClassLoadera?

konto usunięte

Temat: Zmiana defaultowego ClassLoadera

Nie ma takiej możliwości, własne ClassLoader'y odpytywane są dopiero w przypadku kiedy ClassLoader rodzic nic nie znajdzie i tej kolejności nie da się zmenić.
zobacz tu
Paweł Grzegorz Kwiatkowski

Paweł Grzegorz Kwiatkowski Architekt
oprogramowania,
Ericsson

Temat: Zmiana defaultowego ClassLoadera

Kamil Hark:
Nie ma takiej możliwości, własne ClassLoader'y odpytywane są dopiero w przypadku kiedy ClassLoader rodzic nic nie znajdzie i tej kolejności nie da się zmenić.
zobacz tu

Coś takiego da się zrobić ;-) Trzeba zrobić własny Bootstrap class loader. Chyba, że mamy na myśli coś innego...

Później uruchomienie wygląda mniej więcej tak:
java MojBootstrap jakas.klasa.Foo argumenty...

MojBootstrap tworzy ClassLoader, laduje przez ten ClassLoader klasy potrzebne do dzialania Foo() i wywoluje metode main na Foo z listą przekazanych argumentów (przesuniętą o 1 pozycję, jako że pierwszy argument to nazwa klasy do załadowania).

konto usunięte

Temat: Zmiana defaultowego ClassLoadera

Paweł Grzegorz Kwiatkowski:
Kamil Hark:
Nie ma takiej możliwości, własne ClassLoader'y odpytywane są dopiero w przypadku kiedy ClassLoader rodzic nic nie znajdzie i tej kolejności nie da się zmenić.
zobacz tu

Coś takiego da się zrobić ;-) Trzeba zrobić własny Bootstrap class loader. Chyba, że mamy na myśli coś innego...

Później uruchomienie wygląda mniej więcej tak:
java MojBootstrap jakas.klasa.Foo argumenty...

MojBootstrap tworzy ClassLoader, laduje przez ten ClassLoader klasy potrzebne do dzialania Foo() i wywoluje metode main na Foo z listą przekazanych argumentów (przesuniętą o 1 pozycję, jako że pierwszy argument to nazwa klasy do załadowania).


Niestety, pomysł dobry ale nie mogę go zastosować ponieważ to się musi odbywać w runtime. :(

konto usunięte

Temat: Zmiana defaultowego ClassLoadera

Generalnie chodzi o to by stworzyć nowy classLoader i wrzucić do niego część aplikacji - tak by miała oddzielną przestrzeń nazw.

konto usunięte

Temat: Zmiana defaultowego ClassLoadera

Ok, w sumie mam to co chciałem. Mam własnego classLoadera, jestem w stanie wciągać nim klasę. Problem polega jednak na tym, że aby stworzyć instancję tej klasy w ClassLoaderze nadrzędnym do mojego muszę wyciągać go tak:

String jarFile = "/home/andrzej/NetBeansProjects/cl/dist/cl.jar";
ExternalClassLoader classLoader = new ExternalClassLoader(jarFile);
Object klasa = classLoader.findClass("pl.cl.KeepGoing");

problem z tym jest taki, że mogę uzyskać Object. Chciałbym teraz aby JVM jeśli nie znajdzie klasy A załadowanej moim classloaderem w nadrzędnym classloaderze (w tym przypadku systemowym), powinien zacząć szukać w obszarze mojego ClassLoadera. Czy muszę jakoś zarejestrować mój ClassLoader, oraz jak mogę sprawić by nie szukał po wszystkim podrzędnych classloaderach ale w tym właściwym? Chodzi mi o to bym nie mając klasy pl.cl.KeepGoing w głównym ClassLoaderze mógł po stworzeniu mojego classloadera tworzyć obiekt na zasadzie
KeepGoing kg = new KeepGoing() a nie jakimiś dziwnymi obejściami.Andrzej K. edytował(a) ten post dnia 18.02.09 o godzinie 17:21

konto usunięte

Temat: Zmiana defaultowego ClassLoadera

Mam nadzieję, że rozwiązanie, które znalazłem dla siebie również Tobie się sprawdzi. Siedziałem dzisiaj nad tym jakieś 2 godziny, a rozwiązanie okazało się proste.

Otóż mój problem polegał na tym, aby serwer przesyłał do aplikacji klientckich klasy implementujące pewien interfejs - w ten sposób dynamicznie można poszerzać funkcjonalność. Ok, więc przesyłałem je w postaci jarów przez sieć i zapisywałem w nadrzędnym folderze temporaryLibs/.

Pobrałem ścieżkę folderu bierzącego i dokleiłem do niego "\\temporaryLibs"
String desiredDir = System.getProperty("user.dir") + "\\temporaryLibs";

Następnie ( i tutaj już dla uproszczę wprowadzając nazwy Test1, Test2, Test3 etc) utworzyłem obiekt URL do pliku Test2.jar zgodnie ze specyfikacją protokołu (więcej na http://docs.sun.com/source/819-0913/author/jar.html)

URL jarFile = new URL("jar","","file:" + dir + "\\Test2.jar" + "!/");

Ładuję klasy korzystając z utworzonego obiektu URL:
URLClassLoader cl = URLClassLoader.newInstance(new URL[] {jarFile });

Tworzę instancję klasy taskX :-)

Class c = cl.loadClass("taskX");

i wiem, że jest kompatybilna z interfejsem Iabc, więc mogę:

Iabc newIabc = (Iabc)c.newInstance();

wywołuję pożądaną metodę interfejsu:

double[] tab = newIabc.returnSth();

I wszystko byłoby pięknie, jednak okazuje się, że jeżeli Test1 powiązany jest w jakikolwiek sposób z klasami z Test3, wtedy wczytanie klasy Test1 powyższą metodą nie kończy się pomyślnie. Na szczęście wpadłem na coś :-) Wystarczy, że metodzie URLClassLoader podamy jako parametr listę wszystkich jarów, jakie mogą być powiązane z tym, który poprawnie trzeba załadować. Dla uproszczenia zakładam, że Test1 ma odwołania do Test2 i oba są w nadrzędnym katalogu, który wcześniej został określony jako dir:

Tworzę obiekty URL dla obu plików:
URL jarFile1 = new URL("jar","","file:" + dir + "\\Test1.jar" + "!/");
URL jarFile2 = new URL("jar","","file:" + dir + "\\Test3.jar" + "!/");

I teraz ważne, aby podać listę URLi, inaczej nie zadziała:
URLClassLoader ucl = URLClassLoader.newInstance(new URL[] {jarFile1,jarFile2});

Tworzę instancję:
Class c = ucl.loadClass("taskXXX");

Wszystko powinno działać bez zarzutów.

Pozdrawiam :-)Dżafar - Sadik Ridha edytował(a) ten post dnia 04.03.09 o godzinie 23:21

Następna dyskusja:

Zmiana czasu




Wyślij zaproszenie do