Wczytując się w pRaSSówkę (wspaniałe określenie dla zbioru RSS za Polskim The Daily WTF) i posiłkując się Google natrafiłem na ciekawe dokonania w dziedzinie OSGi i tworzenia aplikacji webowych z Wicket. Trafiłem na Open Participation Software for Java, gdzie mnóstwo ciekawego oprogramowania związanego z OSGi, m.in. Pax Wicket (o czym nie będę jeszcze pisał, ale nie mogłem się oprzeć, aby już nie wspomnieć).
Projektem, który przyciągnął moją uwagę był Pax Web, czyli OSGi Http Service ze wsparciem dla wielu elementów specyfikacji Servlets, w tym i filtrów. Dlaczego wymieniłem filtry jako istotne? Przypominam, że Wicket pracuje oparty o filtr lub servlet, a w mojej przykładowej aplikacji skorzystałem z filtra. Stąd padło, że za dzisiejszy cel postanowiłem obrać uruchomienie demonstracyjnej aplikacji Wicketa z Pax Web.
Po zapoznaniu się z dokumentacją Pax Web (wyjątkowo niewiele acz treściwie) przyszło mi zdecydować o środowisku uruchomieniowym OSGi. Wybrałem Apache Felix. Poza nim miałem do wyboru Knoplerfisha bądź Eclipse Equinox. Z bardziej osobistych niż technicznych pobódek wybrałem Felix. Pobrałem Felix 1.0.3.
Rozpocząłem od uruchomienia Pax Web na Felixie. Uruchomienie Felixa i instalacja opisane są w Apache Felix Usage Documentation.
jlaskowski@dev /cygdrive/c/apps/felixPodczas uruchomienia Felixa, podawana jest nazwa profilu, która jest nazwą zbioru zainstalowanych pakunków tak, że kolejne uruchomienie Felixa z tą nazwą zainstaluje i uruchomi dokładnie te pakunki zawarte w zadanym profilu. W praktyce ów profil jest po prostu katalogiem pakunków w katalogu domowym użytkownika.
$ java -jar bin/felix.jar
Welcome to Felix.
=================
Enter profile name: wicket
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
-> version
1.0.3
-> ps
START LEVEL 1
ID State Level Name
[ 0] [Active ] [ 0] System Bundle (1.0.3)
[ 1] [Active ] [ 1] Apache Felix Shell Service (1.0.0)
[ 2] [Active ] [ 1] Apache Felix Shell TUI (1.0.0)
[ 3] [Active ] [ 1] Apache Felix Bundle Repository (1.0.2)
jlaskowski@dev /cygdrive/c/apps/felixUruchomienie Pax Web to wykonanie poleceń install oraz start z pobranym pax-web-service (pax-web-service-0.3.1.jar)
$ ls -l c\:/Documents\ and\ Settings/jlaskowski/.felix/wicket/
total 0
d---------+ 2 jlaskowski None 0 Mar 2 23:02 bundle0
d---------+ 3 jlaskowski None 0 Mar 2 23:02 bundle1
d---------+ 3 jlaskowski None 0 Mar 2 23:02 bundle2
d---------+ 3 jlaskowski None 0 Mar 2 23:02 bundle3
-> install file:/C:/apps/pax-web/pax-web-service-0.3.1.jarI tutaj pierwsza niespodzianka. Niespełniona zależność od pakietu org.osgi.service.http. Dzięki Creating a jetty based OSGi HttpService for apache felix z dnia 29.02.2008 (!) dowiedziałem się, że potrzebuję pobrać i zainstalować również pakunek OSGi compendium API's Feliksa - org.osgi.compendium-1.0.0.jar.
Bundle ID: 4
-> start 4
org.osgi.framework.BundleException: Unresolved package in bundle 4:
package; (&(package=org.osgi.service.http)(version>=1.0.0)(!(version>=2.0.0)))
-> install file:/C:/apps/felix/bundle/org.osgi.compendium-1.0.0.jarTym razem Pax Web rozpoczął pracę bez zgłaszania braku zależności i Jetty 6.1 ruszył na porcie 8080.
Bundle ID: 5
-> start 5
DEBUG: WIRE: 5.0 -> javax.servlet.http -> 4.0
DEBUG: WIRE: 5.0 -> javax.servlet -> 4.0
DEBUG: WIRE: 5.0 -> javax.xml.parsers -> 0
DEBUG: WIRE: 5.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 4.0 -> javax.servlet.http -> 4.0
DEBUG: WIRE: 4.0 -> org.xml.sax -> 0
DEBUG: WIRE: 4.0 -> javax.servlet.resources -> 4.0
DEBUG: WIRE: 4.0 -> org.osgi.service.http -> 5.0
DEBUG: WIRE: 4.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 4.0 -> org.osgi.service.cm -> 5.0
DEBUG: WIRE: 4.0 -> javax.servlet -> 4.0
DEBUG: WIRE: 4.0 -> org.xml.sax.helpers -> 0
DEBUG: WIRE: 4.0 -> javax.xml.parsers -> 0
DEBUG: WIRE: 4.0 -> org.osgi.util.tracker -> 0
DEBUG: WIRE: 4.0 -> javax.servlet.jsp.resources -> 4.0
DEBUG: WIRE: 4.0 -> javax.net.ssl -> 0
DEBUG: WIRE: 4.0 -> org.ops4j.pax.web.service -> 4.0
-> start 4
2008-03-02 23:42:54.096::INFO: Logging to STDERR via org.mortbay.log.StdErrLog
2008-03-02 23:42:54.142::INFO: jetty-6.1.x
2008-03-02 23:42:54.174::INFO: Started SocketConnectorWrapper@0.0.0.0:8080
Pytanie jakie sobie zadawałem, to: Dobrze mam uruchomionego Jetty, ale co z moją aplikacją? Jak mogę ją zainstalować? Każdy kto "dotknie" OSGi wie, że cokolwiek nie pojawi się w tym środowisku musi być wprost lub niewprost pakunkiem. Oznaczało to, że aplikacja webowa musiałaby w jakiś sposób stać się pakunkiem. Nie jest to wyczyn sam w sobie, bo opisywałem to już w Pakunki OSGi w projekcie wielomodułowym Apache Maven 2 z maven-bundle-plugin czy Tworzenie pakietów OSGi z Apache Maven 2, ale jak sprawić, aby pakunek aplikacji webowej był właśnie aplikacją webową i to jeszcze rozpoznaną przez właśnie uruchomionego Jetty. Na pewno musiałaby pojawić się jakaś zależność między nimi, ale jak ją określić?!
Z pomocą przychodzi Pax Web Extender - War, czyli kolejny pakunek z OPS4J, który sprawia, że uruchomienie aplikacji webowych staje się trywialne. Wystarczy pobrać pax-web-ex-war-0.3.0.jar i uruchomić.
-> install file:/C:/apps/pax-web/pax-web-ex-war-0.3.0.jarPakunek Pax Web Extender uruchomiony. A teraz co? Znowu dokumentacja, a tam instrukcja jak bez żadnych modyfikacji do aplikacji webowej uruchomić ją na OSGi, czyli Pax URL - war. Kolejny pakunek do uruchomienia.
Bundle ID: 6
-> start 6
DEBUG: WIRE: 6.0 -> javax.servlet.http -> 4.0
DEBUG: WIRE: 6.0 -> javax.servlet -> 4.0
DEBUG: WIRE: 6.0 -> org.xml.sax -> 0
DEBUG: WIRE: 6.0 -> org.osgi.service.http -> 5.0
DEBUG: WIRE: 6.0 -> javax.xml.parsers -> 0
DEBUG: WIRE: 6.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 6.0 -> org.w3c.dom -> 0
DEBUG: WIRE: 6.0 -> org.osgi.util.tracker -> 0
DEBUG: WIRE: 6.0 -> org.ops4j.pax.web.service -> 4.0
-> install file:/C:/apps/pax-web/pax-url-war-0.2.1.jarTeraz wystarczy po prostu uruchomić aplikację webową, np. http://repo1.maven.org/maven2/org/apache/wicket/wicket-examples/1.3.1/wicket-examples-1.3.1.war.
Bundle ID: 7
-> start 7
DEBUG: WIRE: 7.0 -> org.osgi.service.url -> 0
DEBUG: WIRE: 7.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 7.0 -> org.ops4j.pax.url.war -> 7.0
DEBUG: WIRE: 7.0 -> javax.xml.transform.stream -> 0
DEBUG: WIRE: 7.0 -> org.osgi.service.cm -> 5.0
DEBUG: WIRE: 7.0 -> javax.xml.transform -> 0
DEBUG: WIRE: 7.0 -> javax.net.ssl -> 0
-> installAplikacja wydaje się uruchomiona. Pozostaje sprawdzić ją w działaniu. Ale moment, a jaki adres aplikacji? Chciałoby się, aby było to podobnie jak to ma miejsce w typowym środowisku kontenera servletów, gdzie nazwa pliku wskazuje na nazwę kontekstu. W tym przypadku tak nie jest i nazwa aplikacji obliczana jest na podstawie parametru przekazanego po war, czyli w tym przypadku będzie to:
war:http://repo1.maven.org/maven2/org/apache/wicket/wicket-examples/1.3.1/wicket-examples-1.3.1.war
Bundle ID: 8
-> start 8
DEBUG: WIRE: 8.0 -> javax.servlet.http -> 4.0
DEBUG: WIRE: 8.0 -> javax.sql.rowset -> 0
DEBUG: WIRE: 8.0 -> javax.xml.namespace -> 0
DEBUG: WIRE: 8.0 -> javax.crypto -> 0
DEBUG: WIRE: 8.0 -> javax.xml.transform -> 0
DEBUG: WIRE: 8.0 -> javax.naming -> 0
DEBUG: WIRE: 8.0 -> javax.servlet -> 4.0
DEBUG: WIRE: 8.0 -> javax.xml.parsers -> 0
DEBUG: WIRE: 8.0 -> javax.management.modelmbean -> 0
DEBUG: WIRE: 8.0 -> javax.xml.transform.stream -> 0
DEBUG: WIRE: 8.0 -> javax.swing -> 0
DEBUG: WIRE: 8.0 -> javax.management -> 0
DEBUG: WIRE: 8.0 -> javax.swing.border -> 0
DEBUG: WIRE: 8.0 -> javax.management.remote -> 0
DEBUG: WIRE: 8.0 -> javax.swing.event -> 0
DEBUG: WIRE: 8.0 -> org.xml.sax.helpers -> 0
DEBUG: WIRE: 8.0 -> javax.swing.tree -> 0
DEBUG: WIRE: 8.0 -> javax.swing.table -> 0
DEBUG: WIRE: 8.0 -> javax.sql -> 0
DEBUG: WIRE: 8.0 -> javax.crypto.spec -> 0
DEBUG: WIRE: 8.0 -> javax.rmi.CORBA -> 0
DEBUG: WIRE: 8.0 -> javax.transaction -> 0
DEBUG: WIRE: 8.0 -> javax.swing.text -> 0
DEBUG: WIRE: 8.0 -> org.xml.sax -> 0
DEBUG: WIRE: 8.0 -> javax.imageio -> 0
DEBUG: WIRE: 8.0 -> org.w3c.dom -> 0
DEBUG: WIRE: 8.0 -> javax.xml.transform.dom -> 0
DEBUG: WIRE: 8.0 -> javax.rmi -> 0
...
INFO - WebApplication - [TemplateApplication] Started Wicket in development mode
********************************************************************
*** WARNING: Wicket is running in DEVELOPMENT mode. ***
*** ^^^^^^^^^^^ ***
*** Do NOT deploy to your live server(s) without changing this. ***
*** See Application#getConfigurationType() for more information. ***
********************************************************************
...
->
http://localhost:8080/http___repo1.maven.org_maven2_org_apache_wicket_wicket-examples_1.3.1_wicket-examples-1.3.1.warPytanie tylko skąd o tym się dowiedzieć, bo przecież mimo dokumentacji Instructions file syntax nie wyliczyłem jej zamieniając odpowiednie znaki.
Nazwa kontekstu kryje się w Bundle-SymbolicName pakunku. Sprawdzam jaką konfigurację ma pakunek o identyfikatorze 8, który jest zainstalowaną aplikacją.
-> headers 8Interesująca nas właściwość to Bundle-SymbolicName.
Bundle 8
--------
Generated-By-Ops4j-Pax-From =
http://repo1.maven.org/maven2/org/apache/wicket/wicket-examples/1.3.1/wicket-examples-1.3.1.war
Bundle-ClassPath = .,WEB-INF/classes,WEB-INF/lib/...
Tool = Bnd-unknown version
Created-By = 1.5.0_14 (Sun Microsystems Inc.)
Bnd-LastModified = 1204529294312
WAR-URL =
http://repo1.maven.org/maven2/org/apache/wicket/wicket-examples/1.3.1/wicket-examples-1.3.1.war
Built-By = fb
Originally-Created-By = Apache Maven
Bundle-Version = 0
Build-Jdk = 1.5.0_13
Manifest-Version = 1.0
Bundle-ManifestVersion = 2
Archiver-Version = Plexus Archiver
Import-Package = javax.activation;resolution:=...
Bundle-SymbolicName =
http___repo1.maven.org_maven2_org_apache_wicket_wicket-examples_1.3.1_wicket-examples-1.3.1.war
Pozostaje sprawdzić instalację mojej demonstracyjnej aplikacji webowej - wicket-demo.
-> install war:file:/c:/projs/sandbox/wicket-demo/target/wicket-demo-1.0-SNAPSHOT.warNiestety z jakiś nieznanych mi powodów moja aplikacja nie pozwoliła się uruchomić. Zostawiam to na później.
Bundle ID: 10
-> start 10
DEBUG: WIRE: 10.0 -> javax.servlet.http -> 4.0
DEBUG: WIRE: 10.0 -> javax.sql.rowset -> 0
DEBUG: WIRE: 10.0 -> javax.xml.namespace -> 0
DEBUG: WIRE: 10.0 -> javax.crypto -> 0
DEBUG: WIRE: 10.0 -> javax.xml.transform -> 0
DEBUG: WIRE: 10.0 -> javax.naming -> 0
DEBUG: WIRE: 10.0 -> javax.servlet -> 4.0
DEBUG: WIRE: 10.0 -> javax.xml.parsers -> 0
DEBUG: WIRE: 10.0 -> javax.xml.transform.stream -> 0
DEBUG: WIRE: 10.0 -> javax.management.modelmbean -> 0
DEBUG: WIRE: 10.0 -> javax.swing -> 0
DEBUG: WIRE: 10.0 -> javax.management -> 0
DEBUG: WIRE: 10.0 -> javax.swing.border -> 0
DEBUG: WIRE: 10.0 -> javax.transaction.xa -> 0
DEBUG: WIRE: 10.0 -> javax.management.remote -> 0
DEBUG: WIRE: 10.0 -> javax.swing.event -> 0
DEBUG: WIRE: 10.0 -> org.xml.sax.helpers -> 0
DEBUG: WIRE: 10.0 -> javax.swing.tree -> 0
DEBUG: WIRE: 10.0 -> javax.swing.table -> 0
DEBUG: WIRE: 10.0 -> javax.management.openmbean -> 0
DEBUG: WIRE: 10.0 -> javax.sql -> 0
DEBUG: WIRE: 10.0 -> javax.crypto.spec -> 0
DEBUG: WIRE: 10.0 -> javax.rmi.CORBA -> 0
DEBUG: WIRE: 10.0 -> javax.transaction -> 0
DEBUG: WIRE: 10.0 -> javax.swing.text -> 0
DEBUG: WIRE: 10.0 -> org.xml.sax -> 0
DEBUG: WIRE: 10.0 -> javax.imageio -> 0
DEBUG: WIRE: 10.0 -> org.w3c.dom -> 0
DEBUG: WIRE: 10.0 -> javax.rmi -> 0
-> headers 10
Bundle 10
---------
Generated-By-Ops4j-Pax-From =
file:/c:/projs/sandbox/wicket-demo/target/wicket-demo-1.0-SNAPSHOT.war
Bundle-ClassPath = .,WEB-INF/classes,WEB-INF/lib/...
Tool = Bnd-unknown version
Created-By = 1.5.0_14 (Sun Microsystems Inc.)
Bnd-LastModified = 1204531073078
WAR-URL =
file:/c:/projs/sandbox/wicket-demo/target/wicket-demo-1.0-SNAPSHOT.war
Built-By = jlaskowski
Originally-Created-By = Apache Maven
Bundle-Version = 0
Build-Jdk = 1.5.0_14
Manifest-Version = 1.0
Bundle-ManifestVersion = 2
Archiver-Version = Plexus Archiver
Import-Package = javax.activation;resolution:=...
Bundle-SymbolicName =
file__c__projs_sandbox_wicket-demo_target_wicket-demo-1.0-SNAPSHOT.war
-> shutdownW dowód wdzięczności zgłosiłem błąd - (PAXWEB-84) NPE after a web app (bundle) is stopped, który został już naprawiony (!) To nazywa się współpraca.
-> INFO - Application - [EchoApplication] destroy: Wicket JMX initializer
INFO - Application - [GuestBookApplication] destroy: Wicket JMX initializer
INFO - Application - [FormInputApplication] destroy: Wicket JMX initializer
INFO - Application - [UnicodeConverterApplication] destroy: Wicket JMX initializer
INFO - Application - [SignInApplication] destroy: Wicket JMX initializer
INFO - Application - [PrototypeApplication] destroy: Wicket JMX initializer
INFO - Application - [ImagesApplication] destroy: Wicket JMX initializer
INFO - Application - [AjaxApplication] destroy: Wicket JMX initializer
INFO - Application - [HangmanApplication] destroy: Wicket JMX initializer
INFO - Application - [StatelessApplication] destroy: Wicket JMX initializer
INFO - Application - [BreadCrumbApplication] destroy: Wicket JMX initializer
INFO - Application - [NiceUrlApplication] destroy: Wicket JMX initializer
INFO - Application - [MyAuthenticatedWebApplication] destroy: Wicket JMX initializer
INFO - Application - [ExampleApplication] destroy: Wicket JMX initializer
INFO - Application - [GuiceApplication] destroy: Wicket JMX initializer
INFO - Application - [CaptchaApplication] destroy: Wicket JMX initializer
INFO - Application - [RolesApplication] destroy: Wicket JMX initializer
INFO - Application - [LibraryApplication] destroy: Wicket JMX initializer
INFO - Application - [HelloBrowserApplication] destroy: Wicket JMX initializer
INFO - Application - [VelocityTemplateApplication] destroy: Wicket JMX initializer
INFO - Application - [WizardApplication] destroy: Wicket JMX initializer
INFO - Application - [WicketExamplesMenuApplication] destroy: Wicket JMX initializer
INFO - Application - [ComponentReferenceApplication] destroy: Wicket JMX initializer
INFO - Application - [NavomaticApplication] destroy: Wicket JMX initializer
INFO - Application - [DatesApplication] destroy: Wicket JMX initializer
INFO - Application - [Application] destroy: Wicket JMX initializer
INFO - Application - [StockQuoteApplication] destroy: Wicket JMX initializer
INFO - Application - [NestedApplication] destroy: Wicket JMX initializer
INFO - Application - [PubApplication] destroy: Wicket JMX initializer
INFO - Application - [RepeaterApplication] destroy: Wicket JMX initializer
INFO - Application - [UploadApplication] destroy: Wicket JMX initializer
INFO - Application - [FramesApplication] destroy: Wicket JMX initializer
INFO - Application - [CustomResourceLoadingApplication] destroy: Wicket JMX initializer
INFO - Application - [LinkomaticApplication] destroy: Wicket JMX initializer
INFO - Application - [HelloWorldApplication] destroy: Wicket JMX initializer
INFO - Application - [SignIn2Application] destroy: Wicket JMX initializer
INFO - Application - [TemplateApplication] destroy: Wicket JMX initializer
INFO - Application - [EncodingsApplication] destroy: Wicket JMX initializer
INFO - Application - [PubApplication] destroy: Wicket JMX initializer
2008-03-03 00:01:28.468:/http___repo1.maven.org_maven2_org_apache_wicket_wicket-examples_1.3.1_wicket-example
INFO - XmlWebApplicationContext - Closing application context [Root WebApplicationContext]
INFO - DefaultListableBeanFactory - Destroying singletons in {org.springframework.beans.factory.support.Defa
f BeanFactory hierarchy}
Brak komentarzy:
Prześlij komentarz