2014-04-14 19 views
6

Jeśli mam zmienną statyczną, która ma przypisaną wartość z klasy, która używa wzorca singleton, czy to w jakiś sposób wymaga, aby wszystkie klasy, które mogą potencjalnie przydzielić wartość do tej zmiennej statycznej do załadowania?Kiedy dokładnie jest załadowana klasa?

Pracuję z kodem, który wygląda mniej więcej tak (uproszczony, aby chronić dane firmowe):

private static DEVICE_FACTORY; 

String factoryType = propertyFile.getDeviceFactoryType(); 

if(factoryType.equals("REAL")) 
    DEVICE_FACTORY = RealDeviceFactory.getInstance(); 
else 
    DEVICE_FACTORY = SimulatedDeviceFactory.getInstance(); 

kod dla każdego rodzaju zakładu jest w zupełnie różnych projektów. Wersja produkcyjna słoika aplikacji nie zawiera żadnej z symulowanych klas. Mój problem polega na tym, że kiedy próbuję przetestować mój kod produkcyjny, otrzymuję "NoClassDefFoundError" spowodowany przez "ClassNotFoundException". Potwierdziłem, że właściwość jest poprawnie ustawiona na "REAL", więc nie mam pojęcia, dlaczego JVM próbuje utworzyć/załadować symulowane klasy ...

EDIT Spróbuję stworzyć uproszczoną wersję, która demonstruje problem jutro. Ślad stosu (edytowane do chronionych danych firmowych) przedstawia się następująco:

java.lang.NoClassDefFoundError: my/package/SimulatedDeviceFactory 
       at java.lang.Class.getDeclaredMethods0(Native Method) 
       at java.lang.Class.privateGetDeclaredMethods(Unknown Source) 
       at java.lang.Class.getMethod0(Unknown Source) 
       at java.lang.Class.getMethod(Unknown Source) 
       at sun.launcher.LauncherHelper.getMainMethod(Unknown Source) 
       at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source) 
Caused by: java.lang.ClassNotFoundException: my.package.SimulatedDeviceFactory 
       at java.net.URLClassLoader$1.run(Unknown Source) 
       at java.net.URLClassLoader$1.run(Unknown Source) 
       at java.security.AccessController.doPrivileged(Native Method) 
       at java.net.URLClassLoader.findClass(Unknown Source) 
       at java.lang.ClassLoader.loadClass(Unknown Source) 
       at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) 
       at java.lang.ClassLoader.loadClass(Unknown Source) 

Czy to możliwe, że używam wzorzec Singleton na każdego rodzaju fabryki urządzeń zatem, choć nie będę używać SimulatedDeviceFactory, ponieważ używam statycznego wywołania metody z tej klasy JVM myśli, że musi to załadować mimo to?

Jeśli jest to sprawa mogłaby używać refleksji i FQCN rozwiązać to dość szybko ...

+3

Czy możesz ograniczyć to do przykładu, który odtwarza problem? Szczegóły naprawdę mają znaczenie w przypadku takim jak ten, a twój kod jest niepoprawny (nie możesz mieć zmiennych, jeśli w definicji klasy) –

+1

Czy wyjątek zostanie zgłoszony w gałęzi 'else'? – MxyL

+0

Pamiętasz, aby umieścić pliki jar dla innych projektów w swojej ścieżce klasowej, ** w prawo **? – Powerlord

Odpowiedz

0

Tak działa Java. SimulatedDeviceFactory jest ładowany podczas ładowania głównej klasy.

Powinieneś użyć refleksji w tej sytuacji. Jest to dobry i dość popularny tupot. Łatwy w konfiguracji i łatwy do debugowania.

Unikaj stosowania innych obejść. Debugowanie problemów związanych z modułem ładującym klasy w serwerach aplikacji JEE jest naprawdę bolesne w **.