2012-06-14 9 views
13

Ich habe ein OSGi Bundle mit Persistenz-Service (mit hibernate) und ein Fragment, das Konfiguration (XML-Datei) enthält. Im Bundle-Aktivator, ich lade die Konfiguration mit:Wann ist ein OSGi-Fragment an den Host angehängt?

@Override 
public void start(BundleContext ctx) { 
    URL url = ctx.getBundle().getResource("hibernate.cfg.xml"); 
    SessionFactory sessionFactory = new AnnotationConfiguration().configure(url).buildSessionFactory(); 
} 

aber manchmal, das URL ist null. Als ich versucht habe, alle verfügbaren URL s (unter Verwendung der findEntries Methode) aufzulisten, schien es, dass die eigenen eigenen immer verfügbar sind, aber die fragmentierten nur manchmal. Ich benutze Felix 4.0.2, das Bündel und das Fragment wird bei Felix gestartet. auto.start level.

Antwort

22

Fragmente werden an den Host zu dem Zeitpunkt angehängt, zu dem der Host aufgelöst wird. Normalerweise wird das Fragment so lange angehängt, wie es installiert ist, bevor der Host aufgelöst wird.

Es gibt jedoch immer die Möglichkeit für den Host, ohne das Fragment aufzulösen, weil Hosts nicht von ihren Fragmenten abhängen. Daher sollten Sie normalerweise Ihren Host so schreiben, dass er mit dem Fragment nicht zurechtkommt - dh er sollte keine NPEs werfen.

Seit OSGi R4.3 können Sie mit Hilfe des Require-Capability und Provide-Capability Header. Indem Sie Ihren eigenen Namespace für die Abhängigkeit erfinden, können Sie Ihr Fragment mit Provide-Capability versehen. Dann kann Ihr Host es mit Require-Capability anfordern .... jetzt stellt das OSGi-Framework sicher, dass das Fragment verfügbar sein muss, bevor es den Host auflöst.

+0

Danke, erfordern/bieten Fähigkeit funktioniert perfekt! – Kojotak

+0

Das ist praktisch. Ich habe nie gesehen, dass Usecase fehlschlägt (wir benutzen Equinox), aber ich wusste nicht, dass es das Fragment nicht rechtzeitig "auflösen" könnte. Gut zu wissen. – Robin

+3

Ich möchte StackOverflow lassen mich Benutzer abonnieren, nur damit ich alles Neil Beiträge lesen konnte. :-) Ich lerne fast jedes Mal etwas Neues, wenn er antwortet! –

0

Das Fragment wird während des Auflösungsprozesses des Fragmentbündels an den Host angehängt. Der Host ist aufgelöst und kann erfolgreich gestartet werden, auch wenn das Fragment nicht vorhanden ist. aber das Fragment hängt vom Host ab - es kann aufgelöst und anschließend erst gestartet werden, nachdem es an den Host angehängt wurde.

Wenn Sie beide Bundles mit demselben Startlevel haben, haben Sie scheinbar Rennbedingungen für diese beiden Bundles erstellt. Das Framework beginnt, beide Pakete gleichzeitig aufzulösen und zu starten. Manchmal gelingt es, das Host-Paket zu starten, bevor der Auflösungsprozess des Fragments beendet wurde -> dann verhält sich die Startmethode des Host-Pakets so, als ob kein Fragment verfügbar wäre.

Was Sie tun können, ist z.B. um dem Fragment einen früheren Startpegel als dem des Host-Bündels zu geben. Das Fragment sollte aufgelöst und erfolgreich gestartet werden, selbst wenn das Host-Paket noch nicht gestartet wurde. Es muss nur das Host-Paket aufgelöst werden.

Sie können dieses Verhalten auch auf anderen OSGi-Frameworks testen - z. auf ProSyst's mBedded Server (mBS) - Ich weiß, dass es vollständig konform mit OSGI-Spezifikation 4.2 ist, wo die obige Fragmentauflösung angegeben ist.

+0

Vielen Dank für die Klarstellung! Leider funktioniert es nicht. Ich habe den Felix.auto.start Level für das Fragment niedriger als für das Paket selbst festgelegt. Ich habe dies in der gogo-Konsole überprüft - das Bundle hat eine höhere Stufe als das Fragment. Ich glaube, dass das Startlevel nicht garantiert, dass das Bündel/Fragment mit niedrigerem Level seine Auflösung beenden wird, bevor es zu einem höheren Startlevel geht. – Kojotak

+4

Das ist falsch. Zuerst hängt das Fragment zu dem Zeitpunkt an, zu dem der * Host * aufgelöst ist. Zweitens wird das Framework nicht gleichzeitig aufgelöst und gestartet. Tatsächlich hat das Starten keinerlei Auswirkung auf die Auflösung, und Fragmente können sowieso nicht gestartet werden. –

Verwandte Themen