odwołanie do innego projektu JEE, NoClassDefFoundError

0

Witam
Na początku napiszę że używam Eclipse+Glassfish+JPA, a to wszystko w projekcie Eclipse Dynamic Web Project. Mam dwa takie projekty i chcę aby miały możliwość wymiany danych między sobą. Nie ma znaczenia czy oba są "Dynamic..." czy też jeden jest "Dynamic.. " a drugi EJB Project błąd zawsze jest ten sam.
Mam pytanie: czy ktoś może mi racjonalnie wyjaśnić dlaczego ciągle dostaję błąd (podczas uruchamiania strony na serwerze): **HTTP Status 500 - **

 
exception 
javax.servlet.ServletException

root cause 
javax.ejb.EJBException

root cause 
java.lang.NoClassDefFoundError: wynik/Asocjacyjna

root cause 
java.lang.ClassNotFoundException: wynik.Asocjacyjna

Klasy na pewno się widzą, ponieważ wskazałem je "sobie" w Java Build Patch, mam dostęp do wszystkich metod danej klasy a jednocześnie ciągle dostaję ten błąd znalezienia klasy. W klasie do której chcę się dobrać mam zapytanie JPQL oraz powiedzmy jakąś zmienną String. Jeśli chcę uzyskać dostęp do tych zmiennych przez metodę (będącą w pliku EJB) którą "wyrzucam" do pliku xhtml to właśnie otrzymuję błąd serwera. W przypadku gdy chcę uzyskać dostęp do zmiennej String z klasy nie będącej EJB tylko posiadającą zwykłą metodę main - dane ze zmiennej tekstowej poprawnie wyświetlane są na konsoli !

Dodam tylko jeszcze, że w przypadku błędu powyżej, spróbowałem stworzyć zwykły Java Project i tam klasę z metodą która odwołuje się do listy List do jednego z projektów, a drugi projekt wywołuje metodę z tego "zwykłego" projektu aby uzyskać dostęp do listy. Wynik zawsze jest taki sam, niezależnie czy korzystam z odwołania bezpośrednio pomiędzy projektami JEE, czy też korzystam z projektu "zwykłego" - będącego nazwijmy to pośrednikiem.

Walczę z tym dłuższy czas i pomysły do testowania innych rozwiązań skończyły mi się już, stąd proszę o wszelkie porady.

0

Nie masz przypadkiem tej klasy w dwóch JARkach? Sprawdź z jakich classloaderów zostały załadowane, np może wrzuć odpowiedni komunikat w konstruktorze? Nie znam się dokładnie na tym.

0

Nazwa klasy na pewno jest taka sama w przynajmniej dwóch projektach, ale w "tym drugiem" projekcie znajduje się w pakiecie który już ma unikalną nazwę. Więc wydaje mi się że nie powinno być kłopotu, zwłaszcza że jak w Eclipse najedzie się myszką na nazwę klasy z innego projektu to nazwę pakietu do którego należy dana klasa wyświetla poprawnie.
Cały czas walczę z tym, już zacząłem od początku tworzyć projekt, może gdzieś po drodze czegoś zabrakło...

0

W jaki sposób chcesz miec dostęp do klas drugiego projektu (java build path pomoze ci tylko powiazac moduły na etapie developmentu w eclipsie co nie oznacza ze beda sie one widziały w kontenerze serwera) , jesli kazdy z nich jest oddzielna aplikacja bedzie to oznaczało ze oba są ładowane prze AppClassLoader który jest inny dla kazdej aplikacji i nie posiada on dostępu do klas z innego loadera aplikacyjnego.

Jesli jeden z projektow posiada EJB czyli tworzysz ear który ląduje na serwerze , i teraz do obiektow EJB mozesz sie dobrac z innego projektu lookup("jndi/jakisObject") po RMI, ale ten projekt z którego bedziesz sie dobierał do EJBa musi po swojej stronie miec na classpath'ie interfejsy które są implementowane przez EJB do których chcesz miec dostęp.

Jesli tworzysz projekty zalezne miedzy sobą , dobrze jest uzywac do tego maven ver2 (jest mnóstwo tutoriali) gdzie konfigurujsze sobie projekt w XML oznaczające powiązania miedzy projektami jako moduły. Nastepnie budujac projekt jedna komenda on rozrzuca odpowiednio liby do modułów które są od siebie zależne.

0

dziękuję za odpowiedź, to już nieco mi wyjaśniło sprawę...
zastanawiam się jeszcze tylko czy możliwe byłoby takie rozwiązanie. Zbudować jedną aplikację Enterprise Application Project i po prostu do niej dołączać EJB project'y który każdy będzie odwoływał się np do innej bazy danych. A wtedy projekt webowy WAR będzie pobierał dane z poszczególnych EJB project'ów.
Ale i tak coś czuję że Maven mnie nie minie.

0
lukiz napisał(a)

dziękuję za odpowiedź, to już nieco mi wyjaśniło sprawę...
zastanawiam się jeszcze tylko czy możliwe byłoby takie rozwiązanie. Zbudować jedną aplikację Enterprise Application Project i po prostu do niej dołączać EJB project'y który każdy będzie odwoływał się np do innej bazy danych. A wtedy projekt webowy WAR będzie pobierał dane z poszczególnych EJB project'ów.
Ale i tak coś czuję że Maven mnie nie minie.

Oczywiście jest to mozliwe.
EJB są ciekawym mechanizmem bo mozesz sie do nich dobierac nawet z zupełnie innej maszyny która ma dostęp po RMI do serwera wystawiającego usługi realizowane przez EJB.
Ale nadal po stronie klienta musisz miec interfejsy tych EJBow.

A co do mavena to naprawdę warto, chociażby na przyszłość, w większosci firm są one uzywane gdyż usprawniają one cały proces budowania i deploymentu aplikacji.
W chwili obecnej nowe projekty, głównie, składane są za pomocą mvn (starsze ant - chociaz niekiedy i nowe tez)

0

Mam jeszcze jedno pytanie... które nawet mi wydaje się dziwne:
czy błędy wyświetlane przez serwer, mogą nie wystąpić w przypadku użycia innego serwera, chodzi mi tutaj konkretnie o Glassfish i JBoss. Zauważyłem że ten pierwszy czasami nie chce mi uruchomić jakiegoś prostego projektu (tworzonego od początku z przeznaczeniem na ten serwer) natomiast w przypadku JBoss wydaje się że tego błędu nie ma. GlassFish jakoś bardziej przypadł mi do gustu, bo konfiguracja z bazą Derby była mniej kłopotliwa - tj wszystko można zrobić przez panel administracyjny, w JBoss wsparcie w necie dotyczące tej bazy danych jest jakby mniejsze niż w odniesieniu do GlassFish'a.

0

wszystko zależy od kodu i konfiguracji, którą stworzysz, czy jest ona zgodna ze specyfikacją obu serwerów.
Sam kod javy powinien działać wszędzie, no chyba ze jawnie korzystasz z odwołań do klas (konkretnych implementacji) specyficznych dla danego serwera, wtedy mozesz miec problemy z przenoszeniem aplikacji miedzy serwerami, aczkolwiek różnie to bywa.
Ja osobiscie GlassFisha nigdy nie uzywałem, zazwyczaj jboss.

0

Minęło dwa tygodnie od czasu gdy zadałem pytanie, przez ten czas pobawiłem się z Mavenem oraz tworzeniem aplikacji Enterprise Application Project w Eclipse. Może komuś przydadzą się moje doświadczenia, a może ktoś inny mnie poprawi i okaże się że była inna droga rozwiązania mojego problemu.
Ogólnie mój problem polegał na połączeniu ze sobą EJB (a w tym JPA do jednej bazy danych) z WAR (a w tym JPA do innej bazy danych). Mimo wielu prób gdzieś zawsze wyskakiwał błąd. O ile w Maven'ie udało mi się połączyć te projekty jako moduły Maven'a (a więc rozwiązałem problem od którego zaczęło się moje pytanie) to później okazało się że ciągle nie widział jednego dowiązania do bazy danych : ładując war'a na serwer glassfish'a ciągle dostawałem Could not resolve a persistence unit corresponding to the persistence-context-ref-name. Znalazłem w sieci informacje jak pozmieniać persistence-context-ref-name w pliku web.xml i odpowiednio tak samo nazwać w klasach EJB: @PersistenceContext(name = "nazwaZPlikuWebXML")aby rozwiązać problem kilku plików persistence.xml w jednym projekcie ear. To jednak nic nie pomagało błąd był nadal.
Ogólnie aby mieć o połowę mniej problemów radzę:
a) korzystać z serwera Glassfish w wersji FULL, a nie WEB! To jest bardzo ważne, ponieważ w tym drugim przypadku błąd otrzymamy na samym początku, a mianowicie wersja WEB nie obsługuje kontenera ear.
b) połączyć pliki EJB i WAR w kontener ear (tj projekt EAR ma mieć zaznaczone w Project References wszystkie inne projekty które wykorzystujemy).
c) jeśli mamy dwie bazy danych (i tak jak mi w przypadku eclipse'a nie udało się zmusić persistence.xml do obsługi dwóch baz w jednym pliku) to najlepiej korzystać z dwóch projektów EJB, każdy do osobnej bazy danych. Te dwa projekty EJB dodać w Java Build Path -> Projects w Eclipse do projektu WAR. Jeśli w projekcie WAR będziemy mieć bazę danych która będzie się odwoływać do któregoś projektu EJB a stamtąd znowu do projektu WAR wtedy mogą być problemy z błędem persistence.xml lub jakimś innym (w tym przypadku o wyświetlenie jakiegoś błędu nie trudno!). Dlatego ja w projekcie WAR nie mam JPA a więc odwołania do żadnej bazy danych.
d) odwołując się do klas EJB stosujemy adnotacje

@EJB 
NazwaKlasy nazwa;

i następie

 
nazwa.metoda();

To samo dotyczy się gdy nazwy metod z klasy EJB mamy w publicznych interfejsach, tj interfejsy też deklarujemy jako @ejb.

Jeśli gdzieś się pomyliłem to proszę o sprostowanie. W końcu to jest nauka ;-)
P.S. Jeśli chodzi o maven'a to jest to wspaniałe narzędzie które nie jest takie straszne jak się na początku wydaje. Jednak wydaje mi się że plugin do Eclipsa spowalnia pracę IDE, wobec czego lepiej korzystać z mavan'a z wiersza poleceń. Choć w przypadku moich "średnich" (pod względem wielkości projektu) zastosowań nadal zostanę przy Eclipse, bo jak się już zrozumie co i jak to chyba nawet szybciej tworzy się taką aplikację niż w maven'ie.
Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1