2013-11-01 17 views
7

Zaktualizowałem nasze projekty (Java EE bazuje na Websphere 8.5), aby użyć nowej wersji wewnętrznego systemu firmy (i deskryptorów wdrażania Ejb 3.x, a nie 2). x ones). Od tego czasu moje testy integracji kończą się niepowodzeniem z następującym wyjątkiem:Ustaw klasę inicjalizacji fabryki kontekstu JAXB, która ma być używana

[java.lang.ClassNotFoundException: com.ibm.xml.xlxp2.jaxb.JAXBContextFactory] 

Mogę zbudować aplikację z poprzedniej wersji ramowej i wszystko działa poprawnie. Podczas debugowania zauważyłem, że w ContextFinder (javax.xml.bind) istnieją dwa różne zachowania:

  1. Poprzednia wersja (wszystko działa dobrze): Żaden z różnych miejsc wywołuje klasę fabryki więc domyślna klasa fabryczna jest ładowana, co jest com.sun.xml.internal.bind.v2.ContextFactory (zdefiniowane jako stała String w klasie).

  2. ulepszona wersja (ClassNotFound): Jest to zasób "META-INF/services/javax.xml.bind.JAXBContext" beeing załadowany pomyślnie i pierwsza linia odczytu sprawia próbę ContextFinder aby załadować „com.ibm.xml .xlxp2.jaxb.JAXBContextFactory ", który powoduje błąd.

teraz mam dwa pytania:

  1. Jaki jest, że zasób? Ponieważ wewnątrz naszego pliku EAR znajdują się dwa WAR i żaden z tych dwóch nie zawiera usług folderów w katalogu META-INF .

  2. Gdzie ta wartość może być z innego powodu? Ponieważ filediff nie pokazał mi żadnych nowych lub zmienionych plików właściwości.

Nie trzeba powiedzieć, mam zamiar przeczytać o możliwościach konfiguracyjnych JAXB ale jeśli masz pierwsze spostrzeżenia na temat tego, co mogło pójść źle albo mi pomóc z tego zasobu (jest to prawdziwy plik muszę poszukać?) id docenić wiele. Wielkie dzięki!

EDIT (zgodnie z uwagami wejściowe/pytania):

Z ciekawości, czy Twój ramy obejmują JAXB JAR? Czy stara wersja twojego frameworka zawierała jaxb.properties?

Rzeczywiście (jestem trochę zaskoczony) ramy ma dostosowaną EclipseLink-2.4.1-.jar wewnątrz ucha, która obejmuje zarówno realizację JAXB i plik jaxb.properties który pokazuje następujący wpis w obu wersje (ten, który znajdzie fabryki, jak również tego, który zgłasza wyjątek):

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

myślę, że to nie ma nic wspólnego z aktualnego wydania od słoik przebywał dokładnie taka sama w obu uszach (ten, który działa/ten z oczekiwaniem)

Nie jest również dla mnie jasne, dlaczego starsza wersja frameworka kiedykolwiek wybierała com.Słońce realizacja

Istnieje klasa javax.xml.bind.ContextFinder który jest odpowiedzialny za inicjowanie JAXBContextFactory. Ta klasa przeszukuje różne miejsca docelowe pod kątem istnienia pliku jaxb.properties lub "javax.xml.bind.JAXBContext". Jeśli wszystkie z tych miejsc Nie pokazuj się jakim kontekście Fabryka w użyciu znajduje się fabryka deault ładowane który jest ustalony w klasie sama:

private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory"; 

Wracając do mojego problemu:

Budynek z poprzedniego wersja środowiska (i deskryptory wdrażania EJB 2.x) wszystko działa poprawnie). Podczas debugowania widzę, że nie znaleziono żadnej konfiguracji, a co za tym idzie, załadowana jest wyżej wspomniana fabryka.

Budowanie za pomocą nowej wersji frameworka (i deskryptorów wdrażania EJB 3.x, więc mogę wdrożyć) TYLKO TESTCASE kończy się niepowodzeniem, ale reszta funkcji działa (tak, jak mogę wysyłać żądania do naszego serwisu internetowego i nie uruchamiają żadnych błędy). Podczas debugowania widzę, że istnieje konfiguracja. Ten zasób nosi nazwę "META-INF/services/javax.xml.bind.JAXBContext". Oto najważniejsze wskazówki dotyczące sposobu, w jaki ten zasób prowadzi do próby załadowania "com.ibm.xml.xlxp2.jaxb.JAXBContextFactory", co powoduje zgłoszenie wyjątku ClassNotFoundException. To jest uproszczona źródłem wspomnianej klasy javax.xml.bind.ContextFinder:

URL resourceURL = ClassLoader.getSystemResource("META-INF/services/javax.xml.bind.JAXBContext"); 

BufferedReader r = new BufferedReader(new InputStreamReader(resourceURL.openStream(), "UTF-8")); 

String factoryClassName = r.readLine().trim(); 

factoryClassName pole ma teraz wartość „com.ibm.xml.xlxp2.jaxb.JAXBContextFactory”

Ponieważ ta ma zostanę super lageriem, dodam też nagrodę :) Będę pracował cały dzień nad tym i dam ci znać, jeśli pojawią się jakieś nowości.

Aktualizacja/Rozwiązanie

Ta kwestia została rozwiązana. Pierwotny problem pojawił się, ponieważ błędnie skonfigurowano złożoną kompilację projektów z wieloma modelami, z których jedna korzystała z zaktualizowanej wersji niestandardowego słoja łącza zaćmienia, która zawierała definicję JAXBFactory niedostępną w komponencie, w którym wystąpił błąd. Ustawienie fabryki kontekstów JAXB w większości przypadków jest skonfigurowane za pomocą pliku jaxb.propertie lub pliku JAXBContext, który zawiera tę samą definicję. Szczegółowy proces ładowania odpowiedniego JAXBContextFactory odbywa się w javax.xml.bind.ContextFinder.

Błąd nie został jeszcze rozwiązany (podczas gdy ponad 4 główne aplikacje EE/SE prowadzą do błędu) i nie ma ogólnej odpowiedzi, ale zdefiniowany obiekt JAXBContextFactorys musi istnieć w ścieżce klas (wow, co za cud ...), więc albo masz błąd ClassNotFound, ponieważ brakuje zasobów (oczywiście z powodu przyczyny), albo masz nieprawidłową właściwość JAXBContextFactory zdefiniowaną w dowolnym z wyżej wymienionych plików właściwości, które zawierają definicję zgodną z odpowiedzią poniżej.

Bardzo dziękuję za wspaniałe komentarze i wsparcie, naprawdę doceniam!

+0

Bardzo dziękuję za montaż! – JBA

+0

Z ciekawości, czy twój framework obejmuje JARA JAXB? Czy stara wersja twojego frameworka zawierała jaxb.properties? Nie jest dla mnie jasne, w jaki sposób znalazłeś się w sytuacji, w której twój moduł ładujący klasy aplikacji może zobaczyć plik META-INF/services, ale nie klasę implementacji. Nie jest też dla mnie jasne, dlaczego stara wersja frameworka wybierała kiedykolwiek implementację com.sun. –

+0

Wielkie dzięki za twoje dane wejściowe, i edytuję pytania, aby mieć nadzieję dostarczyć więcej informacji – JBA

Odpowiedz

5

Można dołączyć plik jaxb.properties w tym samym pakiecie, co model domeny, aby określić implementację JAXB (JSR-222), której chcesz użyć. Na przykład będzie wyglądać następująco w celu określenia EclipseLink MOXy jako dostawcy JAXB.

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

Aby uzyskać więcej informacji

+0

@ user1902288 - Kto dostarcza wpis "META-INF/services/javax.xml.bind.JAXBContext" ", ciebie lub WebSphere? –

+0

@ BlaiseDoughan Jest dostarczany przez WebSphere. –

+0

Podniosłem twoją odpowiedź, ponieważ wydaje się, że jest to oficjalny sposób ustawiania pożądanego kontekstu. Nawet dlatego, że umieściłem ten plik w obu pakietach modeli (zarówno tych używanych w usłudze, jak i tych w testach integracyjnych) błąd nadal występuje i obecnie debuguję, dlaczego nie znajduje tych jaxb.properties. Gdy tylko zadziała, przyjmuję twoją odpowiedź, aby uzyskać nagrodę za reputację. Myślę, że jest to najlepszy sposób, aby upewnić się, że ContextFacory z Oracle jdk jest wzięty. – JBA

3

Innym szybkie i brudne rozwiązanie (obejście, naprawdę), który pracował dla mnie jest wyraźnie obejmują realizację JAXB do budowa maven. Na przykład

<dependency> 
    <groupId>javax.xml.bind</groupId> 
    <artifactId>jaxb-api</artifactId> 
    <version>2.2.7</version> 
</dependency> 
<dependency> 
    <groupId>com.sun.xml.bind</groupId> 
    <artifactId>jaxb-impl</artifactId> 
    <version>2.2.7</version> 
</dependency> 

Zauważ, że to dodaje jakoś niepotrzebną zależność do budowy, jak JAXB oczywiście już jest częścią każdego JRE> = wersja 6.

Najprawdopodobniej to będzie działać tylko wtedy, gdy jest classloader WAS ustaw na rodzica jako ostatni.

+0

Nie sądzę, że będzie działać domyślnie - WAS nadal będzie korzystał z własnej implementacji z nadrzędnego modułu ładującego klasy. – kboom

+1

To na pewno zadziałało dla mnie w tym czasie. Być może ustawienie klasy WAS na rodzic jako ostatnia byłoby opcją lub wyłączenie/zmiana domyślnej implementacji zgodnie z opisem tutaj: http://stackoverflow.com/a/10002848/1845976 lub może działać tak samo jak w przypadku JAXWS, jak opisano tutaj: http://stackoverflow.com/questions/24864549/error-deploying-jaxws-webservice-on-websphere-server/24866039#24866039 – schnatterer

+0

Masz rację! To jest poprawne rozwiązanie, ale uwzględnij to w swojej odpowiedzi. – kboom

Powiązane problemy