O planach związanych z wykładem pisałem w poprzednim wpisie - Wykład akademicki na PWSZ w Tarnowie - 29.11 od 9:30 do 18:00 i jak to w życiu bywa - plany swoje, a życie swoje.
Mając niemałe obawy o zakres merytoryczny wykładu, postanowiłem przelecieć większość z tego, co nazwałbym interesującym wycinkiem mojej wiedzy technicznej, aby choć na moment móc podzielić się czymś nowym z uczestnikami. Sądziłem, że uczestnicy większość tematów mają już za sobą, więc pojawiły się produkty IBM, o których, jeśli słyszano, to niewiele praktycznie i choć one gwarantowały mi możliwość przekazania czegoś niezbadanego. Po ostatnich szkoleniach z IBM WebSphere BPM z programowania i administracji nie miałem złudzeń, że w ostateczności wejdę na niskopoziomowe "rozbieranie" trzewi WPS V7 czy WAS V8. Sądziłem, że coś w końcu będzie wartościowe, aby spędzić kilka chwil i wziąć udział w wykładzie.
Do ostatniej chwili nie byłem pewien, czy dobrze dopasowałem tematykę. Czym bliżej wystąpienia, tym nachodziła mnie większa ochota, aby w niej pomajstrować. Wziąłem kilka książek, aby tam znaleźć coś unikatowego, a jednocześnie wartościowego, zabrałem się za lekturę podręczników, itp. Zacząłem odczuwać tremę przed niewstrzeleniem się w oczekiwania (które mogły być podkręcone moimi wycieczkami w różne strony rozwiązań javowych).
Zaplanowałem całkiem pokaźny bagaż tematyczny (vide poprzedni wpis z harmonogramem) i wszystko miało odbyć się bez nawet najdrobniejszego slajdu, aby ostatecznie okazać się, że z grupy około 50 osób niewiele ponad 3 osoby miały styczność z Javą (!) To było chyba najbardziej dla mnie szokujące. Ja tu zmagałem się z JEE6 i poziomy wyżej, przy SCA i BPEL, a okazało się, że należało zacząć od samego początku - samego poznawania języka Java. Trafiłem do mekki programistów C!
Jako, że przygotowany byłem na wprowadzenie do dostępu do bazy danych, przez JDBC, Hibernate, Spring Framework, Hibernate+Spring Framework, JPA i EJB, w zasadzie byłem gotowy zacząć pierwsze kilka kwadransów na wprowadzenie do Javy - bez wycieczek w programowanie OO. Pozostałem przy prostych konstrukcjach typu wyświetl na ekran, pobierz z ekranu i na tym się skończyło wprowadzenie.
Zabrałem się za dostęp do bazy danych. MySQL sprawowało się znakomicie, a NetBeans IDE (wersja rozwojowa z dnia poprzedniego) całkiem sprawnie uwijała się przy składaniu kolejnych części aplikacji. Tutaj i Java Tutorial się przydał, aby pokazać, w jaki sposób można przejść podobną ścieżkę, którą właśnie przechodziliśmy (gdyby komuś przyszło do głowy odtworzyć nasze wspólne poczyniania samodzielnie). Od czasu do czasu NetBeans IDE czkał zamrażając się na dobre kilkadziesiąt sekund, co złożyłem na braku dostępu do Sieci i jego młodzieńczego wieku (w końcu to wersja rozwojowa). Na moment przełączyłem się do Eclipse IDE, ale i jemy przypomniało się, aby zaktualizować/sprawdzić coś w Sieci i zamarzł. Wróciłem do NetBeans IDE.
Na zakończenie pierwszego bloku wykładów pokazałem coś, co określiłbym - impress me. Skąd wzięło się to cudo? Chcąc dopasować się do oczekiwań uczestników, zapytałem, co jeszcze mógłbym im pokazać i padło "Zaimponuj nam czymś w Javie, co sprawiłoby, że zechcielibyśmy się nią zająć". Od razu zabrałem się za...Clojure.
Pewnie pomyślisz sobie, zwłaszcza jeśli znasz mój poziom znajomości tego języka, że to był najgorszy z możliwych wyborów. Co to, to nie. Zdecydowanie NIE. Ja wręcz uważam, że właśnie tym najbardziej ująłem ich za serce i przy tym właśnie temacie miałem wrażenie zdobyłem ich największą uwagę. Takie odniosłem wrażenie i jeśli jakikolwiek temat miał swoje komentarze, to Clojure był zdecydowanym liderem. Dlaczego? Kwintesencją dobrej prezentacji jest dopasowanie przykładu do tematu. I tak właśnie było z Clojure.
Podczas sesji z Clojure pokazałem, jak interaktywie tworzyć aplikację okienkową, gdzie rozpoczynam od "gołej" aplikacji na bazie JFrame i dodaję kolejne elementy graficzne. Kiedy pierwszy raz wpadłem na ten pomysł, wiedziałem, że to będzie cudo. Na dole miałem terminal z Clojure REPL, na górze właśnie otworzone okienko przyszłej aplikacji okienkowej, a pod nimi Eclipse z odtwarzanym skryptem, w którym widać było wpisywane linie kodu w Clojure. Zamierzam, to nagrać w postaci skrinkastu, więc chwila i sam przekonasz się, o czym się tutaj pisze.
Clojure nie jest tutaj jakimś specjalnym czymś, co sprawiłoby, że jest to możliwe. Po prostu, jako język skryptowy - podobnie jak Groovy, JRuby, Rhino, Scala, Jython - daje możliwość nauki API przez wprowadzanie kolejnych wywołań w czymś ala Clojure REPL i natychmiastowego otrzymywania rezultatów z ich uruchomienia. Możnaby to przyrównać do środowiska ciągłej nauki API. Bajka!
Po przerwie, przeszliśmy przez Hibernate, Spring Framework i tworzenie aplikacji z servletami (obsługa formularza) z niewielkim EJB uruchamianym w ramach aplikacji webowej (nowość JEE6). W zasadzie 7 osobom udało się wytrwać do 18:00, kiedy to punktualnie zakończyłem wykład.
Bardzo pomocny okazał się stoper firmy Apimac, który odmierzał równe 40-tominutówki i późniejsze 10-ciominutowe przerwy. Super rozwiązanie, aby zagwarantować pewność utrzymania czasu przez prowadzącego. Polecam!
Czego mi brakowało podczas tego wykładu, to większego udziału publiczności. Znalazło się kilku bardziej aktywnych, ale ogólnie panowała cisza i trudno było zorientować się, czy temat ciekawił, czy warto byłoby poruszyć inne aspekty i w ogóle sprawić, aby spędzony czas był wartościowy merytorycznie. Nieskromnie powiem, że bardzo ucieszyła mnie moja lekkość w zmianie tematu, tempa i dopasowanie do poziomu, ale wolałbym bardziej skrupulatne zajęcie się pojedynczym tematem, np. JEE6 niż przejściem od Java, Clojure, Hibernate, Spring, servlety i EJB. Trochę przypominało groch z kapustą, aczkolwiek zagwarantowało, że wykład spędziłem nie nudząc się ani na chwilę. Liczę, że uczestnicy również.
Sam Tarnów bardzo spokojny. Akurat dzisiaj spadło sporo śniegu, więc wszystko zasypane, ale i tak udało mi się dostrzec tlące się piękno tego miejsca. Po 18:00 w zasadzie zero otwartych sklepów i niepokojąca cisza na ulicy. Może poza Rynkiem jest inaczej?! Ach, zastanawiam się, dlaczego zegar na Ratuszu wybija połówki, kwadrans przed pełną i pełną godzinę?
p.s. Wykład prowadzony był w ramach programu Unii Europejskiej wspierającej wymianę doświadczeń między praktykami i firmy a uczelniami, z korzyścią dla nowej kadry informatycznej - studentów. Pewnie i na Twojej uczelni jest to możliwe. Wystarczy zapytać. Resztą się zajmę. Pisz na priv z prośbą o szczegóły. Na prawdę warto.
Pokazywanie postów oznaczonych etykietą spring framework. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą spring framework. Pokaż wszystkie posty
29 listopada 2010
27 listopada 2010
Wykład akademicki na PWSZ w Tarnowie - 29.11 od 9:30 do 18:00
W nadchodzący poniedziałek, 29.11 będę na Wydziale Informatyki Państwowej Wyższej Szkoły Zawodowej (PWSZ) w Tarnowie (ul. Eljasza Goldhammera) u Tomasza Potempy i jego studentów, z którym zorganizowaliśmy mój wykład dotyczący tematu Java i okolice. Głównymi odbiorcami mają być studenci 4 roku, którzy kończą semestr z końcem grudnia, aby w styczniu skupić się na pisaniu pracy inżynierskiej.
Jak to ze mną bywa przy tego typu otwartych tematach, pomysłów mam wiele i byłbym rad, o kilka wskazówek pod kątem możliwości czasowych i znaczenia rynkowego poszczególnych tematów. Celem nie jest przekazanie pełnego obrazu danego rozwiązania, ale raczej naszkicowanie możliwości, aby wybrać do dalszego rozpoznania to, co może być interesujące.
Mam do dyspozycji 2 bloki 5-godzinne (w sensie lekcyjnym nie zegarowym, czyli 45 minut). Można założyć, że w każdym bloku będzie to samo, ale to zależy od ogólnego zainteresowania uczestników oraz mojego przekonania o sensowności dalszego brnięcia w temat. Tym samym nie ma gwarancji, że drugi blok będzie odpowiadał merytorycznie pierwszemu.
Zaczynam o godzinie 9:30, aby zakończyć o 18:00 z 1-godzinną przerwą obiadową w okolicach 13:15. Okazuje się, że będzie okazja spotkać się z Tomkiem Łabuzem, którego można było poznać podczas konferencji Javarsovia 2010, podczas której prezentował temat "AOP, ThreadLocal i JPA".
Planuję przeprowadzić autorski cykl tematyczny, którego mottem byłoby "Od prostoty do większej prostoty, tj. w każdym kroku ukrywamy złożoność problemu". Nie planuję prezentować slajdów, a jedynie siedzieć przed komputerem, prezentując budowanie aplikacji i machając rekoma ze wstawkami krasomówczymi.
Konspekt
Środowiska programistyczne i uruchomieniowe, darmowe i komercyjne:
Jak to ze mną bywa przy tego typu otwartych tematach, pomysłów mam wiele i byłbym rad, o kilka wskazówek pod kątem możliwości czasowych i znaczenia rynkowego poszczególnych tematów. Celem nie jest przekazanie pełnego obrazu danego rozwiązania, ale raczej naszkicowanie możliwości, aby wybrać do dalszego rozpoznania to, co może być interesujące.
Mam do dyspozycji 2 bloki 5-godzinne (w sensie lekcyjnym nie zegarowym, czyli 45 minut). Można założyć, że w każdym bloku będzie to samo, ale to zależy od ogólnego zainteresowania uczestników oraz mojego przekonania o sensowności dalszego brnięcia w temat. Tym samym nie ma gwarancji, że drugi blok będzie odpowiadał merytorycznie pierwszemu.
Zaczynam o godzinie 9:30, aby zakończyć o 18:00 z 1-godzinną przerwą obiadową w okolicach 13:15. Okazuje się, że będzie okazja spotkać się z Tomkiem Łabuzem, którego można było poznać podczas konferencji Javarsovia 2010, podczas której prezentował temat "AOP, ThreadLocal i JPA".
Planuję przeprowadzić autorski cykl tematyczny, którego mottem byłoby "Od prostoty do większej prostoty, tj. w każdym kroku ukrywamy złożoność problemu". Nie planuję prezentować slajdów, a jedynie siedzieć przed komputerem, prezentując budowanie aplikacji i machając rekoma ze wstawkami krasomówczymi.
Konspekt
Środowiska programistyczne i uruchomieniowe, darmowe i komercyjne:
- NetBeans IDE i Eclipse IDE
- IBM Rational Application Developer 8 i IBM WebSphere Integration Developer 7
- GlassFish i IBM WebSphere Application Server 8
- Apache Derby (wbudowane)
- MySQL
- ORM - zapytania bliższe programiście nie adminowi bazy danych
- zniesienie konieczności zarządzania bytami Hibernate
- środowisko IoC/DI
- zniesienie konieczności dbania o zależności poza ich deklarację
- tworzenie projektu od zera
- z linii poleceń
- z IDE (NetBeans IDE)
- bez XML z językiem Clojure (wrócimy do niego niebawem)
- dostęp do bazy danych (zarządzanie transakcjami)
- JPA
- EJB31
- servlet - obsługa HTTP
- JSF - budowanie widoku
- facelets
- CDI
- Apache OpenEJB
- Serwer aplikacyjny - GlassFish i WAS8
- podział projektu na moduły w Apache Maven był podziałem funkcjonalnym (jak OSGi)
- samodzielna aplikacja
- dynamiczne tworzenie aplikacji okienkowej
- odseparowanie kontraktu (interfejsu) od implementacji
- odseparowanie szczegółów komunikacyjnych od implementacji
22 lipca 2010
Book review: Spring Enterprise Recipes: A Problem-Solution Approach
Na dzień przed moim urlopem zakończyłem lekturę książki Spring Enterprise Recipes: A Problem-Solution Approach, którą otrzymałem od wydawnictwa Apress jeszcze w zeszłym roku.
Długo trwało zanim przekonałem się do jej lektury i pewnie tylko za sprawą ostatnich moich warsztaty dotyczących Spring Framework i Hibernate dałem się na nią namówić. I (chyba) nie żałuję (aczkolwiek w moich ustach nie brzmi to najbardziej wiarygodnie, gdyż rzadko udaje mi się przyznać do popełnionych pomyłek). Znalazłem w niej kilka ciekawostek i odświeżyłem ogólną wiedzę nt. Springa, ale żeby zaraz ją rekomendować, to niekoniecznie. Na pewno nie jest dla osób, które chciałyby przestudiować działanie Spring i jego integracji z innymi projektami. Tutaj prawdopodobnie poleciłbym inną książkę (brakuje mi dobrego typu jednak). Ta jest dobra, kiedy już wiemy, o co chodzi w Springu i albo odświeżamy wiedzę, albo uzupełniamy ją o integracje, z których nie dane nam było skorzystać produkcyjnie. Dzięki tej książce poznałem kilka sztuczek i z łatwością poradziłem sobie z warsztatami. Czyta się ją stosunkowo szybko, bo podejście typu "problem, rozwiązanie, omówienie" czyni z tej książki swego rodzaju encyklopedię, którą da się przeczytać zakładając, że nie przekracza odpowiedniego poziomu stron. Książka "Spring Enterprise Recipes" ma ich 450, więc w drodze do pracy i po niej można zmierzyć się z nią bez większego wysiłku. Rozdział w kwadrans to nie jest zbyt karkołomne założenie, szczególnie jeśli omawiany aspekt Springa jest nam dobrze znany i większość stron to kod źródłowy, albo wycinek z pliku XMLowego.
Zainteresowanych angielską wersją recenzji zapraszam do mojego Wiki - Book review: Spring Enterprise Recipes: A Problem-Solution Approach, a samą lekturą do Biblioteki Warszawskiego JUGa.
W końcu upragnione wakacje! Bawcie się dobrze.
Długo trwało zanim przekonałem się do jej lektury i pewnie tylko za sprawą ostatnich moich warsztaty dotyczących Spring Framework i Hibernate dałem się na nią namówić. I (chyba) nie żałuję (aczkolwiek w moich ustach nie brzmi to najbardziej wiarygodnie, gdyż rzadko udaje mi się przyznać do popełnionych pomyłek). Znalazłem w niej kilka ciekawostek i odświeżyłem ogólną wiedzę nt. Springa, ale żeby zaraz ją rekomendować, to niekoniecznie. Na pewno nie jest dla osób, które chciałyby przestudiować działanie Spring i jego integracji z innymi projektami. Tutaj prawdopodobnie poleciłbym inną książkę (brakuje mi dobrego typu jednak). Ta jest dobra, kiedy już wiemy, o co chodzi w Springu i albo odświeżamy wiedzę, albo uzupełniamy ją o integracje, z których nie dane nam było skorzystać produkcyjnie. Dzięki tej książce poznałem kilka sztuczek i z łatwością poradziłem sobie z warsztatami. Czyta się ją stosunkowo szybko, bo podejście typu "problem, rozwiązanie, omówienie" czyni z tej książki swego rodzaju encyklopedię, którą da się przeczytać zakładając, że nie przekracza odpowiedniego poziomu stron. Książka "Spring Enterprise Recipes" ma ich 450, więc w drodze do pracy i po niej można zmierzyć się z nią bez większego wysiłku. Rozdział w kwadrans to nie jest zbyt karkołomne założenie, szczególnie jeśli omawiany aspekt Springa jest nam dobrze znany i większość stron to kod źródłowy, albo wycinek z pliku XMLowego.
Zainteresowanych angielską wersją recenzji zapraszam do mojego Wiki - Book review: Spring Enterprise Recipes: A Problem-Solution Approach, a samą lekturą do Biblioteki Warszawskiego JUGa.
W końcu upragnione wakacje! Bawcie się dobrze.
14 lipca 2010
Tworzenie samodzielnej aplikacji ze Spring Framework i Hibernate w NetBeans IDE 6.9
Właśnie ukończyłem prace nad kolejnym, trzecim i ostatnim artykułem Tworzenie samodzielnej aplikacji ze Spring Framework i Hibernate w NetBeans IDE 6.9, który wprowadza czytelnika w arkana integracji Spring Framework z Hibernate (albo odwrotnie), aby tym samym pozwolić mi na przeprowadzenie warsztatów w bardziej składny sposób - z użyciem materiałów, które są dostępne publicznie, dla każdego. Są to bardzo wprowadzające artykuły przygotowane specjalnie dla początkujących w temacie. Bardziej zaawansowani użytkownicy tandemu Spring + Hibernate pewnie nie znajdą w nich wiele pożytecznego. Uwagi i sugestie mile widziane, a zainteresowanych warsztatami uprasza się o kontakt na priv.
Sama idea warsztatów wypływała już kilkakrotnie i zawsze problemem było właśnie przygotowanie materiałów i działających przykładów. Tradycyjnie jak co roku, Warszawa JUG organizuje konferencję warsztatową Warsjava w okolicach października/listopada i w tym roku zamarzyło mi się, aby być przygotowanym, a może nawet poprowadzić warsztaty płatne?! Jest kilku zainteresowanych pomysłem i teraz przyszło mi realizować jej część merytoryczną. Zainteresowany? Zainteresowana?
W serii warsztatowej o Spring i Hibernate, przez ostatnie tygodnie stworzyłem zapowiadane trzy artykuły:
Muszę przyznać, że NetBeans 6.9 dał mi się tak we znaki (przede wszystkim ciągłe błędy z odświeżaniem zawartości w projekcie), że nie tylko, że musiałem zaktualizować go do najnowszej, rozwojowej wersji z wczorajszego dnia (co niestety zniszczyło mi wszystkie dodatki jakie przychodzą z wersjami produkcyjnymi w temacie integracji NB z systemem operacyjnym, czyli ikonę startową), ale coraz częściej pojawia mi się myśl, aby go całkowicie zakopać i już więcej nie oglądać. Stał się tak toporny w swojej obsłudze projektów, że zwykłe zamykanie/otwieranie projektów prowadziło często do tak kuriozalnych sytuacji, jak oznaczenie niektórych jako nie-NetBeans-owych! A były w nim tworzone! Gdyby nie fakt, że NetBeans i Java EE "w jednym stali domu", to już dawno zapomniałbym o istnieniu NetBeans. Rozważam przejście na Eclipse, albo IDEA. Skłaniam się ku IDEA, ale nie wszyscy ją mają i artykuły byłyby mocno zawężone pod względem grupy odbiorczej. Sugestie?
Tym samym wracam do mojej wcześniejszej aktywności wokół specyfikacji JSR 299: Contexts and Dependency Injection for the Java EE platform. Celem jest stworzenie podobnego zestawu artykułów, aby możliwe było wprowadzenia nowicjusza w tajniki CDI. Pomysły, sugestie, uwagi mile widziane. Jeśli chcesz przeczytać coś interesującego, daj mi poznać swoje potrzeby, a *może* uda mi się je spełnić?! Ku uciesze obu stron ;-)
Sama idea warsztatów wypływała już kilkakrotnie i zawsze problemem było właśnie przygotowanie materiałów i działających przykładów. Tradycyjnie jak co roku, Warszawa JUG organizuje konferencję warsztatową Warsjava w okolicach października/listopada i w tym roku zamarzyło mi się, aby być przygotowanym, a może nawet poprowadzić warsztaty płatne?! Jest kilku zainteresowanych pomysłem i teraz przyszło mi realizować jej część merytoryczną. Zainteresowany? Zainteresowana?
W serii warsztatowej o Spring i Hibernate, przez ostatnie tygodnie stworzyłem zapowiadane trzy artykuły:
- Tworzenie samodzielnej aplikacji ze Spring Framework w NetBeans IDE 6.9
- Tworzenie samodzielnej aplikacji z Hibernate w NetBeans IDE 6.9
- Tworzenie samodzielnej aplikacji ze Spring Framework i Hibernate w NetBeans IDE 6.9
W ten sposób zamknąłem pewien rozdział w mojej działalności edukacyjnej związanej ze wspomnianymi produktami - Spring i Hibernate, które wykorzystałem do stworzenia samodzielnych aplikacji w środowisku NetBeans IDE 6.9. Trochę mnie to integrowanie znużyło i coraz bardziej tęskno mi do pełniejszego środowiska serwera aplikacyjnego JEE6.
Muszę przyznać, że NetBeans 6.9 dał mi się tak we znaki (przede wszystkim ciągłe błędy z odświeżaniem zawartości w projekcie), że nie tylko, że musiałem zaktualizować go do najnowszej, rozwojowej wersji z wczorajszego dnia (co niestety zniszczyło mi wszystkie dodatki jakie przychodzą z wersjami produkcyjnymi w temacie integracji NB z systemem operacyjnym, czyli ikonę startową), ale coraz częściej pojawia mi się myśl, aby go całkowicie zakopać i już więcej nie oglądać. Stał się tak toporny w swojej obsłudze projektów, że zwykłe zamykanie/otwieranie projektów prowadziło często do tak kuriozalnych sytuacji, jak oznaczenie niektórych jako nie-NetBeans-owych! A były w nim tworzone! Gdyby nie fakt, że NetBeans i Java EE "w jednym stali domu", to już dawno zapomniałbym o istnieniu NetBeans. Rozważam przejście na Eclipse, albo IDEA. Skłaniam się ku IDEA, ale nie wszyscy ją mają i artykuły byłyby mocno zawężone pod względem grupy odbiorczej. Sugestie?
Tym samym wracam do mojej wcześniejszej aktywności wokół specyfikacji JSR 299: Contexts and Dependency Injection for the Java EE platform. Celem jest stworzenie podobnego zestawu artykułów, aby możliwe było wprowadzenia nowicjusza w tajniki CDI. Pomysły, sugestie, uwagi mile widziane. Jeśli chcesz przeczytać coś interesującego, daj mi poznać swoje potrzeby, a *może* uda mi się je spełnić?! Ku uciesze obu stron ;-)
05 lipca 2010
Tworzenie samodzielnej aplikacji ze Spring Framework w NetBeans IDE 6.9
Miałem ostatnio ciekawe przedsięwzięcie (coś ala szkolenie-warsztaty) wprowadzające w arkana użycia Spring Framework oraz Hibernate. Dano mi do dyspozycji 2 dni i kiedy podjąłem się wyzwania sądziłem, że to będzie pół dnia omówienia tematu i...właśnie, co ja z nimi będę robił dalej?! Taka myśl towarzyszyła mi do pierwszego dnia, kiedy w połowie okazało się, że to, co łatwe i proste dla jednego (mnie) nie jest takim dla słuchaczy (oni). Okazało się, że należało zapoznać słuchaczy ze wspomnianą tematyką, ale czasami nawet z samym programowaniem w Javie. Można sobie wyobrazić, jak na miejscu, udoskonalałem materiały. Skończyło się na czymś niezwykle odświeżającym dla mnie i (zgodnie z ich oficjalną oceną) czymś pouczającym dla nich.
Jako, że nie mogłem znaleźć wystarczająco wprowadzających artykułów w tajniki użycia tandemu Spring Framework i Hibernate, postanowiłem stworzyć kilka na własne potrzeby. Jeden z nich już udostępniłem, a drugi się robi.
W artykule Tworzenie samodzielnej aplikacji ze Spring Framework w NetBeans IDE 6.9 przedstawiłem kroki niezbędne do stworzenia samodzielnej aplikacji korzystającej ze Spring Framework w zintegrowanym środowisku programistycznym NetBeans IDE 6.9. Starałem się wykorzystać wszystkie możliwości NetBeans, aby jak najmniejszym kosztem stworzyć pełnoprawną aplikację springową. Niestety nie ma ich wiele, ale chociaż pomoc przy tworzeniu pliku konfiguracyjnego Springa okazała się nieoceniona. Tylko dlaczego podpowiedzi w edytorze XML wymagają dostępu do Sieci?!
Kolejny będzie o użyciu Hibernate, aby skończyć na połączeniu obu. Uwagi mile widziane. Chciałbym, aby artykuł stanowił kanwę do nagrania kolejnego skrinkastu, bo skoro mam już scenariusz, to nie pozostaje nic innego, jak skręcić 5-minutówkę.
p.s. Tematyka Spring Framework i Hibernate tak mnie wkręciła, że zabrałem się za lekturę książki Spring Enterprise Recipes: A Problem-Solution Approach panów Josha Longa i Gary'ego Maka wydawnictwa Apress. Jest to moja pierwsza książka w stylu problem-rozwiązanie i bardzo mi ten sposób pisania przypadł do gustu. Czasami trochę rozwlekła i za bardzo wnikająca w pewne aspekty (dosłownie i w przenośni) użycia Springa, ale pomimo tego zdaje się być bardzo pouczająca.
Jako, że nie mogłem znaleźć wystarczająco wprowadzających artykułów w tajniki użycia tandemu Spring Framework i Hibernate, postanowiłem stworzyć kilka na własne potrzeby. Jeden z nich już udostępniłem, a drugi się robi.
W artykule Tworzenie samodzielnej aplikacji ze Spring Framework w NetBeans IDE 6.9 przedstawiłem kroki niezbędne do stworzenia samodzielnej aplikacji korzystającej ze Spring Framework w zintegrowanym środowisku programistycznym NetBeans IDE 6.9. Starałem się wykorzystać wszystkie możliwości NetBeans, aby jak najmniejszym kosztem stworzyć pełnoprawną aplikację springową. Niestety nie ma ich wiele, ale chociaż pomoc przy tworzeniu pliku konfiguracyjnego Springa okazała się nieoceniona. Tylko dlaczego podpowiedzi w edytorze XML wymagają dostępu do Sieci?!
Kolejny będzie o użyciu Hibernate, aby skończyć na połączeniu obu. Uwagi mile widziane. Chciałbym, aby artykuł stanowił kanwę do nagrania kolejnego skrinkastu, bo skoro mam już scenariusz, to nie pozostaje nic innego, jak skręcić 5-minutówkę.
p.s. Tematyka Spring Framework i Hibernate tak mnie wkręciła, że zabrałem się za lekturę książki Spring Enterprise Recipes: A Problem-Solution Approach panów Josha Longa i Gary'ego Maka wydawnictwa Apress. Jest to moja pierwsza książka w stylu problem-rozwiązanie i bardzo mi ten sposób pisania przypadł do gustu. Czasami trochę rozwlekła i za bardzo wnikająca w pewne aspekty (dosłownie i w przenośni) użycia Springa, ale pomimo tego zdaje się być bardzo pouczająca.
21 czerwca 2010
Recenzja "Dependency Injection, Design patterns using Spring and Guice" z Manning
Cóż za niesamowita książka! Jak wspominałem w "Sport to zdrowie", a na mojego nosa jest jednak inaczej, w trakcie oczekiwania na wizytę w gabinecie laryngologicznym dotarłem do końca Dependency Injection, Design patterns using Spring and Guice autorstwa Dhanji R. Prasanna (Manning, sierpień 2009) i jestem nią wprost urzeczony.
Książka naładowana wiedzą dotyczącą koncepcji wstrzeliwania zależności (ang. dependency injection) oraz tematów wspierających jak zarządzanie stanem i wzorców programistycznych - proxy, adapter i provider na przykładach ze Spring Framework i Google Guice (głównie jednak tego drugiego, Guice). Nieoczekiwanie zrozumiałem podstawy do stworzenia trzech specyfikacji Java EE 6 - JSR-299: Contexts and Dependency Injection for the Java EE platform (CDI), JSR 330: Dependency Injection for Java i JSR-316: Java EE 6 Managed Beans, a tym samym zdobyłem garść pożytecznych informacji na tematy, o których jeszcze przed miesiącem mogłem jedynie pomarzyć. Takie akcje lubię najbardziej - robię jedno, a kończę wiele.
Książkę trafiła w moje ręce w ramach programu "Książka dla JUGa za recenzję" i nie potrafię wytłumaczyć, dlaczego zdecydowałem się na jej lekturę. Jest kilka książek, które czekają na mnie, ale akurat padło na nią. Nie żałuję tej decyzji i dziwię się, że nie zabrałem się za nią wcześniej. Ech, gdybym tylko wiedział...Książka trafiła na półkę Biblioteki Warszawskiego JUGa i czeka na kolejnego zainteresowanego zgłębieniem tajników wstrzykiwania zależności oraz podstaw technologicznych stojących za stworzeniem wspomnianych specyfikacji Java EE 6. Dodatkowo można w bardzo przyjemny sposób zapoznać się z Google Guice, co jest o tyle niebezpieczne, że można stać się jego zagorzałym zwolennikiem. To, co mogłem wyczytać o Guice z tej książki z pewnością plasuje mnie w gronie takowych. Ostrzegałem.
Zainteresowanych angielskojęzyczną recenzją zapraszam do mojego artykułu na Wiki - Book review: Dependency Injection.
Jeszcze nie wybrałem kolejnej książki, mimo, że czeka kilka, ale chętnie wysłucham sugestii. Tylko proszę nie wspominać o Clean Code: A Handbook of Agile Software Craftsmanship, bo już zamówiona i pewnie zabrałbym się za nią, gdybym ją miał pod ręką. Wersja polska Czysty kod. Podręcznik dobrego programisty również w drodze.
p.s. Czytałem dzisiaj również bardzo ciekawy artykuł Functional Programming For The Rest of Us nt. programowania funkcyjnego (PF) i wciąż nie mogę otrząsnąć się z wrażenia, jak fascynujący świat kryje się za nim. Chciałbym go skosztować, ale najwyraźniej brakuje mi zapału. Gdyby tak zechciał znaleźć się mentor, któremu udałoby przeciągnąć mnie przez meandry myślenia OO ku PF byłoby cudnie. Clojure preferowany.
p.s. Zostały jedynie 4 dni do naszego społecznościowego święta - konferencji Javarsovia 2010! Koniecznie musimy obgadać to i owo. Gotowym na zaczepki - wystarczy przywitać się (mile widziane komentarze, jakie to fajne rzeczy opisuję na blogu :)), ale można i zagadnąć o cokolwiek ze świata Javy. Chętnie poznam Wasze opinie, które sprawią, że moje pomysły nabiorą rumieńców.
Książka naładowana wiedzą dotyczącą koncepcji wstrzeliwania zależności (ang. dependency injection) oraz tematów wspierających jak zarządzanie stanem i wzorców programistycznych - proxy, adapter i provider na przykładach ze Spring Framework i Google Guice (głównie jednak tego drugiego, Guice). Nieoczekiwanie zrozumiałem podstawy do stworzenia trzech specyfikacji Java EE 6 - JSR-299: Contexts and Dependency Injection for the Java EE platform (CDI), JSR 330: Dependency Injection for Java i JSR-316: Java EE 6 Managed Beans, a tym samym zdobyłem garść pożytecznych informacji na tematy, o których jeszcze przed miesiącem mogłem jedynie pomarzyć. Takie akcje lubię najbardziej - robię jedno, a kończę wiele.
Książkę trafiła w moje ręce w ramach programu "Książka dla JUGa za recenzję" i nie potrafię wytłumaczyć, dlaczego zdecydowałem się na jej lekturę. Jest kilka książek, które czekają na mnie, ale akurat padło na nią. Nie żałuję tej decyzji i dziwię się, że nie zabrałem się za nią wcześniej. Ech, gdybym tylko wiedział...Książka trafiła na półkę Biblioteki Warszawskiego JUGa i czeka na kolejnego zainteresowanego zgłębieniem tajników wstrzykiwania zależności oraz podstaw technologicznych stojących za stworzeniem wspomnianych specyfikacji Java EE 6. Dodatkowo można w bardzo przyjemny sposób zapoznać się z Google Guice, co jest o tyle niebezpieczne, że można stać się jego zagorzałym zwolennikiem. To, co mogłem wyczytać o Guice z tej książki z pewnością plasuje mnie w gronie takowych. Ostrzegałem.
Zainteresowanych angielskojęzyczną recenzją zapraszam do mojego artykułu na Wiki - Book review: Dependency Injection.
Jeszcze nie wybrałem kolejnej książki, mimo, że czeka kilka, ale chętnie wysłucham sugestii. Tylko proszę nie wspominać o Clean Code: A Handbook of Agile Software Craftsmanship, bo już zamówiona i pewnie zabrałbym się za nią, gdybym ją miał pod ręką. Wersja polska Czysty kod. Podręcznik dobrego programisty również w drodze.
p.s. Czytałem dzisiaj również bardzo ciekawy artykuł Functional Programming For The Rest of Us nt. programowania funkcyjnego (PF) i wciąż nie mogę otrząsnąć się z wrażenia, jak fascynujący świat kryje się za nim. Chciałbym go skosztować, ale najwyraźniej brakuje mi zapału. Gdyby tak zechciał znaleźć się mentor, któremu udałoby przeciągnąć mnie przez meandry myślenia OO ku PF byłoby cudnie. Clojure preferowany.
p.s. Zostały jedynie 4 dni do naszego społecznościowego święta - konferencji Javarsovia 2010! Koniecznie musimy obgadać to i owo. Gotowym na zaczepki - wystarczy przywitać się (mile widziane komentarze, jakie to fajne rzeczy opisuję na blogu :)), ale można i zagadnąć o cokolwiek ze świata Javy. Chętnie poznam Wasze opinie, które sprawią, że moje pomysły nabiorą rumieńców.
19 lutego 2009
Podział konfiguracji springowej i automatyczny formularz logowania w Spring Security
Ostatnimi czasy zajmowałem się niezwykle interesującym tematem wykorzystania JA-SIG Central Authentication Service (CAS) oraz LDAP w ramach aplikacji webowej i natychmiast wskazałem na Spring Security jako platformę integracyjną. CAS dostarczał mechanizmu pojedyńczego uwierzytelnienia (ang. SSO - Single Sign-On), a LDAP informacji o użytkownikach i ich rolach (autoryzacja). O całym przedsięwzięciu później, ale teraz jedynie wspomnę, że podczas konfiguracji Spring Security (co w zasadzie dotyczy jakiegokolwiek projektu korzystającego ze Spring Framework) natrafiłem na ciekawą cechę konfiguracyjną - podział pliku applicationContext na oddzielne pliki, które w całości stanowią konfigurację springową aplikacji (patrz 15.2. Common configuration). Wystarczy zatem umieścić pewne części konfiguracji w oddzielnych plikach i można uprościć jej zarządzanie - w pliku WEB-INF/web.xml aplikacji webowej wystarczy użyć wyrażenia regularnego /WEB-INF/applicationContext*.xml, aby wskazać na nie wszystkie.
Kolejną ciekawostką, tym razem bezpośrednio związaną ze Spring Security, które przypomina mi Grails, jest automatyczne tworzenie formularza logowania (strony do podawania loginu i hasła). Wystarczy wdrożyć minimalną konfigurację Spring Security w naszej aplikacji webowej (patrz 2.2. Getting Started with Security Namespace Configuration), w której możemy skorzystać z 2.2.2.2. Form and Basic Login Options:
You might be wondering where the login form came from when you were prompted to log in, since we made no mention of any HTML files or JSPs. In fact, since we didn't explicitly set a URL for the login page, Spring Security generates one automatically, based on the features that are enabled and using standard values for the URL which processes the submitted login, the default target URL the user will be sent to and so on.
Podkreślam "Spring Security generates one automatically". Idealne na szybki start! I faktycznie działa!
<context-param>Spring Framework zadba o ich połączenie i w ten sposób pozbywamy się choć części trudności w obsłudze tego xmlowego szaleństwa w Springu.
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
Kolejną ciekawostką, tym razem bezpośrednio związaną ze Spring Security, które przypomina mi Grails, jest automatyczne tworzenie formularza logowania (strony do podawania loginu i hasła). Wystarczy wdrożyć minimalną konfigurację Spring Security w naszej aplikacji webowej (patrz 2.2. Getting Started with Security Namespace Configuration), w której możemy skorzystać z 2.2.2.2. Form and Basic Login Options:
You might be wondering where the login form came from when you were prompted to log in, since we made no mention of any HTML files or JSPs. In fact, since we didn't explicitly set a URL for the login page, Spring Security generates one automatically, based on the features that are enabled and using standard values for the URL which processes the submitted login, the default target URL the user will be sent to and so on.
Podkreślam "Spring Security generates one automatically". Idealne na szybki start! I faktycznie działa!
13 stycznia 2009
Spring Security z CAS w aplikacji webowej
Zabrałem się za acegi z Grails, ale coś mi nieszło, więc zszedłem na poziom samego Acegi, a właściwie to Spring Security 2.0.4 w "zwykłych" aplikacjach webowych z użyciem facelets. Instrukcja w Tutorial: Adding Security to Spring Petclinic zadziałała bezbłędnie. Przykładowy projekt, który zabezpieczałem Spring Security zarządzany jest przez Apache Maven, więc nie kopiowałem bibliotek, a jedynie zdefiniowałem konieczne zależności w pom.xml:
Pozostało zabrać się za CASowanie mojej przykładowej aplikacji. Zabrałem się za 3.4. CAS Sample, a tam...dwa (drobne?) błędy. Pierwszy to wskazanie na dokument z opisem jak pobrać źródła "...as described in the introduction.":
Not Found
The requested URL /spring-security/site/reference/html/get-source was not found on this server.
a kiedy już dobrałem się do właściwego dokumentu 1.4. Getting the Source okazało się, że http://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/spring-security/trunk/ jest już nieaktualny i faktycznie powinien być https://src.springframework.org/svn/spring-security/trunk
. Niezły bałagan! Zgłosiłem jako SEC-1080 3.4. CAS Sample refers to incorrect get-source document and incorrect svn repo URL. Warto odnotować, jak szybko nastąpiła reakcja ze strony członków zespołu Spring Security - niecała godzina i już znalazł się chętny do wdrożenia poprawek!
Wracając do CAS i Spring Security, w porównaniu z poprzednią konfiguaracją teraz to beans jest wiodącą przestrzenią nazw (poprzednio security). To jest akurat niewielka zmiana i wyłącznie dotyczy organizacji pliku xmlowego niż samej konfiguracji Spring Security.
Jeszcze tylko zmiana w web.xml i rozpoczynam testowanie.
Testy zakończyły się niepowodzeniem:
W komentarzach do komunikatu o Spring Framework 3.0.0.M1 można znaleźć odpowiedź dla poszukujących repozytorium mavenowego dla tego wydania.
Przede wszystkim zmieniamy artifactId na odpowiadający pakietowi (konwencja zapożyczona z nazewnictwa pakunków OSGi, którą SpringSource krzewi przez Spring-DM, a następnie SpringSource dm Server) i dodajemy odpowiednie repozytoria:
Oczywiście korzystając z atrybutu autowire możnaby znacząco uprościć plik konfiguracyjny Springa applicationContext-security.xml, gdzie wiązania typu <property name="authenticationManager" ref="authenticationManager"/> byłyby tworzone dynamicznie przez Spring Framework.
<properties>i dodałem /WEB-INF/applicationContext-security.xml:
<spring-security.version>2.0.4</spring-security.version>
</properties>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core-tiger</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas-client</artifactId>
<version>${spring-security.version}</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>Prawie tak jak opisano w dokumencie, poza wymaganiem, że wszystkie strony <intercept-url pattern="/**" access="ROLE_USER"/> są chronione. Jest jednak drobny błąd w dokumentacji, która wymaga, aby zdefiniować /WEB-INF/applicationContext-security.xml w context-param w deskryptorze wdrożenia web.xml, podczas gdy przez cały dokument mówi się o applicationContext-security-ns.xml. Już zgłosiłem jako SEC-1079 applicationContext-security.xml in Tutorial: Adding Security to Spring Petclinic.
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
<http auto-config="true">
<intercept-url pattern="/**" access="ROLE_USER"/>
</http>
<!--
Usernames/Passwords are
rod/koala
dianne/emu
scott/wombat
peter/opal
-->
<authentication-provider>
<password-encoder hash="md5"/>
<user-service>
<user name="rod" password="a564de63c2d0da68cf47586ee05984d7"
authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER"/>
<user name="dianne" password="65d15fe9156f9c4bbffd98085992a44e" authorities="ROLE_USER,ROLE_TELLER"/>
<user name="scott" password="2b58af6dddbd072ed27ffc86725d7d3a" authorities="ROLE_USER"/>
<user name="peter" password="22b5c9accc6e1ba628cedc63a72d57f8" authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</beans:beans>
Pozostało zabrać się za CASowanie mojej przykładowej aplikacji. Zabrałem się za 3.4. CAS Sample, a tam...dwa (drobne?) błędy. Pierwszy to wskazanie na dokument z opisem jak pobrać źródła "...as described in the introduction.":
Not Found
The requested URL /spring-security/site/reference/html/get-source was not found on this server.
a kiedy już dobrałem się do właściwego dokumentu 1.4. Getting the Source okazało się, że http://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/spring-security/trunk/ jest już nieaktualny i faktycznie powinien być https://src.springframework.org/svn/spring-security/trunk
. Niezły bałagan! Zgłosiłem jako SEC-1080 3.4. CAS Sample refers to incorrect get-source document and incorrect svn repo URL. Warto odnotować, jak szybko nastąpiła reakcja ze strony członków zespołu Spring Security - niecała godzina i już znalazł się chętny do wdrożenia poprawek!
Wracając do CAS i Spring Security, w porównaniu z poprzednią konfiguaracją teraz to beans jest wiodącą przestrzenią nazw (poprzednio security). To jest akurat niewielka zmiana i wyłącznie dotyczy organizacji pliku xmlowego niż samej konfiguracji Spring Security.
<?xml version="1.0" encoding="UTF-8"?>Nie podoba mi się odwołanie do https://localhost:8443/cas-sample w pliku konfiguracyjnym. Niby jest do zmiany podczas wdrażania aplikacji, ale wystarczy zmiana kontekstu webowego i już muszę pamiętać, aby zmienić coś w deskryptorze (!) Tutaj oczekiwałbym jakiejś zmiany.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
<sec:http entry-point-ref="casProcessingFilterEntryPoint">
<sec:intercept-url pattern="/**" access="ROLE_USER" requires-channel="https"/>
</sec:http>
<sec:authentication-manager alias="authenticationManager"/>
<bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter">
<sec:custom-filter after="CAS_PROCESSING_FILTER"/>
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureHandler">
<bean class="org.springframework.security.ui.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/casfailed.jsp"/>
</bean>
</property>
<property name="authenticationSuccessHandler">
<bean class="org.springframework.security.ui.SimpleUrlAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/"/>
</bean>
</property>
<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
<property name="proxyReceptorUrl" value="/secure/receptor" />
</bean>
<bean id="casProcessingFilterEntryPoint" class="org.springframework.security.ui.cas.CasProcessingFilterEntryPoint">
<property name="loginUrl" value="https://localhost:9443/cas/login"/>
<property name="serviceProperties" ref="serviceProperties"/>
</bean>
<bean id="casAuthenticationProvider" class="org.springframework.security.providers.cas.CasAuthenticationProvider">
<sec:custom-authentication-provider />
<property name="userDetailsService" ref="userService"/>
<property name="serviceProperties" ref="serviceProperties" />
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="https://localhost:9443/cas" />
<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
<property name="proxyCallbackUrl" value="https://localhost:8443/cas-sample/secure/receptor" />
</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only"/>
</bean>
<bean id="proxyGrantingTicketStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl" />
<bean id="serviceProperties" class="org.springframework.security.ui.cas.ServiceProperties">
<property name="service" value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/>
<property name="sendRenew" value="false"/>
</bean>
<sec:user-service id="userService">
<sec:user name="rod" password="rod" authorities="ROLE_SUPERVISOR,ROLE_USER" />
<sec:user name="dianne" password="dianne" authorities="ROLE_USER" />
<sec:user name="scott" password="scott" authorities="ROLE_USER" />
</sec:user-service>
</beans>
Jeszcze tylko zmiana w web.xml i rozpoczynam testowanie.
Testy zakończyły się niepowodzeniem:
Caused by: org.springframework.beans.factory.CannotLoadBeanClassException:bo klasa org.springframework.security.ui.SimpleUrlAuthenticationFailureHandler dostępna jest dopiero od wersji Spring Security 2.5.0-SNAPSHOT. Aby z niej skorzystać należy rozbudować konfigurację pom.xml o
Cannot find class [org.springframework.security.ui.SimpleUrlAuthenticationFailureHandler] for
bean with name 'org.springframework.security.ui.SimpleUrlAuthenticationFailureHandler#e3f429'
defined in ServletContext resource [/WEB-INF/applicationContext-security.xml]
<build>Po tym posypało się większymi uaktualnieniami, gdyż
<extensions>
<extension>
<groupId>org.springframework.aws</groupId>
<artifactId>spring-aws-maven</artifactId>
<version>1.2.2</version>
</extension>
</extensions>
</build>
<repositories>
<repository>
<id>spring-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>s3://maven.springframework.org/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
11:09:55,421 WARN [BasicLifecycleMonitor] Exception occured while notifying listenerZdaje się, że jest to pierwszy raz, kiedy przyjdzie mi skorzystać ze Spring Framework 3.0.0.M1, bo ta klasa dopiero w tej wersji się pojawiła - org.springframework.beans.factory.config.BeanExpressionResolver. W takiej sytuacji mam dwa podejścia - brnąć dalej w uaktualnienia licząc, że ze zmianami nie przyjdzie mi zajmować się problemami, które wynikają z błędów w oprogramowaniu, a nie mojej nieznajomości Spring Security, albo po prostu doczytać, co należy zmienić, aby nie korzystać z nowości Spring Security 2.5.0-SNAPSHOT. Na razie wybieram podejście pierwsze - brnę dalej (i cichutko się modlę).
java.lang.NoClassDefFoundError: org/springframework/beans/factory/config/BeanExpressionResolver
W komentarzach do komunikatu o Spring Framework 3.0.0.M1 można znaleźć odpowiedź dla poszukujących repozytorium mavenowego dla tego wydania.
Przede wszystkim zmieniamy artifactId na odpowiadający pakietowi (konwencja zapożyczona z nazewnictwa pakunków OSGi, którą SpringSource krzewi przez Spring-DM, a następnie SpringSource dm Server) i dodajemy odpowiednie repozytoria:
<properties>Zbudować zbudowałem, ale przy uruchomieniu aplikacji pojawił się komunikat o niedostępności org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean, więc dodałem kolejną zależność do projektu:
<spring.version>3.0.0.M1</spring.version>
</properties>
...
<repository>
<id>SpringSource Enterprise Bundle Repository - External Bundle Milestones</id>
<url>http://repository.springsource.com/maven/bundles/milestone</url>
</repository>
<repository>
<id>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</id>
<url>http://repository.springsource.com/maven/bundles/release</url>
</repository>
<repository>
<id>SpringSource Enterprise Bundle Repository - External Bundle Releases</id>
<url>http://repository.springsource.com/maven/bundles/external</url>
</repository>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>Ponownie budowanie i wdrożenie do Geronimo. Teraz jest cacy! Nawet działa! Coś jeszcze będę musiał poczytać o CASie (albo przegadać temat z Michałem Margielem, który oferował swoją pomoc w temacie - podobno się zna ;-)).
<groupId>org.springframework</groupId>
<artifactId>org.springframework.orm</artifactId>
<version>${spring.version}</version>
</dependency>
Oczywiście korzystając z atrybutu autowire możnaby znacząco uprościć plik konfiguracyjny Springa applicationContext-security.xml, gdzie wiązania typu <property name="authenticationManager" ref="authenticationManager"/> byłyby tworzone dynamicznie przez Spring Framework.
21 września 2008
Spring Dynamic Modules a aplikacje webowe
Już pisałem o tym 4 maja 2008 w Aplikacja webowa jako pakunek OSGi ze Spring Dynamic Modules, ale po sobie widzę, że warto wspomnieć o tym jeszcze raz.
Rozdział 8. Web Support nie pozostawia złudzeń, czego możemy dodatkowo oczekiwać od Spring Dynamic Modules (Spring-DM) poza podstawową cechą jako jest wsparcie dla tworzenia pakunków OSGi korzystając ze Spring Framework. Mowa w nim o wsparciu dla aplikacji webowych (będącymi dystrybuowane jako war - plik jar z odpowiednią strukturą katalogową, np. konieczność istnienia WEB-INF/web.xml) będącymi de facto pakunkami OSGi. Jeśli ktokolwiek zastanawiał się nad sensownością zastosowania OSGi w swoich aplikacjach, to przynajmniej obszar aplikacji webowych powinien być już rozwikłany z pomocą tego rozdziału. Spring-DM łączy cechy OSGi z Korporacyjną Javą udostępniając niezbędne elementy jako pakunki OSGi - kontener servletów jak i samą aplikację webową - które wiąże mechanizmami OSGi. Spring-DM to po prostu warstwa wspierająca uruchamianie aplikacji springowych oraz webowych na Platformie OSGi.
Przyjrzyjmy się dokładniej, co takiego oferuje Spring-DM, czego nie znajdziemy w innych środowiskach. Do poprawnego uruchomienia aplikacji webowej potrzebny jest kontener servletów (być może z jsp, ale kto by tego obecnie używał?!). Podstawowym bytem Platformy OSGi jest pakunek. Jeśli cokolwiek miałoby być uruchomione na Platformie OSGi musi być pakunkiem. Pakunek OSGi to zwykły plik jar z odpowiednimi nagłówkami w META-INF/MANIFEST.MF i stąd wypływa niezwykłość OSGi - niby nic szczególnego, a za darmo mamy możliwości niebagatelnej wartości, m.in. wersjonowanie, dedykowane ładowarki klas, uprawnienia, co z kolei składa się na funkcjonalność uktualniania aplikacji bez konieczności jej zatrzymywania. Połączenie elementów Java EE z OSGi polega na udostępnieniu tych pierwszych jako pakunków OSGi i...tyle. Już możemy okrzyknąć nasze rozwiązanie jako zgodne z pryncypiami OSGi. Do tego wcale nie potrzeba Spring-DM. Gdzie dostrzeżemy zaletę jego wykorzystania, to w sposobie integracji trzech (!) technologii OSGi, Java EE oraz Spring Framework - podczas uruchomienia pakunku OSGi z rozszerzeniem pliku .war, lub zawierającego specyficzne dla Spring-DM nagłówki w manifeście, nastąpi ich automatyczne "związanie" z pakunkiem będącym kontenerem servletów (obecnie Tomcat i Jetty). Właśnie owe rozszerzenie Platformy OSGi o funkcjonalność rozpoznawania pakunków będących faktycznie aplikacjami korporacyjnymi - aplikacjami webowymi - jest wartością Spring-DM. Wprowadzając Spring-DM do naszej aplikacji wprowadzamy jednocześnie cechy OSGi, Spring Framework oraz Java EE. Takie 3-w-1, albo po prostu OSprin-JEE-i.
Porównując wsparcie Spring-DM dla uruchamiania aplikacji springowych a aplikacjami webowymi (potencjalnie korzystającymi z elementów springowych) można zauważyć, że w przypadku aplikacji webowych są one jedynie rozpoznawane i przekazywane do kontenera servletów (który uruchomiony jest na Platformie OSGi jako pełnoprawny pakunek OSGi). Nic poza rozpoznaniem aplikacji webowych nie pozostaje w gestii Spring-DM. Tymczasem rozpoznanie aplikacji springowych skutkuje wzbudzeniem Spring-DM Extender, który wykonuje całą pracę uruchomienia pełnej maszyneri springowej.
Jest kilka istotnych kwestii do zapamiętania, aby aplikację webową uruchomić w ramach Spring-DM, które są implikowane przez prawa rządzące OSGi - kwestia widoczności klas. Domyślnie klasy należące do pakietów javax.servlet.*, WEB-INF/lib/*.jar oraz WEB-INF/classes są widoczne dla aplikacji webowej w "zwykłym" kontenerze servletów. Dodatkowo kontener ma możliwość zdefiniowania wspólnej przestrzeni klas/bibliotek dołączanych do aplikacji webowych, o którą ją rozszerza. W przypadku środowiska OSGi obowiązują bardziej restrykcyjne reguły wymagające, aby pakunek deklarował swoją przestrzeń klas przez nagłówki Import-Package oraz Bundle-Classpath w manifeście. Za ich pomocą należy skonstruować wymaganą przestrzeń klas - zawartość ładowarki klas związanej z pakunkiem. Bez nich zasady obowiązujące w specyfikacji Java Servlet są niepełne w środowisku Spring-DM. Zgodnie z adnotacją w 8. Web Support możnaby oczekiwać, aby owe deklaracje były automatycznie dodawane do pakunku przez Spring-DM, ale póki co, taka funkcjonalność nie jest dostępna. Cechą, która jest niezwykle interesująca, a wręcz wskazana, przy konstruowaniu aplikacji webowej w ramach OSGi (za pomocą Spring-DM) jest wyniesienie bibliotek aplikacji poza jej strukturę katalogową, co przy bardzo radykalnym podejściu skończy się pustymi katalogami WEB-INF/lib oraz WEB-INF/classes, a ich zawartość zostanie uruchomiona w ramach OSGi jako osobne pakunki związane z aplikacją przez nagłówki Import-Package (opcjonalnie Require-Bundle) w manifeście. Uaktualnienie aplikacji o nową funkcjonalność, bądź wdrożenie poprawek, to wyłącznie uaktualnienie pakunków OSGi. Niezwykle potężne oręże upraszczające tworzenie aplikacji webowych ze Spring-DM.
Rozdział 8. Web Support nie pozostawia złudzeń, czego możemy dodatkowo oczekiwać od Spring Dynamic Modules (Spring-DM) poza podstawową cechą jako jest wsparcie dla tworzenia pakunków OSGi korzystając ze Spring Framework. Mowa w nim o wsparciu dla aplikacji webowych (będącymi dystrybuowane jako war - plik jar z odpowiednią strukturą katalogową, np. konieczność istnienia WEB-INF/web.xml) będącymi de facto pakunkami OSGi. Jeśli ktokolwiek zastanawiał się nad sensownością zastosowania OSGi w swoich aplikacjach, to przynajmniej obszar aplikacji webowych powinien być już rozwikłany z pomocą tego rozdziału. Spring-DM łączy cechy OSGi z Korporacyjną Javą udostępniając niezbędne elementy jako pakunki OSGi - kontener servletów jak i samą aplikację webową - które wiąże mechanizmami OSGi. Spring-DM to po prostu warstwa wspierająca uruchamianie aplikacji springowych oraz webowych na Platformie OSGi.
Przyjrzyjmy się dokładniej, co takiego oferuje Spring-DM, czego nie znajdziemy w innych środowiskach. Do poprawnego uruchomienia aplikacji webowej potrzebny jest kontener servletów (być może z jsp, ale kto by tego obecnie używał?!). Podstawowym bytem Platformy OSGi jest pakunek. Jeśli cokolwiek miałoby być uruchomione na Platformie OSGi musi być pakunkiem. Pakunek OSGi to zwykły plik jar z odpowiednimi nagłówkami w META-INF/MANIFEST.MF i stąd wypływa niezwykłość OSGi - niby nic szczególnego, a za darmo mamy możliwości niebagatelnej wartości, m.in. wersjonowanie, dedykowane ładowarki klas, uprawnienia, co z kolei składa się na funkcjonalność uktualniania aplikacji bez konieczności jej zatrzymywania. Połączenie elementów Java EE z OSGi polega na udostępnieniu tych pierwszych jako pakunków OSGi i...tyle. Już możemy okrzyknąć nasze rozwiązanie jako zgodne z pryncypiami OSGi. Do tego wcale nie potrzeba Spring-DM. Gdzie dostrzeżemy zaletę jego wykorzystania, to w sposobie integracji trzech (!) technologii OSGi, Java EE oraz Spring Framework - podczas uruchomienia pakunku OSGi z rozszerzeniem pliku .war, lub zawierającego specyficzne dla Spring-DM nagłówki w manifeście, nastąpi ich automatyczne "związanie" z pakunkiem będącym kontenerem servletów (obecnie Tomcat i Jetty). Właśnie owe rozszerzenie Platformy OSGi o funkcjonalność rozpoznawania pakunków będących faktycznie aplikacjami korporacyjnymi - aplikacjami webowymi - jest wartością Spring-DM. Wprowadzając Spring-DM do naszej aplikacji wprowadzamy jednocześnie cechy OSGi, Spring Framework oraz Java EE. Takie 3-w-1, albo po prostu OSprin-JEE-i.
Porównując wsparcie Spring-DM dla uruchamiania aplikacji springowych a aplikacjami webowymi (potencjalnie korzystającymi z elementów springowych) można zauważyć, że w przypadku aplikacji webowych są one jedynie rozpoznawane i przekazywane do kontenera servletów (który uruchomiony jest na Platformie OSGi jako pełnoprawny pakunek OSGi). Nic poza rozpoznaniem aplikacji webowych nie pozostaje w gestii Spring-DM. Tymczasem rozpoznanie aplikacji springowych skutkuje wzbudzeniem Spring-DM Extender, który wykonuje całą pracę uruchomienia pełnej maszyneri springowej.
Jest kilka istotnych kwestii do zapamiętania, aby aplikację webową uruchomić w ramach Spring-DM, które są implikowane przez prawa rządzące OSGi - kwestia widoczności klas. Domyślnie klasy należące do pakietów javax.servlet.*, WEB-INF/lib/*.jar oraz WEB-INF/classes są widoczne dla aplikacji webowej w "zwykłym" kontenerze servletów. Dodatkowo kontener ma możliwość zdefiniowania wspólnej przestrzeni klas/bibliotek dołączanych do aplikacji webowych, o którą ją rozszerza. W przypadku środowiska OSGi obowiązują bardziej restrykcyjne reguły wymagające, aby pakunek deklarował swoją przestrzeń klas przez nagłówki Import-Package oraz Bundle-Classpath w manifeście. Za ich pomocą należy skonstruować wymaganą przestrzeń klas - zawartość ładowarki klas związanej z pakunkiem. Bez nich zasady obowiązujące w specyfikacji Java Servlet są niepełne w środowisku Spring-DM. Zgodnie z adnotacją w 8. Web Support możnaby oczekiwać, aby owe deklaracje były automatycznie dodawane do pakunku przez Spring-DM, ale póki co, taka funkcjonalność nie jest dostępna. Cechą, która jest niezwykle interesująca, a wręcz wskazana, przy konstruowaniu aplikacji webowej w ramach OSGi (za pomocą Spring-DM) jest wyniesienie bibliotek aplikacji poza jej strukturę katalogową, co przy bardzo radykalnym podejściu skończy się pustymi katalogami WEB-INF/lib oraz WEB-INF/classes, a ich zawartość zostanie uruchomiona w ramach OSGi jako osobne pakunki związane z aplikacją przez nagłówki Import-Package (opcjonalnie Require-Bundle) w manifeście. Uaktualnienie aplikacji o nową funkcjonalność, bądź wdrożenie poprawek, to wyłącznie uaktualnienie pakunków OSGi. Niezwykle potężne oręże upraszczające tworzenie aplikacji webowych ze Spring-DM.
15 września 2008
Bundle.findEntries() i spring-osgi-bundle-archetype w akcji - monitorowanie pakunków OSGi z określoną strukturą katalogową
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ą!
W moim nowym artykule Bundle.findEntries() i spring-osgi-bundle-archetype w akcji - monitorowanie pakunków OSGi z określoną strukturą katalogową przedstawiłem funkcjonowanie metody 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. Więcej w samym artykule. Miłej lektury!
W moim nowym artykule Bundle.findEntries() i spring-osgi-bundle-archetype w akcji - monitorowanie pakunków OSGi z określoną strukturą katalogową przedstawiłem funkcjonowanie metody 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. Więcej w samym artykule. Miłej lektury!
11 września 2008
DSL dla konfiguracji Spring Framework
Nie pamiętam, co dokładnie sprawiło, że zacząłem poszukiwania znaczenia plików META-INF/spring.handlers oraz META-INF/spring.schemas w Spring Framework, ale pamiętam, że jednym z powodów było z pewnością znalezienie ich w źródłach Spring Dynamic Modules (moduł spring-osgi-core). A może to była lektura OSGi at LinkedIn: Integrating Spring DM (Part 1)? Postanowiłem samodzielnie spróbować się z tematem i po lekturze Appendix B. Extensible XML authoring sprawdzić w działaniu.
I po 10-15 minutach miałem temat rozpoznany. Na tyle, że kiedy dzisiaj pojawiło się pytanie w temacie The matching wildcard is strict, but no declaration can be found for element 'osgi:reference' od razu pośpieszyłem z odpowiedzią. To się nazywa proaktywna postawa wobec potrzeb klientów ;-)
Więcej o mechaniźmie upraszczania konfiguracji Spring Framework w moim artykule DSL dla konfiguracji Spring Framework.
I po 10-15 minutach miałem temat rozpoznany. Na tyle, że kiedy dzisiaj pojawiło się pytanie w temacie The matching wildcard is strict, but no declaration can be found for element 'osgi:reference' od razu pośpieszyłem z odpowiedzią. To się nazywa proaktywna postawa wobec potrzeb klientów ;-)
Więcej o mechaniźmie upraszczania konfiguracji Spring Framework w moim artykule DSL dla konfiguracji Spring Framework.
08 września 2008
Budowanie Spring-DM ze źródeł
Kolejny raz potwierdziła się stara maksyma, która mówi, aby rozpoczynać pracę z projektem od lektury jego dokumentacji. Tym razem od kilku dni borykałem się ze zbudowaniem Spring-DM ze źródeł i wciąż trafiałem na błąd kompilacji z braku pakietu org.osgi. Dzisiaj po uaktualnieniu wtyczki m2eclipse udało mi się zaimportować projekt Spring-DM do Eclipse Ganymede i natrafić na przysłowiową żyłę złota - readme-building.txt, gdzie napisano:
The following Maven profiles are available for selecting an OSGi platform:
equinox - Equinox 3.2.x
knopflerfish - Knopflerfish 2.0.x/2.1.x
felix - Apache Felix 1.0.x
The OSGi platform should be always specified otherwise the project will not compile.
co sprowadza się do uruchomienia polecenia mvn clean install z określeniem profilu z bibliotekami Platformy OSGi, np. equinox, tj.

Zgłosiłem jako OSGI-618 Define equinox as default OSGi platform while builing i dołączyłem łatkę. To już kolejne (drobne) zgłoszenie w Spring-DM.
The following Maven profiles are available for selecting an OSGi platform:
equinox - Equinox 3.2.x
knopflerfish - Knopflerfish 2.0.x/2.1.x
felix - Apache Felix 1.0.x
The OSGi platform should be always specified otherwise the project will not compile.
co sprowadza się do uruchomienia polecenia mvn clean install z określeniem profilu z bibliotekami Platformy OSGi, np. equinox, tj.
mvn -P equinox clean installPo tym proces budowania Spring-DM zakończył się z BUILD SUCCESSFUL po niespełna 3 minutach (!)
[INFO] ------------------------------------------------------------------------Bajecznie! Zastanawiam się, dlaczego nie zdefiniowano equinox jako domyślnego profilu w głównym pom.xml projektu? Z m2eclipse to jedynie włączenie Active by default w zakładce Profiles.
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Spring Dynamic Modules ................................ SUCCESS [2.968s]
[INFO] Spring OSGi Mocks ..................................... SUCCESS [1:05.110s]
[INFO] Spring OSGi IO ........................................ SUCCESS [8.625s]
[INFO] Spring OSGi Core ...................................... SUCCESS [36.407s]
[INFO] Spring OSGi Extender .................................. SUCCESS [7.422s]
[INFO] Spring OSGi Testing Framework ......................... SUCCESS [18.828s]
[INFO] Spring OSGi Web Support ............................... SUCCESS [21.906s]
[INFO] Spring OSGi Web Extender .............................. SUCCESS [5.109s]
[INFO] Spring OSGi Archetype ................................. SUCCESS [2.750s]
[INFO] Spring OSGi Annotations ............................... SUCCESS [2.516s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 minutes 54 seconds

Zgłosiłem jako OSGI-618 Define equinox as default OSGi platform while builing i dołączyłem łatkę. To już kolejne (drobne) zgłoszenie w Spring-DM.
23 sierpnia 2008
maven-jetty-plugin i JPA ze springowym SimpleLoadTimeWeaver
W mojej krucjacie ku stworzeniu aplikacji webowej z użyciem minimalnego zestawu uruchomieniowego, z facelets oraz maven-jetty-plugin dotarłem do momentu, w którym koniecznym stało się wykorzystanie jakiegoś rozwiązania ORM (mapującego dane relacyjne na obiektowe i vice versa). Nie będę zbyt odkrywczy, jeśli napiszę, że padło na JPA (Java Persistence API). Przypomnę, że nie mam do dyspozycji serwera aplikacyjnego Java EE 5, np. Apache Geronimo, więc postanowiłem skorzystać ze Spring Framework. Zwrócenie się ku Spring Framework było podyktowane chęcią utrzymania minimalnego zestawu uruchomieniowego, którego uruchomienie sprowadzało się do mvn clean jetty:run. Konfigurację JPA oparłem na opisanej w artykule Apache Wicket z JPA z pomocą Spring Framework i Apache Maven 2. Jedyną znaczącą zmianą w stosunku do konfiguracji z artykułu było skorzystanie ze Spring Framework 2.5.5. Ku mojemu zaskoczeniu pierwsze uruchomienie zakończyło się wyjątkiem:
31 faceletsPU WARN [main] openjpa.Runtime - An error occurred while registering a ClassTransformer with PersistenceUnitInfo:Rozwiązaniem okazało się zmiana atrybutu loadTimeWeaver w konfiguracji org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean na org.springframework.instrument.classloading.SimpleLoadTimeWeaver, czyli ostatecznie sekcja dotycząca konfiguracji fabryki zarządcy utrwalania w applicationContext.xml wygląda następująco:
name 'faceletsPU', root URL [file:/C:/projs/sandbox/facelets-spring/target/classes/].
The error is logged along with this warning. Load-time class transformation will not be available.
java.lang.IllegalStateException: Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation.
at org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver.addTransformer(InstrumentationLoadTimeWeaver.java:88)
at org.springframework.orm.jpa.persistenceunit.SpringPersistenceUnitInfo.addTransformer(SpringPersistenceUnitInfo.java:80)
at org.apache.openjpa.persistence.PersistenceProviderImpl.createContainerEntityManagerFactory(PersistenceProviderImpl.java:126)
at org.apache.openjpa.persistence.PersistenceProviderImpl.createContainerEntityManagerFactory(PersistenceProviderImpl.java:53)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:224)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:291)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1368)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
<bean id="entityManagerFactory"Więcej informacji o konfiguracji JPA w Spring Framework, w rozdziale 12.6 "JPA" dokumentacji The Spring Framework - Reference Documentation.
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="oracleDS" />
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver" />
</property>
</bean>
04 maja 2008
Aplikacja webowa jako pakunek OSGi ze Spring Dynamic Modules
Wciąż chodzi mi po głowie sposób tworzenia aplikacji webowej na platformie OSGi, gdzie jej elementy składowe będą faktycznie pakunkami OSGi, które można włączać/wyłączać/uaktualniać dynamicznie bez konieczności jej zatrzymywania, o wielu wersjach tej samej biblioteki w środowisku nie wspominając. Po ostatnim spotkaniu z OSGi skończyło się na skorzystaniu ze Spring Dynamic Modules (Spring-DM). Jednym ze sztandarowych cech najnowszej wersji Spring-DM 1.1.0 M2 jest wsparcie dla uruchamiania aplikacji webowych jako pakunków OSGi. To jest dokładnie to, czego szukałem (chociaż przyznaję, że nie starałem się jakoś specjalnie znaleźć coś innego niż właśnie Spring-DM).
Lekturę dokumentacji Spring-DM rozpocząłem od rozdziału 8. Web Support. Wcześniej czytałem pozostałe rozdziały, więc od razu przeszedłem do sedna. To właśnie lektura rozdziału uzmysłowiła mi, że format dystrybucji aplikacji webowej - plik war - jest faktycznie jarem, a pakunek osgi to właśnie plik jar z odpowiednimi nagłówkami w manifeście (META-INF/MANIFEST.MF). Idąć tym tropem można sobie wyobrazić sytuację, w której umieszczając obowiązkowy nagłówek OSGi - Bundle-SymbolicName - do manifestu w paczce aplikacji webowej nadajemy jej cechy pakunku w środowisku OSGi. Pozostaje jeszcze powiązać oba światy pod względem ich wymagań, np. widoczności klas i pomysł uruchamiania aplikacji webowych jako pakunków OSGi zostanie zmaterializowany. Właśnie taki cel obrał projekt Spring-DM.
Kwintesencją Spring-DM jest następujący zapis w jego dokumentacji:
Spring-DM addresses these problems by bridging the web container and the OSGi space so loading is no longer a concern. Unique in its functionality, the web support in Spring-DM integrates directly with the web container so the WAR processing is literally handled by the server.[...] In short, everything that the target container supports is available to the OSGi WAR through Spring-DM.
Początkowo trudno było mi zrozumieć, co autor miał na myśli, ale teraz po dniu pracy ze Spring-DM sprawa wydaje się być całkowicie oczywista (zakładam, że taka będzie również dla czytelników - rozczarowanych uprasza się o kontakt ;-)). W skrócie, temat sprowadza się do takiego uruchomienia aplikacji webowej, aby jej cechy aplikacji webowej były respektowane w ramach platformy OSGi i odwrotnie, tj. cechy pakunku OSGi (i zasady oraz obowiązki z tego wynikające) będą respektowane przez kontener aplikacji webowej. Nie oznacza to jednak, że samo tworzenie aplikacji webowej powinno zmienić się z punktu widzenia jej twórcy, aczkolwiek uruchomienie na platformie OSGi daje tą zaletę, że jej zależności to zależności pakunku OSGi, więc za pomocą mechanizmów udostępnianych przez platformę OSGi istnieje możliwość zarządzania nimi dynamicznie, w trakcie działania aplilkacji oraz ich automatyczne wersjonowanie. Weźmy na tapetę biblioteki aplikacji webowej umieszczane w katalogu WEB-INF/lib (podobnie będzie z klasami w WEB-INF/classes). Specyfikacja Java Servlet gwarantuje, że oba katalogi WEB-INF/{lib,classes} są dostępne dla zarządcy klas aplikacji webowej. W przypadku pakunku OSGi tak nie jest. Tutaj sprawa jest obwarowana zasadami, które mówią, że pakunek ma dostęp wyłącznie do klas/interfejsów w ramach pakunku oraz tych zależności zewnętrznych zadeklarowanych przez nagłówki Import-Package czy Bundle-Classpath w manifeście. Katalog WEB-INF/lib nie jest niczym specjalnym z punktu widzenia pakunku OSGi, chyba że jest jawnie zadeklarowany we wspomnianym Bundle-Classpath. Podobnie sprawa się tyczy bibliotek zapewnianych przez kontener serwletów, np. javax.servlet. Tylko tyle pakunek OSGi "zobaczy", ile zadeklaruje w Bundle-Classpath i/lub Import-Package. Całe te zawiłości, początkowo mogące być postrzegane jako utrudnienia, dają tę zaletę, że udostępniamy pakunkowi OSGi, który jest aplikacji webową, biblioteki dynamicznie i ich zarządzanie staje się dynamiczne. Jedną z wiodących cech takiego podejścia, jest spowodowanie, że biblioteki, które zazwyczaj znajdowały się w WEB-INF/lib, teraz również instaluje się w środowisku OSGi jako pakunki OSGi, a aplikacje webowe, które jej wymagają deklarują odpowiednią zależność w manifeście (dla już przestraszonych skomplikowaniem sprawy tworzenia aplikacji webowej jako pakunku OSGi, a jeszcze nie dostrzegających zalet takiego podejścia, nadmienię tylko, że Spring-DM poprzez mechanizm wtyczek mavenowych wykrywa zależności i samodzielnie tworzy odpowiedni plik manifestu w trakcie budowania aplikacji). Podsumowując zarządzanie klasami zlecone jest platformie OSGi, więc prawa rządzące aplikacją webową, w kontekście widoczności klas z pakietu javax.servlet i podobnych oraz WEB-INF/{classes,lib} muszą być zadeklarowane w pakunku OSGi explicite (opisane jest to w części 8.3.2. Servlets). Obowiązkowo należy dodać Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources, które zgodnie ze specyfikacją Java Servlet są automatycznie udostępniane przez kontener serwletów, a w przypadku OSGi muszą być jawnie zadeklarowane (bo nie są niczym szczególnym z punktu widzenia środowiska OSGi).
Podkreślając znaczenie uwspólniania zależności aplikacji webowych przytoczę wycinek dokumentacji Spring-DM - rozdział 8.3.2 Servlets:
Before creating entries for embedded libraries, consider whether the library cannot be installed as an OSGi bundle - doing so will allow it to be shared with other WARs if needed and since OSGi allows versioning, it is perfectly okay to have multiple versions of the library inside the same VM.
Dzięki uaktywnieniu bibliotek wykorzystywanych przez pojedyńczą aplikację webową jako pakunków OSGi (jedynie dodanie odpowiednich nagłówków do manifestu aplikacji) oraz ich instalacja poza tą jedną aplikacją webową mamy możliwość udostępnienia jej dla innych pakunków OSGi, niekoniecznie będących aplikacjami webowymi, oraz najistotniejsze, mamy możliwość dynamicznego uaktualniania jej w trakcie pracy systemu zrzucając na barki platformy OSGi zarządzanie zależnościami - dostępnością klas, niszczeniem dostawców klas czy utrzymaniem wielu wersji w trakcie korzystania z klasy w pakunku, który właśnie jest uaktualniany. Za pomocą Spring-DM mamy możliwość połączenia dwóch światów OSGi oraz aplikacji webowych w jeden, co wymaga od nas postrzegania tworzenia aplikacji webowych, a zmiana wpływa na większą modularyzację aplikacji. Tym razem widzę same zalety stosowania Springa (niejednokrotnie podkreślałem, że Spring nie jest lekarstwem na wszystko i mogłobyć to odebrane jako niechęć w jego wykorzystaniu, co już w przypadku Spring-DM można odczuć nie jest prawdą). O takim podejściu do tworzenia aplikacji webowych pisał chociażby Daniel w komentarzu do wpisu Nawigacja w Wicket:
Jak widać po Twoich wpisach OSGi nie jest Ci obce, dlatego zdziwiło mnie zdanie: "to nie wiem jaki miałby zysk wdrożenie OSGi mając na pokładzie Spring + Wicket." :) Przecież korzyści jakie płyną z wykorzystania OSGi są w miarę jasne, chociażby podstawowa: dobre wsparcie dla modularyzacji aplikacji.
Naczytałem się o Spring DM i jego zaletach aktywacji aplikacji webowych jako pakunków OSGi, albo raczej ich uruchomienia na platformie OSGi z Jetty (domyślnie jest już pakunkiem OSGi i Spring-DM dodaje jedynie aktywator pakunku) lub Tomcat (Spring-DM tworzy z niego pakunek OSGi - wpisy w manifeście - oraz dodaje aktywator), ale nie znalazłem chociażby przykładu jakby to ugryźć. Niestety, ale o jakości dokumentacji również nie mogę napisać w samych superlatywach i liczba błędów w dokumentacji Spring DM oraz oraz brak potrzebnych zależności w dystrybucji Spring-DM świadczą o zbytnim pośpiechu (co ma tą zaletę, że wypuszcza się na rynek produkt do ewaluacji i daje możliwość zrozumienia problemu, który rozwiązuje, a błędy poprawia się w kolejnych iteracjach).
Popróbuję się więc z tymi atrakcjami Spring-DM w kontekście uruchamiania aplikacji webowych jako pakunków OSGi. Zacznę od stworzenia projektu. I tu pytanie numer 1. - jak stworzyć projekt, aby skorzystać z spring-osgi-bundle-archetype tworząc projekt aplikacji webowej? Na stronie Spring Dynamic Modules Demos znajdują się dwie prezentacje tworzenia przykładowych aplikacji z użyciem Spring-DM i do utworzenia projektu wystarczył jedynie domyślny archetyp. Tyle tylko, że tam nie było aplikacji webowej (!) Nie zakładałem, że będzie łatwo, ale już na początku takie problemy?! Nie wygląda to zachęcająco.
Rozpocznę od archetypu maven-archetype-webapp, gdyż chcę uniknąć zawiłości związanych z bardziej zaawansowanymi szkieletami webowymi, np. korzystających z JSF, kiedy przyjdzie mi je uruchamiać na OSGi po raz pierwszy z pomocą Spring-DM, a bez dostępnych bibliotek jako pakunków OSGi (parametr -U dodałem wyłącznie dla celów ochronnych opisanych w Niuanse Apache Maven 2 - opcja -U).
Buduję aplikację webową i podchodzę do jej instalacji na Apache Felix 1.0.4 z Spring-DM.
Rozpoczynam instalację pakunków OSGi dostarczanych przez Spring-DM - dostępne w katalogach dist oraz lib. Instaluję:
Na zakończenie przychodzi mi instalować moją aplikację webową i wierzyć, że zostanie rozpoznana i poprawnie zainstalowana w kontenerze servletów przez Spring-DM.
W trakcie uaktualniania pakunku na Felix 1.0.4 natrafiłem na błąd, gdzie pakunek musiał koniecznie mieć rozszerzenie pliku jar, aby został zaakceptowany przez polecenie update - zgłosiłem jako FELIX-544 update command should accept other file extensions than jar only.
Dodaję do pom.xml:
I dalej, rozdział 2. Requirements opisuje wymaganie Bundles deployed for use with Spring Dynamic Modules should specify "Bundle-ManifestVersion: 2" in their manifest (OSGi R4). Koniecznie należy jawnie określić wersję pakunku, gdyż domyślna wartość to 1, która najwyraźniej nie jest rozpoznawana przez Spring-DM.
Za specyfikacją OSGi 4.1 strona 27:
3.2.1.10 Bundle-ManifestVersion: 2
The Bundle-ManifestVersion header defines that the bundle follows the rules of this specification. The Bundle-ManifestVersion header determines whether the bundle follows the rules of this specification. It is 1 (the default) for Release 3 Bundles, 2 for Release 4 and later. Future version of the OSGi Service Platform can define higher numbers for this header.
Dodaję
W 8.2. Web support usage napisano:
To use Spring-DM Web, install:
* spring-osgi-web.jar - Spring-DM web support
* spring-osgi-web-extender.jar - Spring-DM web extender
Niestety, ale już na starcie trudno spełnić to wymaganie, bo nie istnieje spring-osgi-web-extender.jar w katalogu lib lub dist w dystrybucji Spring-DM 1.1.0 M2, a jedynie spring-osgi-extender.jar (!) Nie obejdzie się bez pobrania jej z repozytorium S3 jako spring-osgi-web-extender-1.1.0-m2-20080425.012916-2.jar.
W końcu trochę zniecierpliwiony tymi niespodziankami zabrałem się za przeglądanie kodów źródłowych z repozytorium Spring-DM. Niestety próba zbudowania ich za pomocą polecenia mvn -P equinox,it clean install zakończyła się komunikatem błędu o niedostępności biblioteki do obsługi repozytorium S3 - net.java.dev.jets3t:jets3t:jar:0.5.1-20080115. Ech, jakby nie chciano, abym skosztował tych wszystkich nowości, którymi szczyci się Spring-DM 1.1.0-m2.
Dodałem do pom.xml następujący wpis:

Wciąż jednak strony JSP nie są poprawnie kompilowane. Stan platformy OSGi (Felix 1.0.4) prezentuje się następująco:

Aplikacja webowa spring-osgi-webapp działa!
Na koniec jeszcze raz próba z z Apache Felix 1.0.4 (coś mnie tknęło, że to jednak moja wcześniejsza niewiedza niż niedoskonałości Feliksa były przyczyną niepowodzenia).
A na koniec ciekawa lektura SpringSource Launches New Application Server without Java EE. I co?! Kto już o tym wspominał rok temu, że aspiracjami i21 czy teraz SpringSource to właśnie rynek serwerów aplikacyjnych, gdzie możnaby potraktować Spring Framework z dodatkami jako właśnie serwer aplikacyjny?! Ciekawe, co teraz oponenci takiego spojrzenia mają do powiedzenia?! Zamieniam się w słuch...
Pytanie konkursowe: Jaki nagłówek manifestu służy Spring-DM do rozpoznania pakunku aplikacji webowej do uruchomienia? Nagród nie przewiduje się.
Lekturę dokumentacji Spring-DM rozpocząłem od rozdziału 8. Web Support. Wcześniej czytałem pozostałe rozdziały, więc od razu przeszedłem do sedna. To właśnie lektura rozdziału uzmysłowiła mi, że format dystrybucji aplikacji webowej - plik war - jest faktycznie jarem, a pakunek osgi to właśnie plik jar z odpowiednimi nagłówkami w manifeście (META-INF/MANIFEST.MF). Idąć tym tropem można sobie wyobrazić sytuację, w której umieszczając obowiązkowy nagłówek OSGi - Bundle-SymbolicName - do manifestu w paczce aplikacji webowej nadajemy jej cechy pakunku w środowisku OSGi. Pozostaje jeszcze powiązać oba światy pod względem ich wymagań, np. widoczności klas i pomysł uruchamiania aplikacji webowych jako pakunków OSGi zostanie zmaterializowany. Właśnie taki cel obrał projekt Spring-DM.
Kwintesencją Spring-DM jest następujący zapis w jego dokumentacji:
Spring-DM addresses these problems by bridging the web container and the OSGi space so loading is no longer a concern. Unique in its functionality, the web support in Spring-DM integrates directly with the web container so the WAR processing is literally handled by the server.[...] In short, everything that the target container supports is available to the OSGi WAR through Spring-DM.
Początkowo trudno było mi zrozumieć, co autor miał na myśli, ale teraz po dniu pracy ze Spring-DM sprawa wydaje się być całkowicie oczywista (zakładam, że taka będzie również dla czytelników - rozczarowanych uprasza się o kontakt ;-)). W skrócie, temat sprowadza się do takiego uruchomienia aplikacji webowej, aby jej cechy aplikacji webowej były respektowane w ramach platformy OSGi i odwrotnie, tj. cechy pakunku OSGi (i zasady oraz obowiązki z tego wynikające) będą respektowane przez kontener aplikacji webowej. Nie oznacza to jednak, że samo tworzenie aplikacji webowej powinno zmienić się z punktu widzenia jej twórcy, aczkolwiek uruchomienie na platformie OSGi daje tą zaletę, że jej zależności to zależności pakunku OSGi, więc za pomocą mechanizmów udostępnianych przez platformę OSGi istnieje możliwość zarządzania nimi dynamicznie, w trakcie działania aplilkacji oraz ich automatyczne wersjonowanie. Weźmy na tapetę biblioteki aplikacji webowej umieszczane w katalogu WEB-INF/lib (podobnie będzie z klasami w WEB-INF/classes). Specyfikacja Java Servlet gwarantuje, że oba katalogi WEB-INF/{lib,classes} są dostępne dla zarządcy klas aplikacji webowej. W przypadku pakunku OSGi tak nie jest. Tutaj sprawa jest obwarowana zasadami, które mówią, że pakunek ma dostęp wyłącznie do klas/interfejsów w ramach pakunku oraz tych zależności zewnętrznych zadeklarowanych przez nagłówki Import-Package czy Bundle-Classpath w manifeście. Katalog WEB-INF/lib nie jest niczym specjalnym z punktu widzenia pakunku OSGi, chyba że jest jawnie zadeklarowany we wspomnianym Bundle-Classpath. Podobnie sprawa się tyczy bibliotek zapewnianych przez kontener serwletów, np. javax.servlet. Tylko tyle pakunek OSGi "zobaczy", ile zadeklaruje w Bundle-Classpath i/lub Import-Package. Całe te zawiłości, początkowo mogące być postrzegane jako utrudnienia, dają tę zaletę, że udostępniamy pakunkowi OSGi, który jest aplikacji webową, biblioteki dynamicznie i ich zarządzanie staje się dynamiczne. Jedną z wiodących cech takiego podejścia, jest spowodowanie, że biblioteki, które zazwyczaj znajdowały się w WEB-INF/lib, teraz również instaluje się w środowisku OSGi jako pakunki OSGi, a aplikacje webowe, które jej wymagają deklarują odpowiednią zależność w manifeście (dla już przestraszonych skomplikowaniem sprawy tworzenia aplikacji webowej jako pakunku OSGi, a jeszcze nie dostrzegających zalet takiego podejścia, nadmienię tylko, że Spring-DM poprzez mechanizm wtyczek mavenowych wykrywa zależności i samodzielnie tworzy odpowiedni plik manifestu w trakcie budowania aplikacji). Podsumowując zarządzanie klasami zlecone jest platformie OSGi, więc prawa rządzące aplikacją webową, w kontekście widoczności klas z pakietu javax.servlet i podobnych oraz WEB-INF/{classes,lib} muszą być zadeklarowane w pakunku OSGi explicite (opisane jest to w części 8.3.2. Servlets). Obowiązkowo należy dodać Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources, które zgodnie ze specyfikacją Java Servlet są automatycznie udostępniane przez kontener serwletów, a w przypadku OSGi muszą być jawnie zadeklarowane (bo nie są niczym szczególnym z punktu widzenia środowiska OSGi).
Podkreślając znaczenie uwspólniania zależności aplikacji webowych przytoczę wycinek dokumentacji Spring-DM - rozdział 8.3.2 Servlets:
Before creating entries for embedded libraries, consider whether the library cannot be installed as an OSGi bundle - doing so will allow it to be shared with other WARs if needed and since OSGi allows versioning, it is perfectly okay to have multiple versions of the library inside the same VM.
Dzięki uaktywnieniu bibliotek wykorzystywanych przez pojedyńczą aplikację webową jako pakunków OSGi (jedynie dodanie odpowiednich nagłówków do manifestu aplikacji) oraz ich instalacja poza tą jedną aplikacją webową mamy możliwość udostępnienia jej dla innych pakunków OSGi, niekoniecznie będących aplikacjami webowymi, oraz najistotniejsze, mamy możliwość dynamicznego uaktualniania jej w trakcie pracy systemu zrzucając na barki platformy OSGi zarządzanie zależnościami - dostępnością klas, niszczeniem dostawców klas czy utrzymaniem wielu wersji w trakcie korzystania z klasy w pakunku, który właśnie jest uaktualniany. Za pomocą Spring-DM mamy możliwość połączenia dwóch światów OSGi oraz aplikacji webowych w jeden, co wymaga od nas postrzegania tworzenia aplikacji webowych, a zmiana wpływa na większą modularyzację aplikacji. Tym razem widzę same zalety stosowania Springa (niejednokrotnie podkreślałem, że Spring nie jest lekarstwem na wszystko i mogłobyć to odebrane jako niechęć w jego wykorzystaniu, co już w przypadku Spring-DM można odczuć nie jest prawdą). O takim podejściu do tworzenia aplikacji webowych pisał chociażby Daniel w komentarzu do wpisu Nawigacja w Wicket:
Jak widać po Twoich wpisach OSGi nie jest Ci obce, dlatego zdziwiło mnie zdanie: "to nie wiem jaki miałby zysk wdrożenie OSGi mając na pokładzie Spring + Wicket." :) Przecież korzyści jakie płyną z wykorzystania OSGi są w miarę jasne, chociażby podstawowa: dobre wsparcie dla modularyzacji aplikacji.
Naczytałem się o Spring DM i jego zaletach aktywacji aplikacji webowych jako pakunków OSGi, albo raczej ich uruchomienia na platformie OSGi z Jetty (domyślnie jest już pakunkiem OSGi i Spring-DM dodaje jedynie aktywator pakunku) lub Tomcat (Spring-DM tworzy z niego pakunek OSGi - wpisy w manifeście - oraz dodaje aktywator), ale nie znalazłem chociażby przykładu jakby to ugryźć. Niestety, ale o jakości dokumentacji również nie mogę napisać w samych superlatywach i liczba błędów w dokumentacji Spring DM oraz oraz brak potrzebnych zależności w dystrybucji Spring-DM świadczą o zbytnim pośpiechu (co ma tą zaletę, że wypuszcza się na rynek produkt do ewaluacji i daje możliwość zrozumienia problemu, który rozwiązuje, a błędy poprawia się w kolejnych iteracjach).
Popróbuję się więc z tymi atrakcjami Spring-DM w kontekście uruchamiania aplikacji webowych jako pakunków OSGi. Zacznę od stworzenia projektu. I tu pytanie numer 1. - jak stworzyć projekt, aby skorzystać z spring-osgi-bundle-archetype tworząc projekt aplikacji webowej? Na stronie Spring Dynamic Modules Demos znajdują się dwie prezentacje tworzenia przykładowych aplikacji z użyciem Spring-DM i do utworzenia projektu wystarczył jedynie domyślny archetyp. Tyle tylko, że tam nie było aplikacji webowej (!) Nie zakładałem, że będzie łatwo, ale już na początku takie problemy?! Nie wygląda to zachęcająco.
Rozpocznę od archetypu maven-archetype-webapp, gdyż chcę uniknąć zawiłości związanych z bardziej zaawansowanymi szkieletami webowymi, np. korzystających z JSF, kiedy przyjdzie mi je uruchamiać na OSGi po raz pierwszy z pomocą Spring-DM, a bez dostępnych bibliotek jako pakunków OSGi (parametr -U dodałem wyłącznie dla celów ochronnych opisanych w Niuanse Apache Maven 2 - opcja -U).
jlaskowski@work /cygdrive/c/projs/osgiTemat obsługi manifestu sprowadzę do konfiguracji wtyczki maven-war-plugin. Dodaję odpowiednią sekcję do pom.xml i konfiguruję obowiązkowy nagłówek Bundle-SymbolicName (korzystam z pomocy Eclipse i jego wtyczki Maven Integration for Eclipse - m2eclipse).
$ mvn -U archetype:create -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=pl.jaceklaskowski.osgi -DartifactId=spring-osgi-webapp
...
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating OldArchetype: maven-archetype-webapp:RELEASE
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: pl.jaceklaskowski.osgi
[INFO] Parameter: packageName, Value: pl.jaceklaskowski.osgi
[INFO] Parameter: basedir, Value: c:\projs\osgi
[INFO] Parameter: package, Value: pl.jaceklaskowski.osgi
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: artifactId, Value: spring-osgi-webapp
[INFO] ********************* End of debug info from resources from generated POM ***********************
[INFO] OldArchetype created in dir: c:\projs\osgi\spring-osgi-webapp
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
<plugin>Uruchomienie aplikacji webowej jako pakunku OSGi spróbuję z Apache Felix 1.0.4 jako platformie OSGi. W 5.3. Required Spring Framework and Spring Dynamic Modules Bundles opisano wszystkie niezbędne pakunki, które należy uruchomić dla poprawnego uruchomienia pakunku dowolnej aplikacji webowej. Nie trwało długo, zanim okazało się, że Spring-DM 1.1.0 M2 dostarcza jedynie część z wymaganych bibliotek, a w tym brakuje najważniejszej - spring-osgi-web-extender (!)
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<archive>
<manifestEntries>
<Bundle-SymbolicName>${groupId}.${artifactId}</Bundle-SymbolicName>
</manifestEntries>
</archive>
</configuration>
</plugin>
Buduję aplikację webową i podchodzę do jej instalacji na Apache Felix 1.0.4 z Spring-DM.
jlaskowski@work /cygdrive/c/projs/osgi/spring-osgi-webappSposób w jaki działa Spring-DM to dostarczenie pakunku spring-osgi-web-extender, który monitoruje zainstalowane pakunki i rozpoznaje, które są aplikacjami webowymi. Jeśli trafi się jedna, to następuje zainstalowanie jej na kontenerze servletów (Tomcat lub Jetty), który jest również pakunkiem OSGi dostarczanym przez Spring-DM.
$ mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building spring-osgi-webapp Maven Webapp
[INFO] task-segment: [package]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] No sources to compile
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] No sources to compile
[INFO] [surefire:test]
[INFO] No tests to run.
[INFO] [war:war]
[INFO] Exploding webapp...
[INFO] Assembling webapp spring-osgi-webapp in c:\projs\osgi\spring-osgi-webapp\target\spring-osgi-webapp
[INFO] Copy webapp webResources to c:\projs\osgi\spring-osgi-webapp\target\spring-osgi-webapp
[INFO] Generating war c:\projs\osgi\spring-osgi-webapp\target\spring-osgi-webapp.war
[INFO] Building war: c:\projs\osgi\spring-osgi-webapp\target\spring-osgi-webapp.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
Rozpoczynam instalację pakunków OSGi dostarczanych przez Spring-DM - dostępne w katalogach dist oraz lib. Instaluję:
- dist/spring-osgi-web-1.1.0-m2.jar
- lib/servlet-api.osgi-2.5-SNAPSHOT.jar
- lib/slf4j-log4j12-1.4.3.jar
- lib/jcl104-over-slf4j-1.4.3.jar
- lib/slf4j-api-1.4.3.jar
- lib/log4j.osgi-1.2.15-SNAPSHOT.jar
Na zakończenie przychodzi mi instalować moją aplikację webową i wierzyć, że zostanie rozpoznana i poprawnie zainstalowana w kontenerze servletów przez Spring-DM.
W trakcie uaktualniania pakunku na Felix 1.0.4 natrafiłem na błąd, gdzie pakunek musiał koniecznie mieć rozszerzenie pliku jar, aby został zaakceptowany przez polecenie update - zgłosiłem jako FELIX-544 update command should accept other file extensions than jar only.
-> update 10 file:/C:/projs/osgi/spring-osgi-webapp/target/spring-osgi-webapp.warNiestety żadnych komunikatów, aby jakakolwiek akcja została wykonana po instalacji aplikacji webowej. Coś nie gra. Pytanie jak to sprawdzić? Jeszcze raz zaglądam do dokumentacji, gdzie znalazłem, że aplikacja webowa zostanie rozpoznana przez Spring DM jedynie, jeśli spełnia jeden z poniższych warunków: zawiera katalog META-INF/spring bądź nagłówek Spring-Context (więcej w 5.1. Bundle format and Manifest headers).
Unable to open input stream: java.io.FileNotFoundException:
C:\projs\osgi\spring-osgi-webapp\target\spring-osgi-webapp.war.jar (The system cannot find the file specified)
-> uninstall 10
-> install file:/C:/projs/osgi/spring-osgi-webapp/target/spring-osgi-webapp.war
Bundle ID: 11
-> start 11
-> ps
START LEVEL 1
ID State Level Name
[ 0] [Active ] [ 0] System Bundle (1.0.4)
[ 1] [Active ] [ 1] Apache Felix Shell Service (1.0.1)
[ 2] [Active ] [ 1] Apache Felix Shell TUI (1.0.1)
[ 3] [Active ] [ 1] Apache Felix Bundle Repository (1.0.3)
[ 4] [Active ] [ 1] spring-osgi-web (1.1.0.m2)
[ 5] [Active ] [ 1] servlet-api.osgi (2.5.0.SNAPSHOT)
[ 6] [Active ] [ 1] slf4j-log4j12 (1.4.3)
[ 7] [Active ] [ 1] jcl104-over-slf4j (1.4.3)
[ 8] [Active ] [ 1] slf4j-api (1.4.3)
[ 9] [Active ] [ 1] log4j.osgi (1.2.15.SNAPSHOT)
[ 11] [Active ] [ 1] pl.jaceklaskowski.osgi.spring-osgi-webapp
-> headers 11
Bundle 11
---------
Built-By = jlaskowski
Archiver-Version = Plexus Archiver
Created-By = Apache Maven
Build-Jdk = 1.5.0_14
Manifest-Version = 1.0
Bundle-SymbolicName = pl.jaceklaskowski.osgi.spring-osgi-webapp
Dodaję do pom.xml:
<Spring-Context>*;publish-context:=true</Spring-Context>buduję aplikację i ponownie podchodzę do instalacji (jak można zauważyć zainstalowałem w międzyczasie inne pakunki OSGi dostarczane przez Spring-DM - nazwy pakunków odpowiadają nazwom plików z katalogów dist lub lib).
-> install file:/C:/projs/osgi/spring-osgi-webapp/target/spring-osgi-webapp.war...i jeszcze kilka innych WARNINGów. Rozwiązanie w samym komunikacie i zgodnie z 8.3.2. Servlets dodaję odpowiednie zależności w pom.xml w sekcji konfiguracji wtyczki maven-war-plugin:
Bundle ID: 21
-> ps
START LEVEL 1
ID State Level Name
[ 0] [Active ] [ 0] System Bundle (1.0.4)
[ 1] [Active ] [ 1] Apache Felix Shell Service (1.0.1)
[ 2] [Active ] [ 1] Apache Felix Shell TUI (1.0.1)
[ 3] [Active ] [ 1] Apache Felix Bundle Repository (1.0.3)
[ 4] [Active ] [ 1] spring-osgi-web (1.1.0.m2)
[ 5] [Active ] [ 1] servlet-api.osgi (2.5.0.SNAPSHOT)
[ 6] [Active ] [ 1] slf4j-log4j12 (1.4.3)
[ 7] [Active ] [ 1] jcl104-over-slf4j (1.4.3)
[ 8] [Active ] [ 1] slf4j-api (1.4.3)
[ 9] [Active ] [ 1] log4j.osgi (1.2.15.SNAPSHOT)
[ 12] [Active ] [ 1] spring-osgi-extender (1.1.0.m2)
[ 13] [Active ] [ 1] spring-context (2.5.4)
[ 14] [Active ] [ 1] spring-beans (2.5.4)
[ 15] [Active ] [ 1] spring-osgi-core (1.1.0.m2)
[ 16] [Active ] [ 1] spring-core (2.5.4)
[ 17] [Active ] [ 1] aopalliance.osgi (1.0.0.SNAPSHOT)
[ 18] [Active ] [ 1] spring-osgi-io (1.1.0.m2)
[ 19] [Active ] [ 1] spring-aop (2.5.4)
[ 21] [Installed ] [ 1] pl.jaceklaskowski.osgi.spring-osgi-webapp
-> start 21
-> WARNING: *** Class 'org.springframework.beans.factory.xml.NamespaceHandlerResolver' was not found
because bundle 21 does not import 'org.springframework.beans.factory.xml' even though bundle 14 does export it.
To resolve this issue, add an import for 'org.springframework.beans.factory.xml' to bundle 21.
*** (java.lang.ClassNotFoundException: *** Class 'org.springframework.beans.factory.xml.NamespaceHandlerResolver'
was not found because bundle 21 does not import 'org.springframework.beans.factory.xml' even though bundle 14 does export it.
To resolve this issue, add an import for 'org.springframework.beans.factory.xml' to bundle 21. ***)
<Import-Package>javax.servlet,javax.servlet.http,javax.servlet.resources</Import-Package>Ponownie buduję aplikację i podchodzę do jej instalacji.
<Bundle-Classpath>.,WEB-INF/classes</Bundle-Classpath>
-> install file:/C:/projs/osgi/spring-osgi-webapp/target/spring-osgi-webapp.war...i ponownie WARNINGi, czyli dokumentacja Spring-DM nie opisuje dokładnie wymaganych importów (!) Dodaję do pom.xml kolejne:
INFO: Class path entry not found: WEB-INF/classes
Bundle ID: 23
-> start 23
DEBUG: WIRE: 23.0 -> javax.servlet.http -> 5.0
DEBUG: WIRE: 23.0 -> javax.servlet -> 5.0
DEBUG: WIRE: 23.0 -> javax.servlet.resources -> 5.0
-> WARNING: *** Class 'org.springframework.beans.factory.xml.NamespaceHandlerResolver' was not found
because bundle 23 does not import 'org.springframework.beans.factory.xml' even though bundle 14 does export it.
To resolve this issue, add an import for 'org.springframework.beans.factory.xml' to bundle 23. ***
(java.lang.ClassNotFoundException: *** Class 'org.springframework.beans.factory.xml.NamespaceHandlerResolver'
was not found because bundle 23 does not import 'org.springframework.beans.factory.xml' even though bundle 14 does export it.
To resolve this issue, add an import for 'org.springframework.beans.factory.xml' to bundle 23. ***)
<Import-Package>javax.servlet,javax.servlet.http,javax.servlet.resources,I znowu budowanie aplikacji i jej instalacja (z nadzieją, że to może już).
org.springframework.beans.factory.xml,org.springframework.aop,
org.springframework.aop.framework,org.aopalliance.aop,org.xml.sax,
org.apache.jasper.servlet,org.apache.commons.el,org.apache.catalina.servlets</Import-Package>
-> uninstall 23Niestety, jeszcze nie koniec zmagań, ale tym razem już czysto. Wciąż żadnych komunikatów związanych z uruchomieniem aplikacji. Dokumentacja wspomina o cglib-nodep jako bibliotece do tworzenia proxy, ale niestety nie ma jej w dystrybucji (!) Dodatkowo informacja o konieczności instalacji pakunku cglib-nodep znajduje się w readme.txt w katalogu lib w dystrybucji Spring DM.
-> install file:/C:/projs/osgi/spring-osgi-webapp/target/spring-osgi-webapp.war
INFO: Class path entry not found: WEB-INF/classes
Bundle ID: 24
-> start 24
DEBUG: WIRE: 24.0 -> javax.servlet.http -> 5.0
DEBUG: WIRE: 24.0 -> javax.servlet -> 5.0
DEBUG: WIRE: 24.0 -> org.xml.sax -> 0
DEBUG: WIRE: 24.0 -> org.springframework.beans.factory.xml -> 14.0
DEBUG: WIRE: 24.0 -> javax.servlet.resources -> 5.0
DEBUG: WIRE: 24.0 -> org.springframework.aop.framework -> 19.0
DEBUG: WIRE: 24.0 -> org.aopalliance.aop -> 17.0
DEBUG: WIRE: 24.0 -> org.springframework.aop -> 19.0
I dalej, rozdział 2. Requirements opisuje wymaganie Bundles deployed for use with Spring Dynamic Modules should specify "Bundle-ManifestVersion: 2" in their manifest (OSGi R4). Koniecznie należy jawnie określić wersję pakunku, gdyż domyślna wartość to 1, która najwyraźniej nie jest rozpoznawana przez Spring-DM.
Za specyfikacją OSGi 4.1 strona 27:
3.2.1.10 Bundle-ManifestVersion: 2
The Bundle-ManifestVersion header defines that the bundle follows the rules of this specification. The Bundle-ManifestVersion header determines whether the bundle follows the rules of this specification. It is 1 (the default) for Release 3 Bundles, 2 for Release 4 and later. Future version of the OSGi Service Platform can define higher numbers for this header.
Dodaję
<Bundle-ManifestVersion>2</Bundle-ManifestVersion>do pom.xml.
W 8.2. Web support usage napisano:
To use Spring-DM Web, install:
* spring-osgi-web.jar - Spring-DM web support
* spring-osgi-web-extender.jar - Spring-DM web extender
Niestety, ale już na starcie trudno spełnić to wymaganie, bo nie istnieje spring-osgi-web-extender.jar w katalogu lib lub dist w dystrybucji Spring-DM 1.1.0 M2, a jedynie spring-osgi-extender.jar (!) Nie obejdzie się bez pobrania jej z repozytorium S3 jako spring-osgi-web-extender-1.1.0-m2-20080425.012916-2.jar.
W końcu trochę zniecierpliwiony tymi niespodziankami zabrałem się za przeglądanie kodów źródłowych z repozytorium Spring-DM. Niestety próba zbudowania ich za pomocą polecenia mvn -P equinox,it clean install zakończyła się komunikatem błędu o niedostępności biblioteki do obsługi repozytorium S3 - net.java.dev.jets3t:jets3t:jar:0.5.1-20080115. Ech, jakby nie chciano, abym skosztował tych wszystkich nowości, którymi szczyci się Spring-DM 1.1.0-m2.
Downloading: http://repo1.maven.org/eclipse//net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.pomW przykładowej aplikacji dostępnej w katalogu samples/simple-web-app znalazłem klasę testu jednostkowego - integration-test/src/test/java/org/springframework/osgi/samples/simplewebapp/OsgiHttpIntegrationTest.java, gdzie wymieniono wszystkie konieczne zależności do poprawnego jej uruchomienia. Kolejny raz pojawiła się wzmianka o spring-osgi-web-extender.
Downloading: http://springframework.svn.sourceforge.net/svnroot/springframework/repos/repo-ext//net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.pom
Downloading: http://maven.springframework.org/release/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.pom
Downloading: http://maven.springframework.org/external/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.pom
Downloading: http://maven.springframework.org/milestone/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.pom
Downloading: http://m2.safehaus.org/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.pom
Downloading: http://maven.springframework.org/osgi/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.pom
Downloading: http://jets3t.s3.amazonaws.com/maven2/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.pom
Downloading: http://repo1.maven.org/maven2/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.pom
Downloading: http://repo1.maven.org/eclipse//net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.jar
Downloading: http://springframework.svn.sourceforge.net/svnroot/springframework/repos/repo-ext//net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.jar
Downloading: http://maven.springframework.org/release/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.jar
Downloading: http://maven.springframework.org/external/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.jar
Downloading: http://maven.springframework.org/milestone/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.jar
Downloading: http://m2.safehaus.org/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.jar
Downloading: http://maven.springframework.org/osgi/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.jar
Downloading: http://jets3t.s3.amazonaws.com/maven2/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.jar
Downloading: http://repo1.maven.org/maven2/net/java/dev/jets3t/jets3t/0.5.1-20080115/jets3t-0.5.1-20080115.jar
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.
Missing:
----------
1) net.java.dev.jets3t:jets3t:jar:0.5.1-20080115
Try downloading the file manually from the project website.
Then, install it using the command:
mvn install:install-file -DgroupId=net.java.dev.jets3t -DartifactId=jets3t
-Dversion=0.5.1-20080115 -Dpackaging=jar -Dfile=/path/to/file
Alternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=net.java.dev.jets3t -DartifactId=jets3t -Dversion=0.5.1-20080115
-Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
Path to dependency:
1) org.springframework.osgi:spring-osgi:pom:1.1.0-rc1-SNAPSHOT
2) net.java.dev.jets3t:jets3t:jar:0.5.1-20080115
----------
1 required artifact is missing.
for artifact:
org.springframework.osgi:spring-osgi:pom:1.1.0-rc1-SNAPSHOT
from the specified remote repositories:
ibiblio.org (http://repo1.maven.org/maven2),
spring-release (http://maven.springframework.org/release),
spring-ext (http://springframework.svn.sourceforge.net/svnroot/springframework/repos/repo-ext/),
safehaus-repository (http://m2.safehaus.org),
spring-external (http://maven.springframework.org/external),
spring-milestone (http://maven.springframework.org/milestone),
springsource-s3-osgi-repo (http://maven.springframework.org/osgi),
jets3t (http://jets3t.s3.amazonaws.com/maven2),
eclipse-repository (http://repo1.maven.org/eclipse/)
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
col.add(SPRING_OSGI_GROUP + ", servlet-api.osgi, 2.5-SNAPSHOT");Pobieram brakujące pakunki z repozytorium http://jets3t.s3.amazonaws.com/maven2:
col.add(SPRING_OSGI_GROUP + ", jsp-api.osgi, 2.0-SNAPSHOT");
// JSP compiler
col.add(SPRING_OSGI_GROUP + ", jasper.osgi, 5.5.23-SNAPSHOT");
col.add(SPRING_OSGI_GROUP + ", commons-el.osgi, 1.0-SNAPSHOT");
// standard tag library
col.add("org.springframework.osgi, jstl.osgi, 1.1.2-SNAPSHOT");
// add MX4J for 1.4
// if < jdk 1.5, add an JMX implementation
if (!JdkVersion.isAtLeastJava15())
col.add(SPRING_OSGI_GROUP + ", mx4j.osgi, 3.0.2-SNAPSHOT");
col.add(SPRING_OSGI_GROUP + ", catalina.osgi, 5.5.23-SNAPSHOT");
col.add(SPRING_OSGI_GROUP + ", catalina.start.osgi, 1.0-SNAPSHOT");
// Spring DM web extender
col.add(SPRING_OSGI_GROUP + ", spring-osgi-web," + getSpringDMVersion());
col.add(SPRING_OSGI_GROUP + ", spring-osgi-web-extender," + getSpringDMVersion());
col.add(SPRING_OSGI_GROUP + ", cglib-nodep.osgi, 2.1.3-SNAPSHOT");
- jsp-api.osgi-2.0-20080103.183925-4.jar
- jasper.osgi-5.5.23-20080305.122359-4.jar
- commons-el.osgi-1.0-20080303.111409-4.jar
- jstl.osgi-1.1.2-20080103.183925-4.jar
- cglib-nodep.osgi-2.1.3-20080103.183925-4.jar
- catalina.start.osgi-1.0-20080425.161832-4.jar
- catalina.osgi-5.5.23-20080425.154256-4.jar
- install file:/C:/apps/spring-osgi/dist/spring-osgi-web-1.1.0-m2.jar
- install file:/C:/apps/spring-osgi/lib/servlet-api.osgi-2.5-SNAPSHOT.jar
- install file:/C:/apps/spring-osgi/lib/jcl104-over-slf4j-1.4.3.jar
- install file:/C:/apps/spring-osgi/lib/slf4j-api-1.4.3.jar
- install file:/C:/apps/spring-osgi/lib/slf4j-log4j12-1.4.3.jar
- install file:/C:/apps/spring-osgi/lib/log4j.osgi-1.2.15-SNAPSHOT.jar
- install file:/C:/apps/spring-osgi/dist/spring-osgi-extender-1.1.0-m2.jar
- install file:/C:/apps/spring-osgi/lib/spring-context-2.5.4.jar
- install file:/C:/apps/spring-osgi/lib/spring-beans-2.5.4.jar
- install file:/C:/apps/spring-osgi/lib/spring-core-2.5.4.jar
- install file:/C:/apps/spring-osgi/lib/aopalliance.osgi-1.0-SNAPSHOT.jar
- install file:/C:/apps/spring-osgi/dist/spring-osgi-io-1.1.0-m2.jar
- install file:/C:/apps/spring-osgi/lib/spring-aop-2.5.4.jar
- install file:/C:/spring-dm-libs/jsp-api.osgi-2.0-20080103.183925-4.jar
- install file:/C:/spring-dm-libs/jasper.osgi-5.5.23-20080305.122359-4.jar
- install file:/C:/spring-dm-libs/commons-el.osgi-1.0-20080303.111409-4.jar
- install file:/C:/spring-dm-libs/jstl.osgi-1.1.2-20080103.183925-4.jar
- install file:/C:/spring-dm-libs/catalina.osgi-5.5.23-20080425.154256-4.jar
- install file:/C:/spring-dm-libs/catalina.start.osgi-1.0-20080425.161832-4.jar
- install file:/C:/spring-dm-libs/cglib-nodep.osgi-2.1.3-20080103.183925-4.jar
- install file:/C:/spring-dm-libs/spring-osgi-web-extender-1.1.0-m2-SNAPSHOT.jar
Dodałem do pom.xml następujący wpis:
<Bundle-Name>${artifactId}</Bundle-Name>ponownie zbudowałem aplikację - mvn clean package - i zaktualizowałem pakunek.-> uninstall 26W końcu upragnione uruchomienie aplikacji webowej spring-osgi-webapp jako pakunku OSGi, jednakże adres http://localhost:8080/spring-osgi-webapp/ kończył się pustą stroną lub wyjątkiem o niedostępności klas (niestety komunikat nie wskazywał jakiej). Coś zaczęło działać, ale niepoprawnie. Wykluczam mój błąd ;-) Po zmianie strony JSP na statyczną stronę HTML pojawia się wreszcie strona aplikacji!
-> install file:/C:/projs/osgi/spring-osgi-webapp/target/spring-osgi-webapp.war
Bundle ID: 27
-> start 27
DEBUG: WIRE: 27.0 -> javax.servlet.http -> 5.0
DEBUG: WIRE: 27.0 -> javax.servlet -> 5.0
DEBUG: WIRE: 27.0 -> org.xml.sax -> 0
DEBUG: WIRE: 27.0 -> org.springframework.beans.factory.xml -> 14.0
DEBUG: WIRE: 27.0 -> javax.servlet.resources -> 5.0
DEBUG: WIRE: 27.0 -> org.springframework.aop.framework -> 19.0
DEBUG: WIRE: 27.0 -> org.aopalliance.aop -> 17.0
DEBUG: WIRE: 27.0 -> org.springframework.aop -> 19.0
-> headers 27
spring-osgi-webapp (27)
-----------------------
Built-By = jlaskowski
Created-By = Apache Maven
Build-Jdk = 1.5.0_14
Manifest-Version = 1.0
Bundle-ManifestVersion = 2
Spring-Context = *;publish-context:=true
Archiver-Version = Plexus Archiver
Import-Package = javax.servlet,javax.servlet.http,javax.servlet.resources,
org.springframework.beans.factory.xml,org.springframework.aop,org.springframework.aop.framework,
org.aopalliance.aop,org.xml.sax
Bundle-Name = spring-osgi-webapp
Bundle-Classpath = .,WEB-INF/classes
Bundle-SymbolicName = pl.jaceklaskowski.osgi.spring-osgi-webapp

Wciąż jednak strony JSP nie są poprawnie kompilowane. Stan platformy OSGi (Felix 1.0.4) prezentuje się następująco:
-> psZauważyłem jednak, że wiele (wszystkie?) z dyskusji na forum Spring-DM dotyczyły uruchomienia aplikacji webowej na Equinox. Equinox jest projektem platformy OSGi rozwijanym w organizacji Eclipse, która jest podstawą technologiczną dla Eclipse IDE i mechanizmu wtyczek, które de facto są pakunkami OSGi. Zniechęcony wynikami moich doświadczeń z Apache Felix, postanowiłem na koniec sprawdzić uruchomienie aplikacji z Spring-DM na Equinoksie.
START LEVEL 1
ID State Level Name
[ 0] [Active ] [ 0] System Bundle (1.0.4)
[ 1] [Active ] [ 1] Apache Felix Shell Service (1.0.1)
[ 2] [Active ] [ 1] Apache Felix Shell TUI (1.0.1)
[ 3] [Active ] [ 1] Apache Felix Bundle Repository (1.0.3)
[ 5] [Active ] [ 1] servlet-api.osgi (2.5.0.SNAPSHOT)
[ 6] [Active ] [ 1] slf4j-log4j12 (1.4.3)
[ 7] [Active ] [ 1] jcl104-over-slf4j (1.4.3)
[ 8] [Active ] [ 1] slf4j-api (1.4.3)
[ 9] [Active ] [ 1] log4j.osgi (1.2.15.SNAPSHOT)
[ 13] [Active ] [ 1] spring-context (2.5.4)
[ 14] [Active ] [ 1] spring-beans (2.5.4)
[ 15] [Active ] [ 1] spring-osgi-core (1.1.0.m2)
[ 16] [Active ] [ 1] spring-core (2.5.4)
[ 17] [Active ] [ 1] aopalliance.osgi (1.0.0.SNAPSHOT)
[ 18] [Active ] [ 1] spring-osgi-io (1.1.0.m2)
[ 19] [Active ] [ 1] spring-aop (2.5.4)
[ 32] [Active ] [ 1] spring-webmvc (2.5.4)
[ 33] [Active ] [ 1] spring-web (2.5.4)
[ 37] [Active ] [ 1] spring-osgi-web (1.1.0.m2)
[ 38] [Active ] [ 1] spring-osgi-extender (1.1.0.m2)
[ 50] [Active ] [ 1] jsp-api.osgi (2.0.0.SNAPSHOT)
[ 51] [Active ] [ 1] jasper.osgi (5.5.23.SNAPSHOT)
[ 52] [Active ] [ 1] commons-el.osgi (1.0.0.SNAPSHOT)
[ 56] [Active ] [ 1] cglib-nodep.osgi (2.1.3.SNAPSHOT)
[ 61] [Active ] [ 1] spring-osgi-web-extender (1.1.0.m2-SNAPSHOT)
[ 64] [Active ] [ 1] catalina.start.osgi (1.0.0.SNAPSHOT)
[ 65] [Active ] [ 1] catalina.osgi (5.5.23.SNAPSHOT)
[ 68] [Active ] [ 1] spring-osgi-webapp Maven Webapp (1.0)
[ 69] [Installed ] [ 1] jstl.osgi (1.1.2.SNAPSHOT)
jlaskowski@work ~Instaluje wszystkie pakunki Spring-DM konieczne do uruchomienia mojej aplikacji webowej, jak to miało miejsce wcześniej z Apache Felix.
$ java -jar c:/apps/eclipse/plugins/org.eclipse.osgi_3.4.0.v20080326.jar -console
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.0.v20080326
osgi> ssa następnie próbuję je wszystkie uruchomić poleceniem start 1 2 ... 25 (zamień ... na odpowiednie liczby - identyfikatory pakunków). Niestety pakunek o identyfikatorze 17 odmawia współpracy wyjątkiem:
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.0.v20080326
1 ACTIVE org.springframework.bundle.osgi.web_1.1.0.m2
2 ACTIVE org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
3 ACTIVE jcl104.over.slf4j_1.4.3
4 ACTIVE slf4j.api_1.4.3
5 ACTIVE slf4j.log4j12_1.4.3
6 ACTIVE org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT
7 ACTIVE org.springframework.bundle.osgi.extender_1.1.0.m2
8 ACTIVE org.springframework.bundle.spring.context_2.5.4
9 ACTIVE org.springframework.bundle.spring.beans_2.5.4
10 ACTIVE org.springframework.bundle.spring.core_2.5.4
11 ACTIVE org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT
12 ACTIVE org.springframework.bundle.osgi.io_1.1.0.m2
13 ACTIVE org.springframework.bundle.spring.aop_2.5.4
14 ACTIVE org.springframework.osgi.jsp-api.osgi_2.0.0.SNAPSHOT
15 ACTIVE org.springframework.osgi.jasper.osgi_5.5.23.SNAPSHOT
16 ACTIVE org.springframework.osgi.commons-el.osgi_1.0.0.SNAPSHOT
17 INSTALLED org.springframework.osgi.jstl.osgi_1.1.2.SNAPSHOT
18 RESOLVED org.springframework.osgi.catalina.osgi_6.0.16.SNAPSHOT
19 RESOLVED org.springframework.osgi.catalina.start.osgi_6.0.16.SNAPSHOT
20 RESOLVED org.springframework.osgi.cglib-nodep.osgi_2.1.3.SNAPSHOT
21 RESOLVED org.springframework.bundle.osgi.web.extender_1.1.0.m2-SNAPSHOT
22 RESOLVED org.springframework.osgi.catalina.start.osgi_1.0.0.SNAPSHOT
23 RESOLVED org.springframework.osgi.catalina.osgi_5.5.23.SNAPSHOT
24 ACTIVE pl.jaceklaskowski.osgi.spring-osgi-webapp_1.0.0
25 ACTIVE org.springframework.bundle.osgi.core_1.1.0.m2
org.osgi.framework.BundleException: The bundle could not be resolved. Reason: Missing Constraint:Nie wygląda to dobrze. Spróbowałem odszukać biblioteki znaczników standard JSTL jako pakunek OSGi, ale niestety nic nie znalazłem w repozytorium Spring-DM na S3. Skoro nie było, to znaczy, że najprawdopodobniej nie jest potrzebne. Podchodzę jeszcze raz do tematu, tyle że postanawiam uruchomić jedynie moją aplikację webową bez uruchamiania pozostałych pakunków (platforma OSGi zmieni ich stan na RESOLVED, ale nie na ACTIVE, w którym otrzymywałem wyjątek brakującego pakietu. Zawiłości platformy OSGi, w które nie ma co na razie wchodzić). Zmieniam również wersję Equinoksa na starszą - 3.3.2.R33x_v20080105.
Import-Package: org.apache.taglibs.standard.tag.common.fmt; version="0.0.0"
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:305)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:265)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:257)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:257)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:150)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:303)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.console(FrameworkConsole.java:288)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:224)
at java.lang.Thread.run(Thread.java:595)
jlaskowski@work ~Skąd ja wziąłem akurat tą wersję Equinoksa jest poza moją wiedzą - jakoś się kiedyś przy czymś ściągnęło. Najlepiej pobrać aktualną produkcyjną wersję ze strony domowej projektu Equinox. Wersja 3.3.2 powinna spełniać nasze wymagania.
$ java -jar c:/.m2/eclipse/eclipse/plugins/org.eclipse.osgi_3.3.2.R33x_v20080105.jar -console
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
jlaskowski@work ~Na razie czysto, a aplikacja jako pakunek 26 wydaje się być uruchomiona (stan ACTIVE) wraz z pakunkami Tomcata (pakunki 22, 23 i 24). Uruchomienie przeglądarki i skierowanie na adres http://localhost:8080/spring-osgi-webapp/index.jsp kończy się....
$ java -jar c:/.m2/eclipse/eclipse/plugins/org.eclipse.osgi_3.3.2.R33x_v20080105.jar -console
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
osgi> install file:/C:/apps/spring-osgi/dist/spring-osgi-core-1.1.0-m2.jar
Bundle id is 1
osgi> install file:/C:/apps/spring-osgi/dist/spring-osgi-web-1.1.0-m2.jar
Bundle id is 2
osgi> install file:/C:/apps/spring-osgi/dist/spring-osgi-io-1.1.0-m2.jar
Bundle id is 3
osgi> install file:/C:/apps/spring-osgi/lib/servlet-api.osgi-2.5-SNAPSHOT.jar
Bundle id is 4
osgi> install file:/C:/apps/spring-osgi/lib/jcl104-over-slf4j-1.4.3.jar
Bundle id is 5
osgi> install file:/C:/apps/spring-osgi/lib/slf4j-api-1.4.3.jar
Bundle id is 6
osgi> install file:/C:/apps/spring-osgi/lib/slf4j-log4j12-1.4.3.jar
Bundle id is 7
osgi> install file:/C:/apps/spring-osgi/lib/log4j.osgi-1.2.15-SNAPSHOT.jar
Bundle id is 8
osgi> install file:/C:/apps/spring-osgi/dist/spring-osgi-extender-1.1.0-m2.jar
Bundle id is 9
osgi> install file:/C:/apps/spring-osgi/lib/spring-context-2.5.4.jar
Bundle id is 10
osgi> install file:/C:/apps/spring-osgi/lib/spring-beans-2.5.4.jar
Bundle id is 11
osgi> install file:/C:/apps/spring-osgi/lib/spring-core-2.5.4.jar
Bundle id is 12
osgi> install file:/C:/apps/spring-osgi/lib/aopalliance.osgi-1.0-SNAPSHOT.jar
Bundle id is 13
osgi> install file:/C:/apps/spring-osgi/lib/spring-aop-2.5.4.jar
Bundle id is 14
osgi> install file:/C:/spring-dm-libs/jsp-api.osgi-2.0-SNAPSHOT.jar
Bundle id is 15
osgi> install file:/C:/spring-dm-libs/jasper.osgi-5.5.23-SNAPSHOT.jar
Bundle id is 16
osgi> install file:/C:/spring-dm-libs/commons-el.osgi-1.0-SNAPSHOT.jar
Bundle id is 17
osgi> install file:/C:/spring-dm-libs/jstl.osgi-1.1.2-SNAPSHOT.jar
Bundle id is 18
osgi> install file:/C:/spring-dm-libs/catalina.osgi-6.0.16-SNAPSHOT.jar
Bundle id is 19
osgi> install file:/C:/spring-dm-libs/catalina.start.osgi-6.0.16-SNAPSHOT.jar
Bundle id is 20
osgi> install file:/C:/spring-dm-libs/cglib-nodep.osgi-2.1.3-SNAPSHOT.jar
Bundle id is 21
osgi> install file:/C:/spring-dm-libs/spring-osgi-web-extender-1.1.0-m2-SNAPSHOT.jar
Bundle id is 22
osgi> install file:/C:/spring-dm-libs/catalina.start.osgi-1.0-20080425.161832-4.jar
Bundle id is 23
osgi> install file:/C:/spring-dm-libs/catalina.osgi-5.5.23-20080425.154256-4.jar
Bundle id is 24
osgi> install file:/C:/projs/osgi/spring-osgi-webapp/target/spring-osgi-webapp.war
Bundle id is 25
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
1 INSTALLED org.springframework.bundle.osgi.core_1.1.0.m2
2 INSTALLED org.springframework.bundle.osgi.web_1.1.0.m2
3 INSTALLED org.springframework.bundle.osgi.io_1.1.0.m2
4 INSTALLED org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
5 INSTALLED jcl104.over.slf4j_1.4.3
6 INSTALLED slf4j.api_1.4.3
7 INSTALLED slf4j.log4j12_1.4.3
8 INSTALLED org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT
9 INSTALLED org.springframework.bundle.osgi.extender_1.1.0.m2
10 INSTALLED org.springframework.bundle.spring.context_2.5.4
11 INSTALLED org.springframework.bundle.spring.beans_2.5.4
12 INSTALLED org.springframework.bundle.spring.core_2.5.4
13 INSTALLED org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT
14 INSTALLED org.springframework.bundle.spring.aop_2.5.4
15 INSTALLED org.springframework.osgi.jsp-api.osgi_2.0.0.SNAPSHOT
16 INSTALLED org.springframework.osgi.jasper.osgi_5.5.23.SNAPSHOT
17 INSTALLED org.springframework.osgi.commons-el.osgi_1.0.0.SNAPSHOT
18 INSTALLED org.springframework.osgi.jstl.osgi_1.1.2.SNAPSHOT
19 INSTALLED org.springframework.osgi.catalina.osgi_6.0.16.SNAPSHOT
20 INSTALLED org.springframework.osgi.catalina.start.osgi_6.0.16.SNAPSHOT
21 INSTALLED org.springframework.osgi.cglib-nodep.osgi_2.1.3.SNAPSHOT
22 INSTALLED org.springframework.bundle.osgi.web.extender_1.1.0.m2-SNAPSHOT
23 INSTALLED org.springframework.osgi.catalina.start.osgi_1.0.0.SNAPSHOT
24 INSTALLED org.springframework.osgi.catalina.osgi_5.5.23.SNAPSHOT
25 INSTALLED pl.jaceklaskowski.osgi.spring-osgi-webapp_1.0.0
osgi> start 24
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
1 RESOLVED org.springframework.bundle.osgi.core_1.1.0.m2
2 RESOLVED org.springframework.bundle.osgi.web_1.1.0.m2
3 RESOLVED org.springframework.bundle.osgi.io_1.1.0.m2
4 RESOLVED org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
5 RESOLVED jcl104.over.slf4j_1.4.3
6 RESOLVED slf4j.api_1.4.3
7 RESOLVED slf4j.log4j12_1.4.3
8 RESOLVED org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT
9 RESOLVED org.springframework.bundle.osgi.extender_1.1.0.m2
10 RESOLVED org.springframework.bundle.spring.context_2.5.4
11 RESOLVED org.springframework.bundle.spring.beans_2.5.4
12 RESOLVED org.springframework.bundle.spring.core_2.5.4
13 RESOLVED org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT
14 RESOLVED org.springframework.bundle.spring.aop_2.5.4
15 RESOLVED org.springframework.osgi.jsp-api.osgi_2.0.0.SNAPSHOT
16 RESOLVED org.springframework.osgi.jasper.osgi_5.5.23.SNAPSHOT
17 RESOLVED org.springframework.osgi.commons-el.osgi_1.0.0.SNAPSHOT
18 INSTALLED org.springframework.osgi.jstl.osgi_1.1.2.SNAPSHOT
19 RESOLVED org.springframework.osgi.catalina.osgi_6.0.16.SNAPSHOT
20 RESOLVED org.springframework.osgi.catalina.start.osgi_6.0.16.SNAPSHOT
21 RESOLVED org.springframework.osgi.cglib-nodep.osgi_2.1.3.SNAPSHOT
22 RESOLVED org.springframework.bundle.osgi.web.extender_1.1.0.m2-SNAPSHOT
23 RESOLVED org.springframework.osgi.catalina.start.osgi_1.0.0.SNAPSHOT
24 ACTIVE org.springframework.osgi.catalina.osgi_5.5.23.SNAPSHOT
25 RESOLVED pl.jaceklaskowski.osgi.spring-osgi-webapp_1.0.0
osgi> start 1
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
1 ACTIVE org.springframework.bundle.osgi.core_1.1.0.m2
2 RESOLVED org.springframework.bundle.osgi.web_1.1.0.m2
3 RESOLVED org.springframework.bundle.osgi.io_1.1.0.m2
4 RESOLVED org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
5 RESOLVED jcl104.over.slf4j_1.4.3
6 RESOLVED slf4j.api_1.4.3
7 RESOLVED slf4j.log4j12_1.4.3
8 RESOLVED org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT
9 RESOLVED org.springframework.bundle.osgi.extender_1.1.0.m2
10 RESOLVED org.springframework.bundle.spring.context_2.5.4
11 RESOLVED org.springframework.bundle.spring.beans_2.5.4
12 RESOLVED org.springframework.bundle.spring.core_2.5.4
13 RESOLVED org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT
14 RESOLVED org.springframework.bundle.spring.aop_2.5.4
15 RESOLVED org.springframework.osgi.jsp-api.osgi_2.0.0.SNAPSHOT
16 RESOLVED org.springframework.osgi.jasper.osgi_5.5.23.SNAPSHOT
17 RESOLVED org.springframework.osgi.commons-el.osgi_1.0.0.SNAPSHOT
18 INSTALLED org.springframework.osgi.jstl.osgi_1.1.2.SNAPSHOT
19 RESOLVED org.springframework.osgi.catalina.osgi_6.0.16.SNAPSHOT
20 RESOLVED org.springframework.osgi.catalina.start.osgi_6.0.16.SNAPSHOT
21 RESOLVED org.springframework.osgi.cglib-nodep.osgi_2.1.3.SNAPSHOT
22 RESOLVED org.springframework.bundle.osgi.web.extender_1.1.0.m2-SNAPSHOT
23 RESOLVED org.springframework.osgi.catalina.start.osgi_1.0.0.SNAPSHOT
24 ACTIVE org.springframework.osgi.catalina.osgi_5.5.23.SNAPSHOT
25 RESOLVED pl.jaceklaskowski.osgi.spring-osgi-webapp_1.0.0
osgi> start 22
log4j:WARN No appenders could be found for logger (org.springframework.util.ClassUtils).
log4j:WARN Please initialize the log4j system properly.
org.osgi.framework.BundleException: Exception in org.springframework.osgi.web.extender.internal.activator.WarLoaderListener.start()
of bundle org.springframe...
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:1018)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:974)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:346)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:260)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:252)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:260)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:150)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:300)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.console(FrameworkConsole.java:285)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:221)
at java.lang.Thread.run(Thread.java:595)
Caused by: org.springframework.osgi.OsgiException: Cannot create Tomcat deployer
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.createDefaultWarDeployer(WarListenerConfiguration.java:156)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.<init>(WarListenerConfiguration.java:84)
at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener.start(WarLoaderListener.java:243)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
... 14 more
Caused by: org.springframework.osgi.service.ServiceUnavailableException: service matching filter=[(objectClass=org.apache.catalina.Service)] unavailable
at org.springframework.osgi.service.importer.internal.aop.ServiceDynamicInterceptor.getTarget(ServiceDynamicInterceptor.java:330)
at org.springframework.osgi.service.importer.internal.aop.ServiceDynamicInterceptor.afterPropertiesSet(ServiceDynamicInterceptor.java:366)
at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.createProxy(OsgiServiceProxyFactoryBean.java:118)
at org.springframework.osgi.service.importer.support.AbstractOsgiServiceImportFactoryBean.getObject(AbstractOsgiServiceImportFactoryBean.java:94)
at org.springframework.osgi.web.deployer.internal.util.Utils.createServerServiceProxy(Utils.java:117)
at org.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer.afterPropertiesSet(TomcatWarDeployer.java:90)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.createDefaultWarDeployer(WarListenerConfiguration.java:152)
... 19 more
Nested Exception:
org.springframework.osgi.OsgiException: Cannot create Tomcat deployer
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.createDefaultWarDeployer(WarListenerConfiguration.java:156)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.<init>(WarListenerConfiguration.java:84)
at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener.start(WarLoaderListener.java:243)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:974)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:346)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:260)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:252)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:260)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:150)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:300)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.console(FrameworkConsole.java:285)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:221)
at java.lang.Thread.run(Thread.java:595)
Caused by: org.springframework.osgi.service.ServiceUnavailableException: service matching filter=[(objectClass=org.apache.catalina.Service)] unavailable
at org.springframework.osgi.service.importer.internal.aop.ServiceDynamicInterceptor.getTarget(ServiceDynamicInterceptor.java:330)
at org.springframework.osgi.service.importer.internal.aop.ServiceDynamicInterceptor.afterPropertiesSet(ServiceDynamicInterceptor.java:366)
at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.createProxy(OsgiServiceProxyFactoryBean.java:118)
at org.springframework.osgi.service.importer.support.AbstractOsgiServiceImportFactoryBean.getObject(AbstractOsgiServiceImportFactoryBean.java:94)
at org.springframework.osgi.web.deployer.internal.util.Utils.createServerServiceProxy(Utils.java:117)
at org.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer.afterPropertiesSet(TomcatWarDeployer.java:90)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.createDefaultWarDeployer(WarListenerConfiguration.java:152)
... 19 more
Nested Exception:
org.springframework.osgi.service.ServiceUnavailableException: service matching filter=[(objectClass=org.apache.catalina.Service)] unavailable
at org.springframework.osgi.service.importer.internal.aop.ServiceDynamicInterceptor.getTarget(ServiceDynamicInterceptor.java:330)
at org.springframework.osgi.service.importer.internal.aop.ServiceDynamicInterceptor.afterPropertiesSet(ServiceDynamicInterceptor.java:366)
at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.createProxy(OsgiServiceProxyFactoryBean.java:118)
at org.springframework.osgi.service.importer.support.AbstractOsgiServiceImportFactoryBean.getObject(AbstractOsgiServiceImportFactoryBean.java:94)
at org.springframework.osgi.web.deployer.internal.util.Utils.createServerServiceProxy(Utils.java:117)
at org.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer.afterPropertiesSet(TomcatWarDeployer.java:90)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.createDefaultWarDeployer(WarListenerConfiguration.java:152)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.<init>(WarListenerConfiguration.java:84)
at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener.start(WarLoaderListener.java:243)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:974)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:346)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:260)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:252)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:260)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:150)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:300)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.console(FrameworkConsole.java:285)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:221)
at java.lang.Thread.run(Thread.java:595)
Nested Exception:
org.springframework.osgi.OsgiException: Cannot create Tomcat deployer
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.createDefaultWarDeployer(WarListenerConfiguration.java:156)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.<init>(WarListenerConfiguration.java:84)
at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener.start(WarLoaderListener.java:243)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:974)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:346)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:260)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:252)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:260)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:150)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:300)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.console(FrameworkConsole.java:285)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:221)
at java.lang.Thread.run(Thread.java:595)
Caused by: org.springframework.osgi.service.ServiceUnavailableException: service matching filter=[(objectClass=org.apache.catalina.Service)] unavailable
at org.springframework.osgi.service.importer.internal.aop.ServiceDynamicInterceptor.getTarget(ServiceDynamicInterceptor.java:330)
at org.springframework.osgi.service.importer.internal.aop.ServiceDynamicInterceptor.afterPropertiesSet(ServiceDynamicInterceptor.java:366)
at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.createProxy(OsgiServiceProxyFactoryBean.java:118)
at org.springframework.osgi.service.importer.support.AbstractOsgiServiceImportFactoryBean.getObject(AbstractOsgiServiceImportFactoryBean.java:94)
at org.springframework.osgi.web.deployer.internal.util.Utils.createServerServiceProxy(Utils.java:117)
at org.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer.afterPropertiesSet(TomcatWarDeployer.java:90)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.createDefaultWarDeployer(WarListenerConfiguration.java:152)
... 19 more
Nested Exception:
org.springframework.osgi.service.ServiceUnavailableException: service matching filter=[(objectClass=org.apache.catalina.Service)] unavailable
at org.springframework.osgi.service.importer.internal.aop.ServiceDynamicInterceptor.getTarget(ServiceDynamicInterceptor.java:330)
at org.springframework.osgi.service.importer.internal.aop.ServiceDynamicInterceptor.afterPropertiesSet(ServiceDynamicInterceptor.java:366)
at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.createProxy(OsgiServiceProxyFactoryBean.java:118)
at org.springframework.osgi.service.importer.support.AbstractOsgiServiceImportFactoryBean.getObject(AbstractOsgiServiceImportFactoryBean.java:94)
at org.springframework.osgi.web.deployer.internal.util.Utils.createServerServiceProxy(Utils.java:117)
at org.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer.afterPropertiesSet(TomcatWarDeployer.java:90)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.createDefaultWarDeployer(WarListenerConfiguration.java:152)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.<init>(WarListenerConfiguration.java:84)
at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener.start(WarLoaderListener.java:243)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:974)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:346)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:260)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:252)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:260)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:150)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:300)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.console(FrameworkConsole.java:285)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:221)
at java.lang.Thread.run(Thread.java:595)
osgi>
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
1 ACTIVE org.springframework.bundle.osgi.core_1.1.0.m2
2 RESOLVED org.springframework.bundle.osgi.web_1.1.0.m2
3 RESOLVED org.springframework.bundle.osgi.io_1.1.0.m2
4 RESOLVED org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
5 RESOLVED jcl104.over.slf4j_1.4.3
6 RESOLVED slf4j.api_1.4.3
7 RESOLVED slf4j.log4j12_1.4.3
8 RESOLVED org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT
9 RESOLVED org.springframework.bundle.osgi.extender_1.1.0.m2
10 RESOLVED org.springframework.bundle.spring.context_2.5.4
11 RESOLVED org.springframework.bundle.spring.beans_2.5.4
12 RESOLVED org.springframework.bundle.spring.core_2.5.4
13 RESOLVED org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT
14 RESOLVED org.springframework.bundle.spring.aop_2.5.4
15 RESOLVED org.springframework.osgi.jsp-api.osgi_2.0.0.SNAPSHOT
16 RESOLVED org.springframework.osgi.jasper.osgi_5.5.23.SNAPSHOT
17 RESOLVED org.springframework.osgi.commons-el.osgi_1.0.0.SNAPSHOT
18 INSTALLED org.springframework.osgi.jstl.osgi_1.1.2.SNAPSHOT
19 RESOLVED org.springframework.osgi.catalina.osgi_6.0.16.SNAPSHOT
20 RESOLVED org.springframework.osgi.catalina.start.osgi_6.0.16.SNAPSHOT
21 RESOLVED org.springframework.osgi.cglib-nodep.osgi_2.1.3.SNAPSHOT
22 RESOLVED org.springframework.bundle.osgi.web.extender_1.1.0.m2-SNAPSHOT
23 RESOLVED org.springframework.osgi.catalina.start.osgi_1.0.0.SNAPSHOT
24 ACTIVE org.springframework.osgi.catalina.osgi_5.5.23.SNAPSHOT
25 RESOLVED pl.jaceklaskowski.osgi.spring-osgi-webapp_1.0.0
osgi> start 23
osgi> 2008-04-30 23:43:48 org.apache.catalina.startup.ClusterRuleSetFactory getClusterRuleSet
INFO: Unable to find a cluster rule set in the classpath. Will load the default rule set.
2008-04-30 23:43:48 org.apache.catalina.startup.ClusterRuleSetFactory getClusterRuleSet
INFO: Unable to find a cluster rule set in the classpath. Will load the default rule set.
2008-04-30 23:43:48 org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
2008-04-30 23:43:48 org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 262 ms
2008-04-30 23:43:48 org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
2008-04-30 23:43:48 org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.16
2008-04-30 23:43:48 org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
1 ACTIVE org.springframework.bundle.osgi.core_1.1.0.m2
2 RESOLVED org.springframework.bundle.osgi.web_1.1.0.m2
3 RESOLVED org.springframework.bundle.osgi.io_1.1.0.m2
4 RESOLVED org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
5 RESOLVED jcl104.over.slf4j_1.4.3
6 RESOLVED slf4j.api_1.4.3
7 RESOLVED slf4j.log4j12_1.4.3
8 RESOLVED org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT
9 RESOLVED org.springframework.bundle.osgi.extender_1.1.0.m2
10 RESOLVED org.springframework.bundle.spring.context_2.5.4
11 RESOLVED org.springframework.bundle.spring.beans_2.5.4
12 RESOLVED org.springframework.bundle.spring.core_2.5.4
13 RESOLVED org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT
14 RESOLVED org.springframework.bundle.spring.aop_2.5.4
15 RESOLVED org.springframework.osgi.jsp-api.osgi_2.0.0.SNAPSHOT
16 RESOLVED org.springframework.osgi.jasper.osgi_5.5.23.SNAPSHOT
17 RESOLVED org.springframework.osgi.commons-el.osgi_1.0.0.SNAPSHOT
18 INSTALLED org.springframework.osgi.jstl.osgi_1.1.2.SNAPSHOT
19 RESOLVED org.springframework.osgi.catalina.osgi_6.0.16.SNAPSHOT
20 RESOLVED org.springframework.osgi.catalina.start.osgi_6.0.16.SNAPSHOT
21 RESOLVED org.springframework.osgi.cglib-nodep.osgi_2.1.3.SNAPSHOT
22 RESOLVED org.springframework.bundle.osgi.web.extender_1.1.0.m2-SNAPSHOT
23 ACTIVE org.springframework.osgi.catalina.start.osgi_1.0.0.SNAPSHOT
24 ACTIVE org.springframework.osgi.catalina.osgi_5.5.23.SNAPSHOT
25 RESOLVED pl.jaceklaskowski.osgi.spring-osgi-webapp_1.0.0
osgi> start 22
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
1 ACTIVE org.springframework.bundle.osgi.core_1.1.0.m2
2 RESOLVED org.springframework.bundle.osgi.web_1.1.0.m2
3 RESOLVED org.springframework.bundle.osgi.io_1.1.0.m2
4 RESOLVED org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
5 RESOLVED jcl104.over.slf4j_1.4.3
6 RESOLVED slf4j.api_1.4.3
7 RESOLVED slf4j.log4j12_1.4.3
8 RESOLVED org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT
9 RESOLVED org.springframework.bundle.osgi.extender_1.1.0.m2
10 RESOLVED org.springframework.bundle.spring.context_2.5.4
11 RESOLVED org.springframework.bundle.spring.beans_2.5.4
12 RESOLVED org.springframework.bundle.spring.core_2.5.4
13 RESOLVED org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT
14 RESOLVED org.springframework.bundle.spring.aop_2.5.4
15 RESOLVED org.springframework.osgi.jsp-api.osgi_2.0.0.SNAPSHOT
16 RESOLVED org.springframework.osgi.jasper.osgi_5.5.23.SNAPSHOT
17 RESOLVED org.springframework.osgi.commons-el.osgi_1.0.0.SNAPSHOT
18 INSTALLED org.springframework.osgi.jstl.osgi_1.1.2.SNAPSHOT
19 RESOLVED org.springframework.osgi.catalina.osgi_6.0.16.SNAPSHOT
20 RESOLVED org.springframework.osgi.catalina.start.osgi_6.0.16.SNAPSHOT
21 RESOLVED org.springframework.osgi.cglib-nodep.osgi_2.1.3.SNAPSHOT
22 ACTIVE org.springframework.bundle.osgi.web.extender_1.1.0.m2-SNAPSHOT
23 ACTIVE org.springframework.osgi.catalina.start.osgi_1.0.0.SNAPSHOT
24 ACTIVE org.springframework.osgi.catalina.osgi_5.5.23.SNAPSHOT
25 RESOLVED pl.jaceklaskowski.osgi.spring-osgi-webapp_1.0.0
osgi> start 25
osgi> 2008-04-30 23:44:21 org.apache.catalina.startup.DigesterFactory register
WARNING: Could not get url for /javax/servlet/jsp/resources/jsp_2_1.xsd
2008-04-30 23:44:21 org.apache.catalina.startup.DigesterFactory register
WARNING: Could not get url for /javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd
2008-04-30 23:44:21 org.apache.catalina.startup.DigesterFactory register
WARNING: Could not get url for /javax/servlet/resources/j2ee_web_services_1_1.xsd
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
1 ACTIVE org.springframework.bundle.osgi.core_1.1.0.m2
2 RESOLVED org.springframework.bundle.osgi.web_1.1.0.m2
3 RESOLVED org.springframework.bundle.osgi.io_1.1.0.m2
4 RESOLVED org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
5 RESOLVED jcl104.over.slf4j_1.4.3
6 RESOLVED slf4j.api_1.4.3
7 RESOLVED slf4j.log4j12_1.4.3
8 RESOLVED org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT
9 RESOLVED org.springframework.bundle.osgi.extender_1.1.0.m2
10 RESOLVED org.springframework.bundle.spring.context_2.5.4
11 RESOLVED org.springframework.bundle.spring.beans_2.5.4
12 RESOLVED org.springframework.bundle.spring.core_2.5.4
13 RESOLVED org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT
14 RESOLVED org.springframework.bundle.spring.aop_2.5.4
15 RESOLVED org.springframework.osgi.jsp-api.osgi_2.0.0.SNAPSHOT
16 RESOLVED org.springframework.osgi.jasper.osgi_5.5.23.SNAPSHOT
17 RESOLVED org.springframework.osgi.commons-el.osgi_1.0.0.SNAPSHOT
18 INSTALLED org.springframework.osgi.jstl.osgi_1.1.2.SNAPSHOT
19 RESOLVED org.springframework.osgi.catalina.osgi_6.0.16.SNAPSHOT
20 RESOLVED org.springframework.osgi.catalina.start.osgi_6.0.16.SNAPSHOT
21 RESOLVED org.springframework.osgi.cglib-nodep.osgi_2.1.3.SNAPSHOT
22 ACTIVE org.springframework.bundle.osgi.web.extender_1.1.0.m2-SNAPSHOT
23 ACTIVE org.springframework.osgi.catalina.start.osgi_1.0.0.SNAPSHOT
24 ACTIVE org.springframework.osgi.catalina.osgi_5.5.23.SNAPSHOT
25 ACTIVE pl.jaceklaskowski.osgi.spring-osgi-webapp_1.0.0
osgi> uninstall 25
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
1 ACTIVE org.springframework.bundle.osgi.core_1.1.0.m2
2 RESOLVED org.springframework.bundle.osgi.web_1.1.0.m2
3 RESOLVED org.springframework.bundle.osgi.io_1.1.0.m2
4 RESOLVED org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
5 RESOLVED jcl104.over.slf4j_1.4.3
6 RESOLVED slf4j.api_1.4.3
7 RESOLVED slf4j.log4j12_1.4.3
8 RESOLVED org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT
9 RESOLVED org.springframework.bundle.osgi.extender_1.1.0.m2
10 RESOLVED org.springframework.bundle.spring.context_2.5.4
11 RESOLVED org.springframework.bundle.spring.beans_2.5.4
12 RESOLVED org.springframework.bundle.spring.core_2.5.4
13 RESOLVED org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT
14 RESOLVED org.springframework.bundle.spring.aop_2.5.4
15 RESOLVED org.springframework.osgi.jsp-api.osgi_2.0.0.SNAPSHOT
16 RESOLVED org.springframework.osgi.jasper.osgi_5.5.23.SNAPSHOT
17 RESOLVED org.springframework.osgi.commons-el.osgi_1.0.0.SNAPSHOT
18 INSTALLED org.springframework.osgi.jstl.osgi_1.1.2.SNAPSHOT
19 RESOLVED org.springframework.osgi.catalina.osgi_6.0.16.SNAPSHOT
20 RESOLVED org.springframework.osgi.catalina.start.osgi_6.0.16.SNAPSHOT
21 RESOLVED org.springframework.osgi.cglib-nodep.osgi_2.1.3.SNAPSHOT
22 ACTIVE org.springframework.bundle.osgi.web.extender_1.1.0.m2-SNAPSHOT
23 ACTIVE org.springframework.osgi.catalina.start.osgi_1.0.0.SNAPSHOT
24 ACTIVE org.springframework.osgi.catalina.osgi_5.5.23.SNAPSHOT
osgi> install file:/C:/projs/osgi/spring-osgi-webapp/target/spring-osgi-webapp.war
Bundle id is 26
osgi> start 26
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
1 ACTIVE org.springframework.bundle.osgi.core_1.1.0.m2
2 RESOLVED org.springframework.bundle.osgi.web_1.1.0.m2
3 RESOLVED org.springframework.bundle.osgi.io_1.1.0.m2
4 RESOLVED org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
5 RESOLVED jcl104.over.slf4j_1.4.3
6 RESOLVED slf4j.api_1.4.3
7 RESOLVED slf4j.log4j12_1.4.3
8 RESOLVED org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT
9 RESOLVED org.springframework.bundle.osgi.extender_1.1.0.m2
10 RESOLVED org.springframework.bundle.spring.context_2.5.4
11 RESOLVED org.springframework.bundle.spring.beans_2.5.4
12 RESOLVED org.springframework.bundle.spring.core_2.5.4
13 RESOLVED org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT
14 RESOLVED org.springframework.bundle.spring.aop_2.5.4
15 RESOLVED org.springframework.osgi.jsp-api.osgi_2.0.0.SNAPSHOT
16 RESOLVED org.springframework.osgi.jasper.osgi_5.5.23.SNAPSHOT
17 RESOLVED org.springframework.osgi.commons-el.osgi_1.0.0.SNAPSHOT
18 INSTALLED org.springframework.osgi.jstl.osgi_1.1.2.SNAPSHOT
19 RESOLVED org.springframework.osgi.catalina.osgi_6.0.16.SNAPSHOT
20 RESOLVED org.springframework.osgi.catalina.start.osgi_6.0.16.SNAPSHOT
21 RESOLVED org.springframework.osgi.cglib-nodep.osgi_2.1.3.SNAPSHOT
22 ACTIVE org.springframework.bundle.osgi.web.extender_1.1.0.m2-SNAPSHOT
23 ACTIVE org.springframework.osgi.catalina.start.osgi_1.0.0.SNAPSHOT
24 ACTIVE org.springframework.osgi.catalina.osgi_5.5.23.SNAPSHOT
26 ACTIVE pl.jaceklaskowski.osgi.spring-osgi-webapp_1.0.0

Aplikacja webowa spring-osgi-webapp działa!
Na koniec jeszcze raz próba z z Apache Felix 1.0.4 (coś mnie tknęło, że to jednak moja wcześniejsza niewiedza niż niedoskonałości Feliksa były przyczyną niepowodzenia).
jlaskowski@work /cygdrive/c/apps/felixKieruję przeglądarkę na adres aplikacji i okazuje się, że z Felix też działa! Wersje pakunków i ich stan (uruchomiony - ACTIVE bądź jedynie rozpoznany - RESOLVED) ma najwyraźniej znacznie.
$ rm -rf c\:/Documents\ and\ Settings/jlaskowski/.felix
jlaskowski@work /cygdrive/c/apps/felix
$ java -Dfelix.cache.profile=spring-osgi-webapp -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
...tutaj instaluję pakunki i niektóre uruchamiam (w stanie ACTIVE)
-> ps
START LEVEL 1
ID State Level Name
[ 0] [Active ] [ 0] System Bundle (1.0.4)
[ 1] [Active ] [ 1] Apache Felix Shell Service (1.0.1)
[ 2] [Active ] [ 1] Apache Felix Shell TUI (1.0.1)
[ 3] [Active ] [ 1] Apache Felix Bundle Repository (1.0.3)
[ 4] [Active ] [ 1] spring-osgi-core (1.1.0.m2)
[ 5] [Resolved ] [ 1] spring-osgi-web (1.1.0.m2)
[ 6] [Resolved ] [ 1] spring-osgi-io (1.1.0.m2)
[ 7] [Resolved ] [ 1] servlet-api.osgi (2.5.0.SNAPSHOT)
[ 8] [Resolved ] [ 1] jcl104-over-slf4j (1.4.3)
[ 9] [Resolved ] [ 1] slf4j-api (1.4.3)
[ 10] [Resolved ] [ 1] slf4j-log4j12 (1.4.3)
[ 11] [Resolved ] [ 1] log4j.osgi (1.2.15.SNAPSHOT)
[ 12] [Installed ] [ 1] spring-osgi-extender (1.1.0.m2)
[ 13] [Resolved ] [ 1] spring-context (2.5.4)
[ 14] [Resolved ] [ 1] spring-beans (2.5.4)
[ 15] [Resolved ] [ 1] spring-core (2.5.4)
[ 16] [Resolved ] [ 1] aopalliance.osgi (1.0.0.SNAPSHOT)
[ 17] [Resolved ] [ 1] spring-aop (2.5.4)
[ 18] [Resolved ] [ 1] jsp-api.osgi (2.0.0.SNAPSHOT)
[ 19] [Resolved ] [ 1] jasper.osgi (5.5.23.SNAPSHOT)
[ 20] [Resolved ] [ 1] commons-el.osgi (1.0.0.SNAPSHOT)
[ 21] [Installed ] [ 1] jstl.osgi (1.1.2.SNAPSHOT)
[ 22] [Resolved ] [ 1] cglib-nodep.osgi (2.1.3.SNAPSHOT)
[ 23] [Active ] [ 1] spring-osgi-web-extender (1.1.0.m2-SNAPSHOT)
[ 24] [Active ] [ 1] catalina.start.osgi (1.0.0.SNAPSHOT)
[ 25] [Active ] [ 1] catalina.osgi (5.5.23.SNAPSHOT)
[ 26] [Active ] [ 1] spring-osgi-webapp Maven Webapp (1.0)
A na koniec ciekawa lektura SpringSource Launches New Application Server without Java EE. I co?! Kto już o tym wspominał rok temu, że aspiracjami i21 czy teraz SpringSource to właśnie rynek serwerów aplikacyjnych, gdzie możnaby potraktować Spring Framework z dodatkami jako właśnie serwer aplikacyjny?! Ciekawe, co teraz oponenci takiego spojrzenia mają do powiedzenia?! Zamieniam się w słuch...
Pytanie konkursowe: Jaki nagłówek manifestu służy Spring-DM do rozpoznania pakunku aplikacji webowej do uruchomienia? Nagród nie przewiduje się.
Subskrybuj:
Posty (Atom)
