OSGi: wie gewährleisten Sie die classpath-Konsistenz?
Gemäß der OSGi-Dokumentation, OSGi ist entworfen, um zu helfen verhindern, dass die ClassPath-Probleme.
Beispielsweise von "OSGi in action":
ClassNotFoundExceptions beim starten der Anwendung, weil die
Klasse Pfad war nicht korrekt. OSGi können helfen, indem Sie sicherstellen, dass code
Abhängigkeiten erfüllt sind, bevor der code ausgeführt werden soll.
Jedoch, seit wir gewechselt haben, unsere java-Anwendung OSGi, sehe ich mehr ClassNotFoundExceptions und vor allem NoClassDefFoundErrors als je zuvor. Klassen, die vorher feinen laden findet man nicht mehr von der OSGI classloader, und schlimmer noch: Sie erhalten die Fehlermeldung in run-time, was bedeutet, dass Sie nicht einfach zu überprüfen, außer durch die manuelle Prüfung jeder Ecke der Anwendung.
Beispielsweise die, unser Antrag wurde problemlos ausgeführt unter OSGi, aber wir erhalten Berichte von beta-Testern, dass Sie nicht exportieren Sie Dokumente in PDF nicht mehr. In der Tat, wenn ich sah in ihm, ich fand, dass diese Funktionalität verursacht eine Ausnahme protokolliert werden:
java.lang.NoClassDefFoundError: org/w3c/dom/Node
So, ist OSGi eigentlich die Schaffung von mehr classpath-Probleme, als Sie löst?
und noch wichtiger: Wie kann ich testen, ob meine Klasse-Pfad ist konsistent mit allen notwendigen Import-Package-Anweisungen etc. vor ich über Sie zu Lesen in bug-reports?
- "außer durch die manuelle Prüfung jeder Ecke der Anwendung" - erm automatisierten tests? (das gleiche gilt für jede Anwendung), Wenn Sie hatte eine test-suites, bevor Sie migriert sind, die Sie haben würden, entdeckte diesen Fehler noch vor der Tester hatte. Um zu testen, ob Ihr Bündel Draht, richtig, Sie benötigen dazu einige Integrationstests - wir sind mit Pax Exam für diese und haben kurze integration tests (aktuelle bundle und es ist Mitarbeitern) sowie einige längere Ende-zu-Ende-tests (testen der gesamten app).
- Für die Suche nach dieser stack-überlauf, wenn Sie auf der Suche OSGi NoClassDefFound.... halten Sie es daran, dass die aktuelle Java-thread ausführen, das OSGi-bundle-code bestimmt die "aktive" ClassLoader aka Thread-Kontext-ClassLoader (TCCL). Die "active" - ClassLoader kann nicht der ClassLoader des OSGi-container erstellt für die bundle-code. Damit alles klappt, manchmal muss man manuell wechseln, der thread ist TCCL.
- Siehe 2012. Neil Bartlett. "Der Gefürchtete Thread Context Class Loader", blogs.paremus.com/2012/10/....
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer OSGi-Anwendung wird nicht werfen ClassNotFoundExceptions und NoClassDefFoundErrors wenn Ihrem manifest korrekt ist. Das heißt, Sie müssen sagen, OSGi, welche Pakete des Bundles verwendet, wenn Sie nicht tun, diese korrekt oder ehrlich, dann OSGi kann dir nicht helfen. In anderen Worten: GIGO (Garbage In, Garbage Out).
Verwenden Sie beispielsweise das Paket
org.w3c.dom
aber Sie tun es nicht in IhrerImport-Package
- Anweisung. Daher OSGi nicht wissen, dass Sie benötigen den Zugriff auf das Paket, und so, wenn Sie tatsächlich versuchen, zu laden Klassen aus diesem Paket, sind Sie nicht verfügbar.So, Sie müssen sicherstellen, dass Ihre
Import-Package
Aussage ist korrekt mit Bezug auf die Pakete, die Ihre bundles auch tatsächlich nutzen. Die gute Nachricht ist, dass der "bnd" - tool kann dies für Sie tun, von der Erzeugung der bundle-manifest, mit bytecode-Analyse, um herauszufinden, alle statisch referenzierten Pakete.Update:
Ihre Letzte Frage fragt, wie um zu testen, ob Ihre bundles sind konsistent vor der Entdeckung der Probleme zur Laufzeit. Bnd hat eine "verify" - Funktion, die tut genau dies. Eigentlich, wenn Sie verwenden Bnd zu generieren, das manifest in den ersten Platz, dann werden Sie nicht brauchen, überprüfen Sie die Funktion. Allerdings, ich weiß nicht, etwas über Ihren build-Prozess, so dass Sie vielleicht finden es schwierig, sich zu bewegen, um eine Bnd-basiertes build, die kurzfristig... in diesem Fall wäre es relativ einfach ist, fügen Sie die Verifizierung Aufgabe als post-processing-Schritt-nach-dem bauen. Allerdings würde ich noch empfehlen, versucht die Bnd früher in den build-Prozess.
Ich denke, die Probleme hier ist, dass Sie nicht die richtige Angabe Pakete/Klassen von Ihren bundle (mit der Import-Pakete, die Richtlinie in Ihr MANIFEST). Es sei denn, OSGi kennt diejenigen, die es wirklich nicht Hilfe!!!
Nicht sicher, wie Sie den Aufbau Ihrer OSGi-bundles, aber Sie sollten überprüfen, die
Maven bundle plugin
, das löst die Probleme explizit angeben, Import-Pakete (zumindest für die compile-Zeit sind). Sehen http://wso2.org/library/tutorials/develop-osgi-bundles-using-maven-bundle-plugin#Importing%20packages.Ich bin nicht die Beantwortung der zentralen Frage, aber meine Lösung für ein ähnliches problem.
In meinem Fall hatte ich diese Klasse-Struktur:
interface javax.script.ScriptEngineFactory
class pkga.A implements ScriptEngineFactory
class pkgb.B extends A
Mein wichtigstes Projekt war der code in der Klasse
B
und diese erweiterte KlasseA
in einem abhängigen Jar. Mitnicht ausreichend war, erhielt ich eine Fehlermeldung, Klagen über den Mangel an
javax.script.ScriptEngineFactory
. Dies ist seltsam, wie es ist Bestandteil des standard-JDK-8, beachten Sie, dass code im Paketpkgb
nicht explizit Referenzjavax.script.*
; vielleicht das Manifest der Schriftsteller wusste nicht, dass dieses interface benötigt werden, exportiert werden?Fand ich dies zusätzlich zu den Export-Package-Richtlinie das problem gelöst