Tworzenie pakietów OSGi z Apache Maven 2

Z Jacek Laskowski - Wiki Projektanta Java EE

Rozczytując się w artykułach dotyczących OSGi z serii Getting Started with OSGi postanowiłem je trochę usprawnić i tym samym zachęcić większą ilość osób do popróbowania się z tematem. Postanowiłem spróbować sił tworzenia pakietów OSGi z Apache Maven 2.0.5 , aby zautomatyzować prace przy projekcie. Podekscytowany łatwością pracy z OSGi, jedyną sprawą do rozwiązania było zautomatyzowanie kompilacji, budowania i instalacji. Brzmi znajomo?! To właśnie dokładnie te zadania, dla których powstał M2.

Spis treści

Warunki początkowe

Poprawnie zainstalowany Eclipse IDE 3.3M5 oraz Apache Maven 2.0.5 (szczegóły ich instalacji pozostawiam ich dokumentacji dostępnych na ich stronach domowych).

Stworzenie przestrzeni roboczej projektu

Wykonanie polecenia mvn archetype:create z odpowiednimi parametrami doskonale obsłuży temat.

    mvn archetype:create -DgroupId=pl.jaceklaskowski.osgi -DartifactId=article

Przygotowanie projektu do pracy z Eclipse IDE

Tym razem skorzystamy z zadania eclipse:

    mvn eclipse:eclipse

Konfiguracja przestrzeni roboczej do pracy z M2 (zmienna M2_REPO)

Definiujemy zmienną M2_REPO dla przestrzeni roboczej (ang. workspace), z którą związany jest nasz projekt (jest to zmienna pozwalająca na korzystanie z bibliotek w repozytorium M2).

W moim przypadku, przestrzeń robocza Eclipse to c:/projs/sandbox.

    mvn -Declipse.workspace=c:/projs/sandbox eclipse:add-maven-repo

Instalacja wtyczki M2 dla Eclipe

Instalujemy wtyczkę M2 dla Eclipse zgodnie z wytycznymi prezentowanymi w krótkim filmie Installing Maven 2.0 plugin for Eclipse. Sprowadza się to do zdefiniowania strony wtyczki do pobrania w Eclipse jako http://m2eclipse.codehaus.org/.

Grafika:eclipse-maven2-plugin.png

Import projektu do Eclipse

Import projektu to wybranie menu File->Import->Existing Projects into Workspace i wskazanie na katalog stworzony przez M2.

Aktywacja obsługi M2 w projekcie

Uaktywniamy obsługę M2 w projekcie poprzez menu kontekstowe projektu Maven2->Enable.

Grafika:eclipse-maven2-plugin-enable.PNG

Dodanie zależności projektu od biblioteki OSGi

Istnieją dwa podejścia do tej kwestii.

Sposób 1 (prostszy, ale niepreferowany): Wybieramy menu Maven2->Add Dependency z menu kontekstowego

Grafika:eclipse-maven2-adddependency.png

, wpisujemy osgi i wybieramy org.osgi osgi_R4_core, a następnie wciskamy przycisk OK.

Grafika:eclipse-maven2-osgidep.png

Plik pom.xml powinien zawierać następującą sekcję (będzie brakowało wskazania na repozytorium, więc ważne jest, aby wprowadzić to ręcznie):

    <dependency>
      <groupId>org.osgi</groupId>
      <artifactId>osgi_R4_core</artifactId>
      <version>1.0</version>
    </dependency>
    ...
    <repositories>
      <repository>
        <id>central</id>
        <name>iBiblio Maven Legacy Repo</name>
        <url>http://www.ibiblio.org/maven</url>
        <layout>legacy</layout>
      </repository>
    </repositories>

Sposób 2 (preferowany): Instalujemy wersję biblioteki OSGi z dystrybucji Eclipse 3.3M5 wierząc, że tym samym zapobiegniemy ewentualnym problemom związanym z nieaktualnością w/w biblioteki oraz unikniemy konieczności deklarowania repozytorium. Wykonujemy kroki opisane w dokumencie Guide to installing 3rd party JARs, tj.

   mvn install:install-file -Dfile=c:/apps/eclipse/plugins/org.eclipse.osgi_3.3.0.v20070208.jar -DgroupId=org.eclipse -DartifactId=osgi -Dversion=3.3.0.v20070208 -Dpackaging=jar

UWAGA: U mnie ścieżka do Eclipse IDE to c:/apps/eclipse. Koniecznie należy ją zmienić, aby odpowiadała konfiguracji lokalnej.

Sprawdzenie działania konsoli OSGi

Sprawdzamy działanie konsoli OSGi na bazie właśnie zainstalowanej biblioteki OSGi.

    $ java -jar c\:/.m2/org/eclipse/osgi/3.3.0.v20070208/osgi-3.3.0.v20070208.jar -console

    osgi> exit

Pojawienie się osgi> wskazuje na poprawne uruchomienie konsoli. Wyjście poprzez wydanie polecenia exit, albo close (preferowane).

Utworzenie klasy pakietu OSGi

Po konfiguracji projektu w Eclipse tworzymy pierwszy pakiet OSGi (ang. OSGi bundle) zgodnie z wytycznymi w rozpoczynającym serię Getting started with OSGi artykule Getting started with OSGi: Your first bundle.

Jak tworzyć klasy itp, czyli podstawy pracy z Eclipse pozostawiam (doczytujemy w) dokumentacji.

Utworzenie MANIFEST.MF

Tworzymy plik manifestu MANIFEST.MF w katalogu src/main/resources i wskazujemy go jako obowiązujący w naszym projekcie zarządzanym przez M2. Proces dołączania pliku MANIFEST.MF do projektu opisano w Using your own manifest file.

UWAGA: W naszym projekcie korzystamy z pakietu pl.jaceklaskowski.osgi podczas, gdy MANIFEST.MF nie zawiera specyfikacji pakietu. Koniecznie należy to zmodyfikować.

Plik pom.xml projektu powinien wyglądać następująco (dobrze jest również zmienić wartość znacznika version na 1.0):

    <?xml version="1.0"?>
    <project>
      <modelVersion>4.0.0</modelVersion>
      <groupId>pl.jaceklaskowski.osgi</groupId>
      <artifactId>article</artifactId>
      <name>article</name>
      <version>1.0</version>
      <url>http://maven.apache.org</url>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
              <archive>
                <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
              </archive>
            </configuration>
          </plugin>
        </plugins>
      </build>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>org.eclipse</groupId>
          <artifactId>osgi</artifactId>
          <version>3.3.0.v20070208</version>
        </dependency>
      </dependencies>
    </project>

Definicja nowego generatora Eclipse w projekcie

Definiujemy nowy generator (ang. builder) dla projektu w Properties->Builders, który będzie typu m2 build z zadaniem (ang. goal) jar. Automatycznie zostanie utworzona definicja programu zewnętrznego w menu Run->External Tools lub na pasku narzędziowym, co znacznie usprawnia budowanie pliku dystrybucyjnegopakietu (pliku jar).

Grafika:eclipse-maven2-newbuilder.png

Po zatwierdzeniu Eclipse wykona poszczególne generatory, w tym i m2 build z zadaniem jar i w ten sposób utworzymy nasz pierwszy pakiet OSGi (!)

    [WARN] Unable to get resource from repository central (http://repo1.maven.org/maven2)
    [INFO] ----------------------------------------------------------------------------
    [INFO] Building article
    [INFO]    task-segment: [jar:jar]
    [INFO] ----------------------------------------------------------------------------
    [INFO] Searching repository for plugin with prefix: 'jar'.
    [INFO] jar:jar
    [INFO] Building jar: C:\projs\sandbox\article\target\article-1.0.jar
    [INFO] ----------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL

Instalacja pakietu

Wykonanie tego kroku jest analogiczne do opisanego w artykule. Podaję go dla kompletności.

    jlaskowski@dev /cygdrive/c/projs/sandbox/article
    $ java -jar c\:/.m2/org/eclipse/osgi/3.3.0.v20070208/osgi-3.3.0.v20070208.jar -console
    
    osgi> install file:target/article-1.0.jar
    Bundle id is 1
    
    osgi> ss
    
    Framework is launched.
    
    id      State       Bundle
    0       ACTIVE      org.eclipse.osgi_3.3.0.v20070208
    1       INSTALLED   HelloWorld_1.0.0
    
    osgi> close

Ponowne uruchomienie środowiska uruchomieniowego OSGi przywróci stan pakietów do ostatnio zapisanego, czyli nasz pakiet powinien być w stanie zainstalowany (INSTALLED - więcej o stanach pakietu w dokumentacji org.osgi.framework.Bundle).

Informacja o stanie środowiska zapisywana jest w katalogu configuration, w którym znajduje się biblioteka OSGi, czyli w repozytorium M2 - C:\.m2\org\eclipse\osgi\3.3.0.v20070208 (u mnie katalog repozytorium lokalnego M2 jest c:\.m2). Skasowanie katalogu configuration to skasowanie stanu poprzednio uruchomionych sesji.

Przyjrzyjmy się poniższej sesji, aby docenić kolejne zalety stosowania OSGi. Proszę zauważyć stan pakietów.

UWAGA: Korzystamy z polecenia close zamiast exit. Pierwszy zatrzymuje środowisko i wychodzi (miękkie zamknięcie) podczas, gdy exit zatrzymuje środowisko wywołując System.exit (twarde zamknięcie).

    jlaskowski@dev /cygdrive/c/projs/sandbox/article
    $ java -jar c\:/.m2/org/eclipse/osgi/3.3.0.v20070208/osgi-3.3.0.v20070208.jar -console
    
    osgi> ss
    
    Framework is launched.
    
    id      State       Bundle
    0       ACTIVE      org.eclipse.osgi_3.3.0.v20070208
    
    osgi> install file:target/article-1.0.jar
    Bundle id is 1
    
    osgi> ss
    
    Framework is launched.
    
    id      State       Bundle
    0       ACTIVE      org.eclipse.osgi_3.3.0.v20070208
    1       INSTALLED   HelloWorld_1.0.0
    
    osgi> start 1
    Hello EclipseZone Readers!
    
    osgi> close
    
    Goodbye EclipseZone Readers!
    
    jlaskowski@dev /cygdrive/c/projs/sandbox/article
    $ java -jar c\:/.m2/org/eclipse/osgi/3.3.0.v20070208/osgi-3.3.0.v20070208.jar -console
    Hello EclipseZone Readers!
    
    osgi> ss
    
    Framework is launched.
    
    id      State       Bundle
    0       ACTIVE      org.eclipse.osgi_3.3.0.v20070208
    1       ACTIVE      HelloWorld_1.0.0
    
    osgi> stop 1
    Goodbye EclipseZone Readers!
    
    osgi> close
    
    
    jlaskowski@dev /cygdrive/c/projs/sandbox/article
    $ java -jar c\:/.m2/org/eclipse/osgi/3.3.0.v20070208/osgi-3.3.0.v20070208.jar -console
    
    osgi> ss
    
    Framework is launched.
    
    id      State       Bundle
    0       ACTIVE      org.eclipse.osgi_3.3.0.v20070208
    1       RESOLVED    HelloWorld_1.0.0
    
    osgi> close

Błędy Eclipse IDE 3.3M5 i WTP 2.0M4

W trakcie pracy z projektem natrafiłem na kilka problemów ze względu na brak zgodności zainstalowanej wtyczki WTP 2.0M4 i wersji Eclipse IDE 3.3M5.

java.lang.NullPointerException

Wyłącz Enable drag and drop of text w General->Editors->Text Editors przy WTP 2.0M4 ([news.eclipse.webtools Re: Bug with WTP 2.0 M4 vs. Eclipse 3.3M5?]), aby pozbyć się błędu związanego z edycją plików obsługiwanych przez WTP (xhtml, html, xml).

!MESSAGE Unable to create editor ID org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorPart: An unexpected exception was thrown.
!STACK 0
java.lang.NullPointerException
	at org.eclipse.ui.texteditor.AbstractTextEditor.getAction(AbstractTextEditor.java:4619)
	at org.eclipse.wst.xml.ui.internal.tabletree.XMLTableTreeActionBarContributor.getAction(XMLTableTreeActionBarContributor.java:210)
	at org.eclipse.wst.xml.ui.internal.tabletree.XMLTableTreeActionBarContributor.setActiveEditor(XMLTableTreeActionBarContributor.java:198)
	at org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorActionBarContributor.activateSourcePage(XMLMultiPageEditorActionBarContributor.java:54)
	at org.eclipse.wst.xml.ui.internal.tabletree.SourceEditorActionBarContributor.setActivePage(SourceEditorActionBarContributor.java:168)

Zobacz https://bugs.eclipse.org/bugs/show_bug.cgi?id=141013. Mimo, że jest poprawiony to znowu się pojawił (ang. regression bug?). Rozwiązanie to zmiana widoku, w którym otwiera się plik, np. Package Explorer na Navigator.

Osobiste