2011-09-19 17 views
9

Zgodnie z dokumentacją OSGi, OSGi zaprojektowano w celu zapobiegania problemom ClassPath.OSGi: jak zapewnić spójność classpath?

Na przykład z „OSGi w działaniu”:

ClassNotFoundExceptions podczas uruchamiania aplikacji, ponieważ ścieżka klasa nie była prawidłowa. OSGi może pomóc, upewniając się, że zależności kodu są spełnione przed zezwoleniem na wykonanie kodu.

Jednakże, ponieważ mamy włączony naszą aplikację java do OSGi, widzę więcej ClassNotFoundExceptions a zwłaszcza NoClassDefFoundErrors niż kiedykolwiek. Klasy, które poprzednio ładowały grzywnę, nie są już odnajdywane przez klasę ładującą OSGI, a co gorsza: błąd pojawia się w czasie wykonywania, co oznacza, że ​​nie można go łatwo sprawdzić, z wyjątkiem ręcznego testowania każdego zakątka aplikacji.

Na przykład nasza aplikacja działała szczęśliwie w OSGi, ale otrzymaliśmy raporty od testerów wersji beta, że ​​nie mogą już eksportować dokumentów do formatu PDF. Rzeczywiście, kiedy spojrzałam na niego, stwierdziliśmy, że ta funkcjonalność spowodowała wyjątek być zalogowany:

java.lang.NoClassDefFoundError: org/w3c/dom/Node 

Tak, rzeczywiście jest OSGi tworząc więcej problemów niż rozwiązuje ścieżki klasy?

i co ważniejsze: Jak mogę przetestować, czy moja ścieżka klasowa jest spójna, ze wszystkimi niezbędnymi instrukcjami dotyczącymi pakietów importowych itp. przed Czytałem o nich w raportach o błędach?

+0

„z wyjątkiem ręcznego testowania każdego zakątka aplikacji” - ERM zautomatyzowanych testów? (to samo dotyczy każdej aplikacji) Jeśli przed rozpoczęciem migracji testowałeś pakiety testowe, wykryłbyś te błędy przed testerami. Aby przetestować, czy pakiety są poprawnie podłączone, musisz wykonać kilka testów integracji - używamy do tego celu egzaminu Pax i mamy krótkie testy integracyjne (obecny pakiet i jego współpracownicy), a także niektóre dłuższe testy end-to-end (testowanie całej aplikacji). – earcam

Odpowiedz

12

wniosku istnieje OSGi będzie nie rzucać ClassNotFoundExceptions i NoClassDefFoundErrors jeśli Twój manifest jest poprawna. Oznacza to, że musisz powiedzieć OSGi, które pakiety używa twój pakiet; jeśli nie zrobisz tego poprawnie lub uczciwie, to OSGi nie może ci pomóc. Innymi słowy: GIGO (Garbage In, Garbage Out).

Na przykład, używasz pakietu org.w3c.dom, ale nie umieścisz go w swoim oświadczeniu Import-Package. Dlatego OSGi nie wie, że potrzebujesz dostępu do tego pakietu, a więc kiedy faktycznie spróbujesz załadować klasy z tego pakietu, nie będą one dostępne.

Musisz więc upewnić się, że twoje oświadczenie Import-Package jest dokładne w odniesieniu do pakietów, których faktycznie używają pakiety. Dobrą wiadomością jest to, że narzędzie "bnd" może zrobić to za Ciebie, generując manifest pakietu, używając analizy kodu bajtowego, aby znaleźć wszystkie statycznie powiązane pakiety.

Aktualizacja: Twoje ostatnie pytanie pyta jak testować, że zestawy są zgodne przed odkrywając problemy przy starcie. Bnd ma funkcję "weryfikuj", która robi dokładnie to. Właściwie jeśli użyjesz Bnd do wygenerowania manifestu, nie będziesz potrzebować funkcji weryfikacji. Jednak nie wiem nic o twoim procesie kompilacji, więc możesz mieć trudności z przejściem do kompilacji opartej na Bnd w krótkim czasie ... w tym przypadku stosunkowo łatwo byłoby dodać zadanie weryfikacji jako krok przetwarzania po kompilacji. Jednak nadal zalecałbym próbę użycia Bnd wcześniej w procesie kompilacji.

+0

Nie wiedziałem o funkcji weryfikacji bnd, bardzo dobrze wiedzieć! – amarillion

+3

"jeśli twój manifest jest poprawny" ... oznacza, że ​​jeśli twój manifest jest dokładnie taki, jakiego używa twoja konkretna implementacja, a nie robisz nic, to projektanci OSGI i koderowie konkretnej implementacji, której używasz, nie są " t myślałem. Zgadzam się z amarillionem - OSGI jest koszmarem problemów klasowych, przy czym nie ma dostępnych mechanizmów rozwiązywania problemów. Może to być cenne dla użytkowników końcowych w zakresie większej elastyczności wdrażania, ale jest to HELL dla programistów. – user252690

+0

@ user252690 Anonimowi tchórze łatwo mogą rzucić się o obelgi w Internecie. Jeśli się uspokoisz i zdecydujesz się czegoś nauczyć, wiesz, gdzie znaleźć rozsądnych ludzi, którzy mogą pomóc. –

2

Myślę, że problem polega na tym, że nie określasz poprawnego zestawu pakietów/klas używanych przez twój pakiet (używając dyrektywy Import-Packages w MANIFEST). O ile OSGi o tym nie wie, to naprawdę nie może pomóc!

Nie wiesz, jak budujesz pakiety OSGi, ale powinieneś sprawdzić kod Maven bundle plugin, który rozwiązuje problemy związane z jawnym określaniem pakietów importu (przynajmniej dla tych z kompilacją). Zobacz http://wso2.org/library/tutorials/develop-osgi-bundles-using-maven-bundle-plugin#Importing%20packages.

+0

+1. Wystarczy dodać: wtyczka Maven Bundle jest oparta na Bnd, więc wszystko, co powiedziałem w mojej odpowiedzi na temat korzystania z Bnd, odnosi się również do wtyczki Maven Bundle. Jeśli twoja kompilacja nie jest obecnie oparta na Maven, nie ma potrzeby przeprowadzania się do Maven, aby uzyskać tę funkcjonalność. –

1

Nie odpowiadam na główne pytanie, ale dostarczam moje rozwiązanie podobnego problemu.

W moim przypadku, miałem tej klasy strukturę:

  • interface javax.script.ScriptEngineFactory
  • class pkga.A implements ScriptEngineFactory
  • class pkgb.B extends A

Moim głównym kod projektu było w klasie B i to rozszerzona klasa A w zależny Słoik. Korzystanie

<Export-Package>pkgb.*</Export-Package> 

była niewystarczająca, otrzymałem błąd narzekają na brak javax.script.ScriptEngineFactory. Jest to dziwne, ponieważ jest częścią standardowego JDK 8, zauważ, że kod w pakiecie pkgbnie zawierał jawnie referencji javax.script.*; być może pisarz Manifest nie wiedział, że ten interfejs musi zostać wyeksportowany?

znalazłem ten dodatek do dyrektywy Export-Package rozwiązał problem

<Export-Package>pkgb.*,javax.script.*</Export-Package>