Bundle.findEntries() i spring-osgi-bundle-archetype w akcji - monitorowanie pakunków OSGi z określoną strukturą katalogową

Z Jacek Laskowski - Wiki Projektanta Java EE

Spring Dynamic Modules (dalej Spring-DM) umożliwia tworzenie ziaren springowych jako pakunki OSGi umożliwiając skorzystanie z cech obu środowisk - Spring Framework i OSGi. Tak określiłbym motto projektu. Jednym z elementów wspomagających tworzenie aplikacji korporacyjnych ze Spring-DM jest stworzenie środowiska uruchomieniowego, w którym cechy OSGi są integralną częścią środowiska. W ten sposób aplikacja webowa może być dystrybuowana w postaci pakunku (wystarczy jedynie dopisanie kilku nagłówków w META-INF/MANIFEST.MF) i uruchomiona w ramach Platformy OSGi (Equinox, Felix czy Knopflerfish). Teoretycznie (jeszcze) możemy sobie wyobrazić sytuację, w której poszczególne części aplikacji są dystrybuowane jako pakunki OSGi, które z kolei składają się na większy pakunek OSGi będący nota bene aplikacją webową. "A po co?" - możnaby zapytać. Odpowiedź sama się nasuwa - wprowadzenie/podniesienie modularności w aplikacji. Jeśli weźmiemy za przykład aplikację webową, to jej jedną z części mogą być servlety zgrupowane jako pakunek OSGi, który dzięki mechanizmom OSGi moglibyśmy podmienić...w trakcie działania naszej aplikacji (!) Czyż nie jest to cecha, której wprowadzenia pożądalibyśmy w naszych aplikacjach? Z pewnością!

Analizując kod projektu Spring-DM w poszukiwaniu odpowiedzi jak on działa i jego współpracy z OSGi, aby mógł rozpoznawać pakunki OSGi jako aplikacje webowe i uruchamiać w ramach kontenera servletów - Jetty lub Apache Tomcat (również będącymi pakunkami OSGi) - natrafiłem na moduł spring-osgi-web-extender. Zacząłem od META-INF/MANIFEST.MF, który jest "sercem" pakunku OSGi - podstawowym miejscem konfiguracji. Jedynym elementem pliku było

Bundle-Activator: org.springframework.osgi.web.extender.internal.activator.WarLoaderListener

Bundle-Activator jest nagłówkiem wskazującym na klasę uruchamianą podczas uruchomienia i zatrzymania pakunku, dla którego został zdefiniowany (więcej w Specyfikacja OSGi - rozdział 4.3 Obiekt Bundle - dokończenie). Podczas tej "wyprawy" natrafiłem na metodę org.osgi.framework.Bundle.findEntries(), której zadaniem jest zwrócenie zawartości odpytywanego pakunku jako listę URLi. W ten sposób możemy prześwietlić zawartość pakunków i poznać ich strukturę katalogową. Dodając do tego możliwość rejestracji słuchacza zdarzeń instalacja/odinstalowanie pakunków przy pomocy org.osgi.framework.BundleListener mamy doskonały sposób na monitorowanie zmian na Platformie OSGi i weryfikację, czy zainstalowany właśnie pakunek nie jest przypadkiem specjalnego traktowania przez naszą aplikację monitorującą. Zgłoszenie zdarzenia podmiany (=odinstalowania i instalacji) pakunku ponownie powoduje wzbudzenie BundleListener i wykonanie właściwej akcji. Mam wrażenie, że jest to jedyny tego typu szkielet aplikacyjny, który znosi z nas obowiązek własnoręcznego tworzenia mechanizmu monitorowania zmian w środowisku - w OSGi wystarczy jedynie implementacja BundleListener.

Jako przykładową aplikację można wyobrazić sobie taką, która reaguje na instalację ziaren EJB (występującymi jako pakunki OSGi) zakładając, że poprawne paczki EJB posiadają plik META-INF/ejb-jar.xml (co nie jest obowiązkowe, ale na potrzeby naszego przykładu przymknijmy na to oko).

Do stworzenia "monitorującego" pakunku OSGi skorzystam z wtyczki Spring-DM - spring-osgi-bundle-archetype (więcej w How to create a Spring-DM bundle project using Maven (and Eclipse...)) oraz Introduction to OSGi.

mvn archetype:create \
 -DarchetypeGroupId=org.springframework.osgi \
 -DarchetypeArtifactId=spring-osgi-bundle-archetype \
 -DarchetypeVersion=1.2.0-m2-SNAPSHOT \
 -DgroupId=pl.jaceklaskowski.spring \
 -DartifactId=spring-ejb-monitor-bundle \
 -Dversion=1.0

Może być wymagane zastąpienie wersji rozwojowej 1.2.0-m2-SNAPSHOT (jako archetypeVersion) na obecnie produkcyjną 1.1.1.

W katalogu projektu spring-ejb-monitor-bundle uruchamiam mvn package, aby sprawdzić poprawne zestawienie projektu.

jlaskowski@work /cygdrive/c/projs/sandbox/spring-ejb-monitor-bundle
$ mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Spring OSGi Bundle
[INFO]    task-segment: [package]
[INFO] ------------------------------------------------------------------------
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 35 seconds

W pom.xml (=sercu projektu mavenowego) definiuję zależność:

<dependency>
  <groupId>org.osgi</groupId>
  <artifactId>org.osgi.core</artifactId>
  <version>4.0</version>
</dependency>

w sekcji <dependencies>, podnoszę domyślną wersję Javy do 1.5 (jako konfiguracja wtyczki maven-compiler-plugin w sekcji <plugins>):

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <source>1.5</source>
    <target>1.5</target>
  </configuration>
</plugin>

oraz dodaję deklarację aktywatora do istniejącej konfiguracji wtyczki maven-bundle-plugin:

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <extensions>true</extensions>
  <version>1.4.0</version>
  <configuration>
    <manifestLocation>META-INF</manifestLocation>
    <instructions>
      <Export-Package>!pl.jaceklaskowski.spring.internal,pl.jaceklaskowski.spring*</Export-Package>
      <Private-Package>pl.jaceklaskowski.spring.internal.*</Private-Package>
      <Include-Resource>src/main/resources</Include-Resource>
      <Bundle-Activator>pl.jaceklaskowski.spring.internal.Aktywator</Bundle-Activator>
    </instructions>
  </configuration>
</plugin>

Dla uproszczenia wprowadzania zmian w artefaktach projektowych warto podeprzeć się Eclipse IDE z wtyczką m2eclipse lub NetBeans IDE 6.5 z NetBeans Mevenide.

Tworzę klasę pl.jaceklaskowski.spring.internal.Aktywator (plik src/main/java/pl/jaceklaskowski/spring/internal/Aktywator.java):

package pl.jaceklaskowski.spring.internal;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;

public class Aktywator implements BundleActivator {

    private final static BundleListener SLUCHACZ = new BundleListener() {
        public void bundleChanged(BundleEvent event) {
            System.out.println("Pakunek " + event.getBundle().getSymbolicName() + " zmienił stan");
            switch (event.getType()) {
            case BundleEvent.INSTALLED:
                System.out.println("...zainstalowano");
                // sprawdź, czy zawiera META-INF/ejb-jar.xml, który oznacza moduł EJB
                if (null != event.getBundle().findEntries("META-INF", "ejb-jar.xml", false)){
                    System.out.println("...rozpoznano moduł EJB");
                }
                break;
            case BundleEvent.UNINSTALLED:
                System.out.println("...odinstalowano");
                break;
            }
        }

    };

    public void start(BundleContext context) throws Exception {
        System.out.println("Instalacja " + SLUCHACZ);
        context.addBundleListener(SLUCHACZ);
    }

    public void stop(BundleContext context) throws Exception {
        System.out.println("Usuniecie " + SLUCHACZ);
        context.removeBundleListener(SLUCHACZ);
    }
}

Jak wspomniałem wcześniej, zadaniem aktywatora jest zarejestrowanie słuchacza (ang. listener) do przechwytywania zdarzeń instalacji/odinstalowania pakunków i w razie stwierdzenia pakunku z plikiem META-INF/ejb-jar.xml odnotowanie tego faktu w dzienniku zdarzeń (ang. log).

Ponownie mvn package, aby w katalogu target odnaleźć gotowy do użycia pakunek pl.jaceklaskowski.spring.spring-ejb-monitor-bundle (nazwa pochodzi z nagłówka Bundle-SymbolicName, która została stworzona przez wtyczkę spring-osgi-bundle-archetype podczas tworzenia projektu).

jlaskowski@work /cygdrive/c/projs/sandbox/spring-ejb-monitor-bundle
$ mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Spring OSGi Bundle
[INFO]    task-segment: [package]
[INFO] ------------------------------------------------------------------------
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 27 seconds

jlaskowski@work /cygdrive/c/projs/sandbox/spring-ejb-monitor-bundle
$ ls -l target/spring-ejb-monitor-bundle-1.0.jar
-rwx------+ 1 jlaskowski None 5490 Sep 14 22:22 target/spring-ejb-monitor-bundle-1.0.jar

Uruchomienie wybranej platformy OSGi (np. Apache Felix poleceniem java -jar bin/felix.jar z poziomu jego katalogu domowego) i pozostaje zainstalować dowolny moduł EJB (dystrybuowany jako pakunek OSGi).

jlaskowski@work /cygdrive/c/apps/felix
$ java -jar bin/felix.jar

Welcome to Felix.
=================

Enter profile name: springdm

DEBUG: WIRE: 1.0 -> org.osgi.service.packageadmin -> 0
DEBUG: WIRE: 1.0 -> org.osgi.service.startlevel -> 0
DEBUG: WIRE: 1.0 -> org.ungoverned.osgi.service.shell -> 1.0
DEBUG: WIRE: 1.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 1.0 -> org.apache.felix.shell -> 1.0
DEBUG: WIRE: 2.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 2.0 -> org.apache.felix.shell -> 1.0
DEBUG: WIRE: 3.0 -> org.osgi.service.obr -> 3.0
DEBUG: WIRE: 3.0 -> org.osgi.framework -> 0
-> DEBUG: WIRE: 3.0 -> org.apache.felix.shell -> 1.0

-> install file:c:/projs/sandbox/spring-ejb-monitor-bundle/target/spring-ejb-monitor-bundle-1.0.jar
Bundle ID: 4
-> start 4
DEBUG: WIRE: 4.0 -> org.osgi.framework -> 0
Instalacja pl.jaceklaskowski.spring.internal.Aktywator$1@166aa18
-> Pakunek pl.jaceklaskowski.spring.spring-ejb-monitor-bundle zmienił stan

Można zauważyć, że każdorazowa zmiana stanu pakunku powoduje wzbudzenie monitora (acz komunikat o odnalezieniu modułu EJB jeszcze się nie pojawił).

Nie trudząc się stworzeniem nowego pakunku z META-INF/ejb-jar.xml posiłkuję się przykładowym modułem EJB z projektu Apache OpenEJB - openejb-itests-beans-3.0.jar (jest on dostępny w repozytorium Apache Maven 2). Do instalacji "obcej" paczki jar ("obcej" = nie będącej pakunkiem OSGi) wykorzystam narzędzie Pax URL - wrap.

-> install file:c:/apps/pax/pax-url-wrap-0.3.2.jar
Bundle ID: 5
Pakunek org.ops4j.pax.url.wrap; singleton:=true zmienił stan
-> ...zainstalowano
WARNING: Unable to resolve bundle 5 (org.osgi.framework.BundleException: Unresolved package in bundle 5: package; 
(&(package=org.osgi.service.cm)(version>=1.0.0)(!(version>=2.0.0))))
-> shutdown
-> Usuniecie pl.jaceklaskowski.spring.internal.Aktywator$1@166aa18

Do poprawnej pracy Pax URL wymagana jest instalacja Configuration Admin Package Version 1.2, który jest dystrybuowany w ramach Apache Felix jako osobny pakunek Config Admin (dla innych platform OSGi - Equinox, Knopflerfish - osobna instalacja pakunku może nie być konieczna).

Dodaję org.apache.felix.configadmin-1.0.4.jar do zestawu automatycznie uruchamianych pakunków podczas startu Felix'a, tj. edycja pliku conf/config.properties z jego katalogu domowym. Zmieniam

felix.auto.start.1= \
 file:bundle/org.apache.felix.shell-1.0.1.jar \
 file:bundle/org.apache.felix.shell.tui-1.0.1.jar \
 file:bundle/org.apache.felix.bundlerepository-1.0.3.jar 

na

felix.auto.start.1= \
 file:bundle/org.apache.felix.shell-1.0.1.jar \
 file:bundle/org.apache.felix.shell.tui-1.0.1.jar \
 file:bundle/org.apache.felix.bundlerepository-1.0.3.jar \
 file:bundle/org.apache.felix.configadmin-1.0.4.jar

po umieszczeniu pobranego pakunku Config Admin w katalogu bundle.

Ponowne uruchamienie Apache Felix (tym razem z parametrem felix.cache.profile, który znosi obowiązek podawania nazwy profilu przy uruchomieniu).

jlaskowski@work /cygdrive/c/apps/felix
$ java -Dfelix.cache.profile=springdm -jar bin/felix.jar

Welcome to Felix.
=================

DEBUG: WIRE: 1.0 -> org.osgi.service.packageadmin -> 0
DEBUG: WIRE: 1.0 -> org.osgi.service.startlevel -> 0
DEBUG: WIRE: 1.0 -> org.ungoverned.osgi.service.shell -> 1.0
DEBUG: WIRE: 1.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 1.0 -> org.apache.felix.shell -> 1.0
DEBUG: WIRE: 2.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 2.0 -> org.apache.felix.shell -> 1.0
DEBUG: WIRE: 3.0 -> org.osgi.service.obr -> 3.0
DEBUG: WIRE: 3.0 -> org.osgi.framework -> 0
-> DEBUG: WIRE: 3.0 -> org.apache.felix.shell -> 1.0
DEBUG: WIRE: 4.0 -> org.osgi.framework -> 0
Instalacja pl.jaceklaskowski.spring.internal.Aktywator$1@166aa18
DEBUG: WIRE: 6.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 6.0 -> org.apache.felix.cm.file -> 6.0
DEBUG: WIRE: 6.0 -> org.apache.felix.cm -> 6.0
DEBUG: WIRE: 6.0 -> org.osgi.service.cm -> 6.0
Pakunek pl.jaceklaskowski.spring.spring-ejb-monitor-bundle zmienił stan
Pakunek org.apache.felix.configadmin zmienił stan
Pakunek org.apache.felix.configadmin zmienił stan
Pakunek System Bundle zmienił stan

-> ps -l
START LEVEL 1
   ID   State         Level  Location
[   0] [Active     ] [    0] System Bundle
[   1] [Active     ] [    1] file:bundle/org.apache.felix.shell-1.0.1.jar
[   2] [Active     ] [    1] file:bundle/org.apache.felix.shell.tui-1.0.1.jar
[   3] [Active     ] [    1] file:bundle/org.apache.felix.bundlerepository-1.0.3.jar
[   4] [Active     ] [    1] file:c:/projs/sandbox/spring-ejb-monitor-bundle/target/spring-ejb-monitor-bundle-1.0.jar
[   5] [Installed  ] [    1] file:c:/apps/pax/pax-url-wrap-0.3.2.jar
[   6] [Active     ] [    1] file:bundle/org.apache.felix.configadmin-1.0.4.jar
-> start 5
DEBUG: WIRE: 5.0 -> org.osgi.service.url -> 0
DEBUG: WIRE: 5.0 -> org.ops4j.pax.url.wrap -> 5.0
DEBUG: WIRE: 5.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 5.0 -> javax.xml.transform.stream -> 0
DEBUG: WIRE: 5.0 -> org.osgi.service.cm -> 6.0
DEBUG: WIRE: 5.0 -> javax.xml.transform -> 0
DEBUG: WIRE: 5.0 -> javax.net.ssl -> 0
Pakunek org.ops4j.pax.url.wrap; singleton:=true zmienił stan
*DEBUG* Scheduling task ManagedService Update: pid=org.ops4j.pax.url.wrap
*DEBUG* Running task ManagedService Update: pid=org.ops4j.pax.url.wrap
-> Pakunek org.ops4j.pax.url.wrap; singleton:=true zmienił stan
-> ps -l
START LEVEL 1
   ID   State         Level  Location
[   0] [Active     ] [    0] System Bundle
[   1] [Active     ] [    1] file:bundle/org.apache.felix.shell-1.0.1.jar
[   2] [Active     ] [    1] file:bundle/org.apache.felix.shell.tui-1.0.1.jar
[   3] [Active     ] [    1] file:bundle/org.apache.felix.bundlerepository-1.0.3.jar
[   4] [Active     ] [    1] file:c:/projs/sandbox/spring-ejb-monitor-bundle/target/spring-ejb-monitor-bundle-1.0.jar
[   5] [Active     ] [    1] file:c:/apps/pax/pax-url-wrap-0.3.2.jar
[   6] [Active     ] [    1] file:bundle/org.apache.felix.configadmin-1.0.4.jar

Tym razem Pax URL reprezentowany przez pakunek org.ops4j.pax.url.wrap uruchomiony został poprawnie.

Pora zainstalować moduł EJB openejb-itests-beans-3.0.jar, a tym samym przetestować monitor.

-> install wrap:http://repo1.maven.org/maven2/org/apache/openejb/openejb-itests-beans/3.0/openejb-itests-beans-3.0.jar
Pakunek org.apache.openejb.openejb-itests-beans zmienił stan
Bundle ID: 7
...zainstalowano
-> WARNING: Unable to resolve bundle 7 (org.osgi.framework.BundleException: Unresolved package in bundle 7: package; (package=javax.interceptor))
...rozpoznano moduł EJB

-> ps -l
START LEVEL 1
   ID   State         Level  Location
[   0] [Active     ] [    0] System Bundle
[   1] [Active     ] [    1] file:bundle/org.apache.felix.shell-1.0.1.jar
[   2] [Active     ] [    1] file:bundle/org.apache.felix.shell.tui-1.0.1.jar
[   3] [Active     ] [    1] file:bundle/org.apache.felix.bundlerepository-1.0.3.jar
[   4] [Active     ] [    1] file:c:/projs/sandbox/spring-ejb-monitor-bundle/target/spring-ejb-monitor-bundle-1.0.jar
[   5] [Active     ] [    1] file:c:/apps/pax/pax-url-wrap-0.3.2.jar
[   6] [Active     ] [    1] file:bundle/org.apache.felix.configadmin-1.0.4.jar
[   7] [Installed  ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/openejb/openejb-itests-beans/3.0/openejb-itests-beans-3.0.jar

I na tym mógłbym zakończyć, gdyż monitor poprawnie wykrył moduł EJB. Dalsza część artykułu będzie dotyczyła konfiguracji pakunków do poprawnego uruchomienia modułu EJB jako pakunku OSGi.

Podczas sprawdzania spójności środowiska do uruchomienia pakunku OSGi będącym modułem EJB pojawił się komunikat niedostępności pakietu javax.interceptor. Próba rozwiązania środowiska jest wynikiem działania metody Bundle.findEntries(), która zobowiązana jest do rozwiązania pakunku (stan RESOLVED), jeśli podczas "prześwietlania" był w stanie zainstalowany (INSTALLED).

W trakcie poszukiwania odpowiedzi na problem brakującego pakietu javax.interceptor natrafiłem na ciekawy artykuł dotyczący uruchomienia OpenEJB w ramach OSGi - OpenEjb in Felix, gdzie znalazłem odpowiedź na to i wiele innych pytań. Kolejna, obowiązkowa lektura dla zainteresowanych OSGi w kontekście uruchamiania aplikacji EJB.

Instaluję paczkę geronimo-interceptor_3.0_spec-1.0.1.jar, która jest dystrybuowana jako pakunek OSGi w ramach projektu Apache Geronimo Specs (ponownie, paczka dostępna jest jako zwykły plik jar - niebędący pakunkiem OSGi - w repozytorium Apache Maven 2).

-> install wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-interceptor_3.0_spec/1.0.1/geronimo-interceptor_3.0_spec-1.0.1.jar
Bundle ID: 8
Pakunek org.apache.geronimo.specs.geronimo-interceptor_3.0_spec zmienił stan
-> ...zainstalowano
DEBUG: WIRE: 8.0 -> javax.interceptor -> 8.0
Pakunek org.apache.geronimo.specs.geronimo-interceptor_3.0_spec zmienił stan

Ponownie podchodzę do uruchomienia pakunku openejb-itests-beans-3.0.jar (identyfikator 7)

-> start 7
org.osgi.framework.BundleException: Unresolved package in bundle 7: package; (package=javax.persistence)

I tak kolejno z następnymi pakunkami OSGi: geronimo-interceptor_3.0_spec-1.0.1.jar, geronimo-jpa_3.0_spec-1.1.1.jar, geronimo-ejb_3.0_spec-1.0.jar, geronimo-annotation_1.0_spec-1.1.1.jar, junit-4.5.jar oraz geronimo-jms_1.1_spec-1.1.1.jar.

-> install wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-interceptor_3.0_spec/1.0.1/geronimo-interceptor_3.0_spec-1.0.1.jar
Bundle ID: 8
-> start 8
-> Pakunek org.apache.geronimo.specs.geronimo-interceptor_3.0_spec zmienił stan

-> install wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-jpa_3.0_spec/1.1.1/geronimo-jpa_3.0_spec-1.1.1.jar
Bundle ID: 9
Pakunek org.apache.geronimo.specs.geronimo-jpa_3.0_spec zmienił stan
-> ...zainstalowano
DEBUG: WIRE: 9.0 -> javax.persistence.spi -> 9.0
DEBUG: WIRE: 9.0 -> javax.persistence -> 9.0
DEBUG: WIRE: 9.0 -> javax.sql -> 0
Pakunek org.apache.geronimo.specs.geronimo-jpa_3.0_spec zmienił stan

-> install wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-ejb_3.0_spec/1.0/geronimo-ejb_3.0_spec-1.0.jar
Bundle ID: 10
Pakunek wrap_http___repo1.maven.org_maven2_org_apache_geronimo_specs_geronimo-ejb_3.0_spec_1.0_geronimo-ejb_3.0_spec-1.0.jar zmienił stan
-> ...zainstalowano
DEBUG: WIRE: 10.0 -> javax.ejb -> 10.0
DEBUG: WIRE: 10.0 -> javax.xml.rpc.handler -> 10.0
DEBUG: WIRE: 10.0 -> javax.ejb.spi -> 10.0
DEBUG: WIRE: 10.0 -> javax.transaction -> 0
Pakunek wrap_http___repo1.maven.org_maven2_org_apache_geronimo_specs_geronimo-ejb_3.0_spec_1.0_geronimo-ejb_3.0_spec-1.0.jar zmienił stan

-> install wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1/geronimo-annotation_1.0_spec-1.1.1.jar
Bundle ID: 11
Pakunek org.apache.geronimo.specs.geronimo-annotation_1.0_spec zmienił stan
-> ...zainstalowano
DEBUG: WIRE: 11.0 -> javax.annotation -> 11.0
DEBUG: WIRE: 11.0 -> javax.annotation.security -> 11.0
Pakunek org.apache.geronimo.specs.geronimo-annotation_1.0_spec zmienił stan

-> install wrap:http://repo1.maven.org/maven2/junit/junit/4.5/junit-4.5.jar
Pakunek wrap_http___repo1.maven.org_maven2_junit_junit_4.5_junit-4.5.jar zmienił stan
Bundle ID: 12
...zainstalowano
-> DEBUG: WIRE: 12.0 -> org.junit.experimental.theories.internal -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.runners -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.runners.model -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.experimental.results -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.internal.builders -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.runner.notification -> 12.0
DEBUG: WIRE: 12.0 -> junit.runner -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.internal.runners -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.internal.requests -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.runner -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.internal -> 12.0
DEBUG: WIRE: 12.0 -> org.hamcrest.core -> 12.0
DEBUG: WIRE: 12.0 -> org.hamcrest -> 12.0
DEBUG: WIRE: 12.0 -> org.hamcrest.internal -> 12.0
DEBUG: WIRE: 12.0 -> org.junit -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.internal.runners.model -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.internal.runners.statements -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.experimental.theories.suppliers -> 12.0
DEBUG: WIRE: 12.0 -> junit.extensions -> 12.0
DEBUG: WIRE: 12.0 -> junit.textui -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.experimental.runners -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.runner.manipulation -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.experimental.theories -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.internal.matchers -> 12.0
DEBUG: WIRE: 12.0 -> junit.framework -> 12.0
DEBUG: WIRE: 12.0 -> org.junit.matchers -> 12.0
Pakunek wrap_http___repo1.maven.org_maven2_junit_junit_4.5_junit-4.5.jar zmienił stan

-> install wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-jms_1.1_spec/1.1.1/geronimo-jms_1.1_spec-1.1.1.jar
Bundle ID: 13
Pakunek org.apache.geronimo.specs.geronimo-jms_1.1_spec zmienił stan
-> ...zainstalowano
DEBUG: WIRE: 13.0 -> javax.transaction.xa -> 0
DEBUG: WIRE: 13.0 -> javax.jms -> 13.0
Pakunek org.apache.geronimo.specs.geronimo-jms_1.1_spec zmienił stan

-> ps -l
START LEVEL 1
   ID   State         Level  Location
[   0] [Active     ] [    0] System Bundle
[   1] [Active     ] [    1] file:bundle/org.apache.felix.shell-1.0.1.jar
[   2] [Active     ] [    1] file:bundle/org.apache.felix.shell.tui-1.0.1.jar
[   3] [Active     ] [    1] file:bundle/org.apache.felix.bundlerepository-1.0.3.jar
[   4] [Active     ] [    1] file:c:/projs/sandbox/spring-ejb-monitor-bundle/target/spring-ejb-monitor-bundle-1.0.jar
[   5] [Active     ] [    1] file:c:/apps/pax/pax-url-wrap-0.3.2.jar
[   6] [Active     ] [    1] file:bundle/org.apache.felix.configadmin-1.0.4.jar
[   7] [Installed  ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/openejb/openejb-itests-beans/3.0/openejb-itests-beans-3.0.jar
[   8] [Active     ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-interceptor_3.0_spec/1.0.1/geronimo-interceptor_3.0_spec-1.0.1.jar
[   9] [Resolved   ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-jpa_3.0_spec/1.1.1/geronimo-jpa_3.0_spec-1.1.1.jar
[  10] [Resolved   ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-ejb_3.0_spec/1.0/geronimo-ejb_3.0_spec-1.0.jar
[  11] [Resolved   ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1/geronimo-annotation_1.0_spec-1.1.1.jar
[  12] [Resolved   ] [    1] wrap:http://repo1.maven.org/maven2/junit/junit/4.5/junit-4.5.jar
[  13] [Resolved   ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-jms_1.1_spec/1.1.1/geronimo-jms_1.1_spec-1.1.1.jar

aż w końcu upragnione start 7, które uruchamia pakunek OSGi będący modułem OSGi:

-> start 7
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.interceptor -> 7.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test -> 7.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.entity.cmr.onetoone -> 7.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.entity.cmr.onetomany -> 7.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.entity.cmr -> 7.0
DEBUG: WIRE: 7.0 -> javax.interceptor -> 8.0
DEBUG: WIRE: 7.0 -> javax.sql -> 0
DEBUG: WIRE: 7.0 -> javax.naming -> 0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.entity.cmr.manytomany -> 7.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.entity.cmp2 -> 7.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.mdb -> 7.0
DEBUG: WIRE: 7.0 -> javax.persistence -> 9.0
DEBUG: WIRE: 7.0 -> javax.transaction -> 0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.object -> 7.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.beans -> 7.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.entity.ejbql -> 7.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.stateless -> 7.0
DEBUG: WIRE: 7.0 -> javax.ejb -> 10.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.entity.bmp -> 7.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.stateful -> 7.0
DEBUG: WIRE: 7.0 -> javax.annotation -> 11.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.entity -> 7.0
DEBUG: WIRE: 7.0 -> junit.framework -> 12.0
DEBUG: WIRE: 7.0 -> javax.rmi -> 0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.entity.cmr.cmrmapping -> 7.0
DEBUG: WIRE: 7.0 -> javax.jms -> 13.0
DEBUG: WIRE: 7.0 -> org.apache.openejb.test.entity.cmp -> 7.0
-> Pakunek org.apache.openejb.openejb-itests-beans zmienił stan
Pakunek org.apache.openejb.openejb-itests-beans zmienił stan

Pełny obraz zainstalowanych pakunków poniżej:

-> ps -l
START LEVEL 1
   ID   State         Level  Location
[   0] [Active     ] [    0] System Bundle
[   1] [Active     ] [    1] file:bundle/org.apache.felix.shell-1.0.1.jar
[   2] [Active     ] [    1] file:bundle/org.apache.felix.shell.tui-1.0.1.jar
[   3] [Active     ] [    1] file:bundle/org.apache.felix.bundlerepository-1.0.3.jar
[   4] [Active     ] [    1] file:c:/projs/sandbox/spring-ejb-monitor-bundle/target/spring-ejb-monitor-bundle-1.0.jar
[   5] [Active     ] [    1] file:c:/apps/pax/pax-url-wrap-0.3.2.jar
[   6] [Active     ] [    1] file:bundle/org.apache.felix.configadmin-1.0.4.jar
[   7] [Active     ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/openejb/openejb-itests-beans/3.0/openejb-itests-beans-3.0.jar
[   8] [Active     ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-interceptor_3.0_spec/1.0.1/geronimo-interceptor_3.0_spec-1.0.1.jar
[   9] [Resolved   ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-jpa_3.0_spec/1.1.1/geronimo-jpa_3.0_spec-1.1.1.jar
[  10] [Resolved   ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-ejb_3.0_spec/1.0/geronimo-ejb_3.0_spec-1.0.jar
[  11] [Resolved   ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1/geronimo-annotation_1.0_spec-1.1.1.jar
[  12] [Resolved   ] [    1] wrap:http://repo1.maven.org/maven2/junit/junit/4.5/junit-4.5.jar
[  13] [Resolved   ] [    1] wrap:http://repo1.maven.org/maven2/org/apache/geronimo/specs/geronimo-jms_1.1_spec/1.1.1/geronimo-jms_1.1_spec-1.1.1.jar
-> shutdown
-> Pakunek org.apache.geronimo.specs.geronimo-interceptor_3.0_spec zmienił stan
Pakunek org.apache.openejb.openejb-itests-beans zmienił stan
*DEBUG* Scheduling task Thread[Configuration Updater,5,main]
Pakunek org.apache.felix.configadmin zmienił stan
Pakunek org.ops4j.pax.url.wrap; singleton:=true zmienił stan
Usuniecie pl.jaceklaskowski.spring.internal.Aktywator$1@166aa18

Kompletny projekt spring-ejb-monitor-bundle dostępny jest do pobrania jako spring-ejb-monitor-bundle.zip.

Osobiste