Okazuje się, że w przeciwieństwie do mojego wczorajszego pesymizmu o mojej znajomości tematu usług sieciowych (patrz: Zabieram się za JAX-WS), dzisiaj, ku mojemu zdumieniu, otrzymałem następującą wiadomość:
Dear Jacek (Certification ID#: SUN295099)
Congratulations on completing all the requirements for the
Sun Certified Developer for Java Web Services 5 certification. You were certified on 12/10/2008.
Congratulations!
Certification Department
W ten sposób stałem się posiadaczem certyfikatu Sun Certified Developer for Java Web Services 5 (SCDJWS5). Do pełni szczęścia brakuje mi jeszcze informacji o wynikach z poszczególnych obszarów tematycznych, bo pakiet certyfikacyjny jeszcze w drodze.
Jeśli ktoś zapyta, jak się przygotowywałem, z jakich książek korzystałem, to niestety nie będę miał satysfakcjonującej odpowiedzi - po prostu podszedłem do egzaminu "z biegu" i okazuje się, że najwięcej wiedzy dało mi wcześniejsze rozpoznawanie tematu EJB3 z jego @WebService i próby uruchomienia usług sieciowych na bazie EJB3 z Apache Geronimo. Zapomniałem nawet, że udało mi się opublikować kilka artykułów na ten temat - Tworzenie usługi sieciowej z JAX-WS, Tworzenie usługi sieciowej z JAX-WS, Apache Geronimo 2 i NetBeans 6 czy SCAlanie z JAX-WS.
Chciałbym podziękować Grzegorzowi Dudzie za jego wpis SCDJWS za darmo, który był początkiem całej historii (patrz: Sun Certified Developer for Java Web Services (SCDJWS) bezpłatnie do 10 grudnia!). Wielkie dzięki Grześ!
Czy ktoś jeszcze podchodził do tego certyfikatu? Jak poszło?
Wracam do lektury Service Oriented Architecture with Java autorstwa Vincenzo Caselli, Binildas A. Christudas, Malhar Barai (Packt, June 2008). Już się naczekała na swoje "5 minut" na półce Biblioteczki Warszawskiego JUGa. Pierwszy rozdział to porażka - masło maślane, literówki, nuda, ale rozdział 2. czyta się przyjemnie(j). I jest ciekawy przykład z uruchomieniem usługi sieciowej JAX-WS z Endpoint.publish(String address, Object implementor). Takie ciekawostki sprawiają, że czytanie książek, nawet tych początkowo nudnych, może mile zaskoczyć.
07 lutego 2009
06 lutego 2009
Zabieram się za JAX-WS
Nowe książki o Groovy i Grails jeszcze nie dotarły, więc pomyślałem, aby zabrać się za rozpoznanie tematu Java API for XML-Based Web Services (JAX-WS) 2.0. Do tej pory tematyka usług sieciowych (ang. web services) była przeze mnie traktowana po macoszemu, a na mojej liście do rozpoznania leżała od miesięcy i nie ma co więcej czekać. Uzbrojony w wiedzę o Groovy (po lekturze książki Book review: Beginning Groovy and Grails: From Novice to Professional) wydaje mi się, że teraz każdy temat pójdzie gładko, więc dlaczego nie zająć się JAX-WS i przyjrzeć mu się bliżej, może nawet z Groovy w tle?
Zacząłem od pobrania materiałów - specyfikacji JAX-WS 2.0 oraz referencyjnej implementacji JAX-WS RI ze strony domowej specyfikacji, dokumentacji Java Web Services Tutorial 2.0 oraz ostatniego wydania rozwojowego NetBeans IDE 7.0 (ten niestety mnie zaskoczył brakiem pliku uruchomieniowego dla Windows w dzisiejszej wersji rozwojowej, więc będę musiał poczekać na kolejną!). Jest jeszcze do nauki (Free) Web Services and SOA Programming (with Passion!) Hands-on Online Course.
Instalacja JAX-WS RI to uruchomienie instalatora i można próbować się z tematem.
Nie potrafię wytłumaczyć dlaczego, ale zawsze wspominając o JAX-WS na myśl przychodził mi projekt Apache CXF. Zacząłem przeszukiwać jego dokumentację i o dziwo trafiłem na powiązanie CXF z...OSGi - Distributed OSGi. Jeśli jeszcze dostanę się do informacji, że można połączyć Groovy z CXF (dlaczego by nie, skoro Groovy to Java?), a w tle będzie OSGi, może i Grails, byłbym w ogóle szczęśliwy. Na razie wezmę się za lekturę specyfikacji JAX-WS i podłubię po trochu w NetBeans. Później wrócę do CXF, a w międzyczasie przyjdą kolejne książki o Groovy i Grails, i wrócę do nich. Wszystko ustawione. Skoro wszystko mam, wracam do czytania i (potencjalnie) relacji na blogu. Kto by pomyślał, że tak mi przypadnie to czytanie do gustu?!
Zacząłem od pobrania materiałów - specyfikacji JAX-WS 2.0 oraz referencyjnej implementacji JAX-WS RI ze strony domowej specyfikacji, dokumentacji Java Web Services Tutorial 2.0 oraz ostatniego wydania rozwojowego NetBeans IDE 7.0 (ten niestety mnie zaskoczył brakiem pliku uruchomieniowego dla Windows w dzisiejszej wersji rozwojowej, więc będę musiał poczekać na kolejną!). Jest jeszcze do nauki (Free) Web Services and SOA Programming (with Passion!) Hands-on Online Course.
Instalacja JAX-WS RI to uruchomienie instalatora i można próbować się z tematem.
jlaskowski@work /cygdrive/c/appsPoza tym gotowe środowisko jest dystrybuowane w Java SE 6, więc nawet ten krok nie jest konieczny.
$ java -jar JAXWS2.1.1_20070501.jar
jaxws-ri
...
installation complete
Nie potrafię wytłumaczyć dlaczego, ale zawsze wspominając o JAX-WS na myśl przychodził mi projekt Apache CXF. Zacząłem przeszukiwać jego dokumentację i o dziwo trafiłem na powiązanie CXF z...OSGi - Distributed OSGi. Jeśli jeszcze dostanę się do informacji, że można połączyć Groovy z CXF (dlaczego by nie, skoro Groovy to Java?), a w tle będzie OSGi, może i Grails, byłbym w ogóle szczęśliwy. Na razie wezmę się za lekturę specyfikacji JAX-WS i podłubię po trochu w NetBeans. Później wrócę do CXF, a w międzyczasie przyjdą kolejne książki o Groovy i Grails, i wrócę do nich. Wszystko ustawione. Skoro wszystko mam, wracam do czytania i (potencjalnie) relacji na blogu. Kto by pomyślał, że tak mi przypadnie to czytanie do gustu?!
05 lutego 2009
Groovy i Grails, Bloger Roku 2008, 4Developers i Refaktoryzacja
Skończyłem książkę o Groovy i Grails - Beginning Groovy and Grails: From Novice to Professional, co czytelnicy mojego bloga mogli dostrzec przez ostatnie 2 tygodnie. Od razu wziąłem się za recenzję i opublikowałem ją u siebie w Wiki Book review: Beginning Groovy and Grails: From Novice to Professional, którą również opublikowałem na Amazonie - The book made me a single-technology addict. Wystarczył jeden dzień i "1 of 1 people found the following review helpful". Nie spodziewałem się tak szybkich reakcji.
Skoro wszedłem w nastrój na czytanie książek poprosiłem o kolejne z Apressu:
Thanks so much Jacek! What a great review. We will indeed have the books you requested out to you soon.
Zdaje się, że Groovy i Grails nie opuszczą mnie tak prędko, czego sobie i Wam życzę ;-)
Jeden konkurs minął, a zaczął się kolejny - Bloger Roku 2008. Ten będzie trochę tańszy, bo nie wymaga żadnych SMSów, tylko 3 sekundy Twojego czasu. Wchodzimy na stronę konkursową dla Notatnika (niestety bez potwierdzenia, że faktycznie na niej jesteście!), wpisujemy poprawny adres email i OK. Wdzięczność gwarantowana!
Jeśli jeszcze nie masz planów na 7 marca 2009 (sobota) i będziesz w pobliżu Krakowa warto rozważyć udział w konferencji "dla programistów tworzona przez programistów" - 4Developers. Będzie wiele ciekawych osób (Grzegorz Duda z "Java Underground", Waldemar "Waldi" Kot ze swoim CEPem i Adam Bien, nie zapominając o Nealu Fordzie) , więc i Ciebie nie powinno zabraknąć. Będę i ja z tematem "Zwinne i lekkie aplikacje webowe w Javie z Groovy, Grails i Project Zero". Jest jeszcze trochę czasu, aby podstroić temat i przygotować się na serię pytań, których spodziewam się nie będzie mało. Może warto rozważyć przesłanie mi kilku zawczasu, abym przygotował odpowiedź inną niż "Zapiszę i sprawdzę"? Czekam z niecierpliwością, bo szkoda byłoby powtarzać coś, co wielu dobrze już zna.
Mimo, iż pojawia się jako ostatnia wiadomość, lektura książki "Jak odmienić sposób programowania używając refaktoryzacji" zajęła mi dłuższą chwilę w ostatni weekend. Przyznaję, że nigdy wcześniej nie rozważałem refaktoryzacji jako specjalnego tematu do rozważań - po prostu temat wydawał mi się na tyle integralny w zestawie "narzędzi" programisty, że nie było się czym zajmować. Po prostu był i sądziłem, że wiedza jaką posiadałem była wystarczająca. Właśnie ta książka ukazała mi jak bardzo się myliłem, a w tym całe piękno refaktoryzacji i...prozy Mariusza Sieraczkiewicza. 110 stron czyta się niezwykle przyjemnie dzięki odpowiednio dobranej fabule. Czyta się ją z podobnym zacięciem jak inne książki sensacyjne, w których znajdziemy wprowadzenie do tematu, aby później rozwiązać go bardzo wyrafinowanymi acz prostymi w użyciu metodami. Nie inaczej było w tej książce - (trochę przydługawy) wstęp bodajże przez 2 czy 3 rozdziały, aby w kolejnych pokazać, co w trawie piszczy. Na bazie przykładowej aplikacji Mariusz przedstawia poszczególne kroki w dobrze przemyślanym procesie refaktoryzacji. Jakkolwiek w wielu miejscach, nie popełniłbym tak karygodnych błędów jak krótkie nazwy zmiennych, nieodpowiadające treści nazwy metod, przydługie ify, to nie przeszkodziło to wcale znaleźć w przykładzie wartościowych refaktoryzacji - oczywistych, a wciąż za rzadko stosowanych przeze mnie (zbyt często technika Copy-Paste'a zwycięża). Pora to zmienić i mam świadomość, że książka miała na tą decyzję niemały wpływ. Teraz stałem się wrażliwy refaktoryzacyjnie. Czujcie się ostrzeżeni! ;-)
Skoro wszedłem w nastrój na czytanie książek poprosiłem o kolejne z Apressu:
- The Definitive Guide to Grails, Second Edition
- Groovy and Grails Recipes
- Pro Spring Dynamic Modules for OSGi™ Service Platforms
Thanks so much Jacek! What a great review. We will indeed have the books you requested out to you soon.
Zdaje się, że Groovy i Grails nie opuszczą mnie tak prędko, czego sobie i Wam życzę ;-)
Jeden konkurs minął, a zaczął się kolejny - Bloger Roku 2008. Ten będzie trochę tańszy, bo nie wymaga żadnych SMSów, tylko 3 sekundy Twojego czasu. Wchodzimy na stronę konkursową dla Notatnika (niestety bez potwierdzenia, że faktycznie na niej jesteście!), wpisujemy poprawny adres email i OK. Wdzięczność gwarantowana!
Jeśli jeszcze nie masz planów na 7 marca 2009 (sobota) i będziesz w pobliżu Krakowa warto rozważyć udział w konferencji "dla programistów tworzona przez programistów" - 4Developers. Będzie wiele ciekawych osób (Grzegorz Duda z "Java Underground", Waldemar "Waldi" Kot ze swoim CEPem i Adam Bien, nie zapominając o Nealu Fordzie) , więc i Ciebie nie powinno zabraknąć. Będę i ja z tematem "Zwinne i lekkie aplikacje webowe w Javie z Groovy, Grails i Project Zero". Jest jeszcze trochę czasu, aby podstroić temat i przygotować się na serię pytań, których spodziewam się nie będzie mało. Może warto rozważyć przesłanie mi kilku zawczasu, abym przygotował odpowiedź inną niż "Zapiszę i sprawdzę"? Czekam z niecierpliwością, bo szkoda byłoby powtarzać coś, co wielu dobrze już zna.
Mimo, iż pojawia się jako ostatnia wiadomość, lektura książki "Jak odmienić sposób programowania używając refaktoryzacji" zajęła mi dłuższą chwilę w ostatni weekend. Przyznaję, że nigdy wcześniej nie rozważałem refaktoryzacji jako specjalnego tematu do rozważań - po prostu temat wydawał mi się na tyle integralny w zestawie "narzędzi" programisty, że nie było się czym zajmować. Po prostu był i sądziłem, że wiedza jaką posiadałem była wystarczająca. Właśnie ta książka ukazała mi jak bardzo się myliłem, a w tym całe piękno refaktoryzacji i...prozy Mariusza Sieraczkiewicza. 110 stron czyta się niezwykle przyjemnie dzięki odpowiednio dobranej fabule. Czyta się ją z podobnym zacięciem jak inne książki sensacyjne, w których znajdziemy wprowadzenie do tematu, aby później rozwiązać go bardzo wyrafinowanymi acz prostymi w użyciu metodami. Nie inaczej było w tej książce - (trochę przydługawy) wstęp bodajże przez 2 czy 3 rozdziały, aby w kolejnych pokazać, co w trawie piszczy. Na bazie przykładowej aplikacji Mariusz przedstawia poszczególne kroki w dobrze przemyślanym procesie refaktoryzacji. Jakkolwiek w wielu miejscach, nie popełniłbym tak karygodnych błędów jak krótkie nazwy zmiennych, nieodpowiadające treści nazwy metod, przydługie ify, to nie przeszkodziło to wcale znaleźć w przykładzie wartościowych refaktoryzacji - oczywistych, a wciąż za rzadko stosowanych przeze mnie (zbyt często technika Copy-Paste'a zwycięża). Pora to zmienić i mam świadomość, że książka miała na tą decyzję niemały wpływ. Teraz stałem się wrażliwy refaktoryzacyjnie. Czujcie się ostrzeżeni! ;-)
04 lutego 2009
Inni klienci aplikacji w Grails - rozdział 13 z "Beginning Groovy and Grails"
Ostatni rozdział 13. "Alternative Clients" w książce Beginning Groovy and Grails: From Novice to Professional przedstawia temat klientów aplikacji grailsowej innych niż przeglądarka. Już w poprzednim rozdziale o REST mieliśmy możliwość poznać klienta RESTowego w postaci skryptu Groovy, a teraz autorzy omówili tworzenie skryptów Groovy, które korzystają z usług sieciowych (ang. web services) i posiadają bardziej zaawansowany interfejs użytkownika.
Tworzenie aplikacji GUI w Groovy wymaga pobrania dodatkowych bibliotek - SwingXBuilder, SwingX, JGoodies Forms i Glazed Lists. Ich instalacja w Groovy (teraz jesteśmy na poziomie Groovy, a nie Grails) to umieszczenie ich w CLASSPATH, w <katalog-domowy-groovy>/lib lub <katalog-domowy-użytkownika>/groovy/lib.
SwingXBuilder to Groovy "builder" (jak ja miałbym to przetłumaczyć?! Może budowniczy...Bob?!) do tworzenia interfejsu użytkownika w Swingu. Pod spodem korzysta z biblioteki SwingX. JGoodies FormLayout jest popularnym zarządcą układu (ang. layout manager) dla Swinga. Glazed Lists natomiast jest bardzo zaawansowanym komponentem Swing do tworzenia tabel. Ze SwingXBuilder oraz komponentami SwingX tworzymy okienka dialogowe, podpowiedzi i pasek statusu, z Glazed Lists sortowane tabele, a JGoodies Forms obsłuży ich rozkład.
Do skryptu Groovy przekazywany jest parametr args, który jest listą parametrów wejściowych skryptu, np. (Listing 13-1):
W skryptach możemy skorzystać z narzędzia JLine do obsługi wprowadzanego przez użytkownika tekstu z linii poleceń, np. ukrycia wpisywanego hasła, np. (Listing 13-2):
Groovy może wszystko, co potrafi Java. Według autorów, tworzenie GUI w Javie to wybór między Java Swing a Eclipse Standard Widget Toolkit (SWT). Można, więc zamiast programować w Javie i korzystać ze wspomnianych bibliotek, programować w Groovy. Znaczne uproszczenie daje skorzystanie z "budowniczych" (ang. builders) w Groovy - SwingBuilder, SwingXBuilder czy JideBuilder dla Swing oraz SwtBuilder dla SWT. Rozkład komponentów, definiowanie ich akcji jest znacznie prostsze z ich pomocą, np. (Listing 13-5):
Podsumowaniem rozdziału są zdania
"The important thing to remember is that "Groovy is Java" and that allows you to use any of the Java components and libraries you want to build an application."
oraz
"Our goal was to give you a sample of what is possible. You are only limited by your imagination."
Wyjdzie w praniu, jak bardzo się (nie)pomylili. ;-)
W ten sposób, dobrnąłem do samego końca książki Beginning Groovy and Grails: From Novice to Professional, którą wpisuję na listę książek przeczytanych "od deski do deski". Czy warto było? Zdecydowanie TAK! Sama dokumentacja Grails jest bardzo wartościowym źródłem wiedzy o nim, ale książki mają to do siebie, że ich treść prowadzona jest jak pewien projekt, w którym kolejne rozdziały dotykają funkcjonalności wymaganej w kolejnych iteracjach rozwoju aplikacji. Tak też było w przypadku tej książki. Dodatkowo miałem okazję poznać wiele wspomagających projektów, o których nawet nie wiedziałem, że istnieją (!) Jeśli przyjdzie mi realizować projekt aplikacji webowej Grails będzie z pewnością mocnym kandydatem do jego realizacji (obok Apache Wicket, JBoss Seam i JSF - chociaż samo JSF wydaje się być bardzo prymitywne przy poprzednikach). Grails, swoją funkcjonalnością nie odbiega od innych znanych mi szkieletów webowych, a w wielu miejscach przebija ich o głowę (chociażby scaffolding, klasy dziedzinowe z metodami bazodanowymi, "builders", zintegrowany tandem Hibernate+Spring Framework czy Groovy jako język programowania), a jedynym problemem, jaki mógłbym podnieść teraz, to brak własnego doświadczenia wdrożeniowego, w którym mógłbym sprawdzić siłę Grails w boju. Po lekturze książki nie spodziewałbym się wielu wpadek, ale diabeł tkwi w szczegółach i nie twierdzę, że ich nie byłoby. Może dzięki zmniejszeniu ilości czasu potrzebnego na stworzenie aplikacji (dzięki wspomnianym wcześniej cechom Grails) miałbym czas na rozwiązanie potencjalnych niedoskonałości? Mam wrażenie, że tak. A jak Wam idzie wdrażanie aplikacji opartych na Grailsie? Wciąż działają? Z kim konkurowały podczas etapu wyboru tego właściwego szkieletu webowego?
Tworzenie aplikacji GUI w Groovy wymaga pobrania dodatkowych bibliotek - SwingXBuilder, SwingX, JGoodies Forms i Glazed Lists. Ich instalacja w Groovy (teraz jesteśmy na poziomie Groovy, a nie Grails) to umieszczenie ich w CLASSPATH, w <katalog-domowy-groovy>/lib lub <katalog-domowy-użytkownika>/groovy/lib.
SwingXBuilder to Groovy "builder" (jak ja miałbym to przetłumaczyć?! Może budowniczy...Bob?!) do tworzenia interfejsu użytkownika w Swingu. Pod spodem korzysta z biblioteki SwingX. JGoodies FormLayout jest popularnym zarządcą układu (ang. layout manager) dla Swinga. Glazed Lists natomiast jest bardzo zaawansowanym komponentem Swing do tworzenia tabel. Ze SwingXBuilder oraz komponentami SwingX tworzymy okienka dialogowe, podpowiedzi i pasek statusu, z Glazed Lists sortowane tabele, a JGoodies Forms obsłuży ich rozkład.
Do skryptu Groovy przekazywany jest parametr args, który jest listą parametrów wejściowych skryptu, np. (Listing 13-1):
if (args.size() < 2) {
...
}
def userid = args[0]
def password = args[1]Uruchomienie skryptu Groovy to wykonanie groovy <nazwa-skryptu> <parametry>.W skryptach możemy skorzystać z narzędzia JLine do obsługi wprowadzanego przez użytkownika tekstu z linii poleceń, np. ukrycia wpisywanego hasła, np. (Listing 13-2):
import jline.ConsoleReaderJLine jest dystrybuowany z Groovy.
ConsoleReader cr = new jline.ConsoleReader()
print "User id: "
def userid = cr.readLine()
print "Password: "
def password = cr.readLine(new Character('*' as char))
// można również połączyć print i readLine
def uzytkownik = cr.readLine("Użytkownik: ")
Groovy może wszystko, co potrafi Java. Według autorów, tworzenie GUI w Javie to wybór między Java Swing a Eclipse Standard Widget Toolkit (SWT). Można, więc zamiast programować w Javie i korzystać ze wspomnianych bibliotek, programować w Groovy. Znaczne uproszczenie daje skorzystanie z "budowniczych" (ang. builders) w Groovy - SwingBuilder, SwingXBuilder czy JideBuilder dla Swing oraz SwtBuilder dla SWT. Rozkład komponentów, definiowanie ich akcji jest znacznie prostsze z ich pomocą, np. (Listing 13-5):
swing = new SwingXBuilder()Potwierdzeniem możliwości SwingXBuilder jest wersja Groovy Console, która znajduje się w repozytorium SwingXBuilder w demos/Console.
swing.lookAndFeel('system')
swing.action(id: 'exitAction',
name: 'Exit'
closure: this.&exit,
mnemonic: 'x',
accelerator: 'F4'
shortDescription: 'Exit SimpleUI'
}
void exit(event) {
System.exit(0)
}
Podsumowaniem rozdziału są zdania
"The important thing to remember is that "Groovy is Java" and that allows you to use any of the Java components and libraries you want to build an application."
oraz
"Our goal was to give you a sample of what is possible. You are only limited by your imagination."
Wyjdzie w praniu, jak bardzo się (nie)pomylili. ;-)
W ten sposób, dobrnąłem do samego końca książki Beginning Groovy and Grails: From Novice to Professional, którą wpisuję na listę książek przeczytanych "od deski do deski". Czy warto było? Zdecydowanie TAK! Sama dokumentacja Grails jest bardzo wartościowym źródłem wiedzy o nim, ale książki mają to do siebie, że ich treść prowadzona jest jak pewien projekt, w którym kolejne rozdziały dotykają funkcjonalności wymaganej w kolejnych iteracjach rozwoju aplikacji. Tak też było w przypadku tej książki. Dodatkowo miałem okazję poznać wiele wspomagających projektów, o których nawet nie wiedziałem, że istnieją (!) Jeśli przyjdzie mi realizować projekt aplikacji webowej Grails będzie z pewnością mocnym kandydatem do jego realizacji (obok Apache Wicket, JBoss Seam i JSF - chociaż samo JSF wydaje się być bardzo prymitywne przy poprzednikach). Grails, swoją funkcjonalnością nie odbiega od innych znanych mi szkieletów webowych, a w wielu miejscach przebija ich o głowę (chociażby scaffolding, klasy dziedzinowe z metodami bazodanowymi, "builders", zintegrowany tandem Hibernate+Spring Framework czy Groovy jako język programowania), a jedynym problemem, jaki mógłbym podnieść teraz, to brak własnego doświadczenia wdrożeniowego, w którym mógłbym sprawdzić siłę Grails w boju. Po lekturze książki nie spodziewałbym się wielu wpadek, ale diabeł tkwi w szczegółach i nie twierdzę, że ich nie byłoby. Może dzięki zmniejszeniu ilości czasu potrzebnego na stworzenie aplikacji (dzięki wspomnianym wcześniej cechom Grails) miałbym czas na rozwiązanie potencjalnych niedoskonałości? Mam wrażenie, że tak. A jak Wam idzie wdrażanie aplikacji opartych na Grailsie? Wciąż działają? Z kim konkurowały podczas etapu wyboru tego właściwego szkieletu webowego?
03 lutego 2009
Wdrażanie i aktualizacja aplikacji w Grails - rozdział 12 z "Beginning Groovy and Grails"
Po bardzo burzliwych rozdziałach przedstawiających architekturę Grails i potencjał jego wtyczek przyszła pora na niewielkie "podsumowanie" w postaci rozdziału 12. "Deploying and Upgrading". Autorzy wyjaśniają w nim, w jaki sposób uruchamiamy aplikacje grailsowe w ramach serwerów aplikacyjnych Java EE oraz aktualizujemy wersję Grails w aplikacji. Pojawi się również Gant, w którym stworzone zostanie nowe polecenie grails.
Grails dystrybuowany jest z całym środowiskiem rozwojowym opartym na Jetty oraz relacyjnej bazie danych HSQLDB. Wystarczy wykonać polecenie grails run-app, aby uruchomić aplikację w kompletnym środowisku uruchomieniowym - serwerem aplikacji i bazą danych. Brakuje w nim jednak cech środowisk produkcyjnych, z mechanizmami równoważenia obciążenia (ang. load balancing), wysokiej dostępności (ang. high availability) oraz klastrowania (ang. clustering) dla serwera aplikacyjnego oraz wydajnej i transakcyjnej bazy danych.
Wdrożenie (ang. deployment) aplikacji grailsowej składa się z trzech kroków. Najpierw definiujemy konfigurację aplikacji dla poszczególnych środowisk (rozwojowego, testowego i produkcyjnego), tworzymy wersję wdrożeniową w postaci pliku WAR (ang. Web ARchive), aby w końcu wdrożyć go na serwerze aplikacyjnym (kontenerze webowym/servletów).
W każdym ze środowisk, przyjdzie nam zdefiniować specyficzne parametry konfiguracyjne. Polecenie grails uruchamia środowisko w zależności od swojego drugiego parametru na linii poleceń lub w plikach konfiguracyjnych DataSource.groovy lub Config.groovy. Wyróżniamy trzy predefiniowane wartości dla każdego ze środowisk. Dla rozwojowego środowiska jest to dev (na linii poleceń) oraz development w plikach konfiguracyjnych, test (oba parametry) dla testowego oraz prod i production dla środowiska produkcyjnego. Możemy zdefiniować dodatkowe środowiska, np. testów integracyjnych, testów akceptacyjnych (ang. UAT - user Acceptance Tests) oraz testów wydajnościowych (ang. PT - Performance Tests) z dowolnie wybranymi przez nas identyfikatorami. Wskazanie własnego środowiska to wykonanie polecenia grails z parametrem grails.env, np. grails -Dgrails.env=uat run-app.
Grails zawiera 4 główne kategorie konfiguracyjne - konfiguracja adresów URL, domknięcie do wykonania przy uruchomieniu i zatrzymaniu aplikacji, źródła danych i poziomy komunikatów. Katalog grails-app/config jest katalogiem konfiguracyjnym Grails.
Domknięcie init z parametrem servletContext typu javax.servlet.ServletContext w grails-app/config/Bootstrap.groovy jest wykonywane każdorazowo przy uruchomieniu aplikacji (włączając w to sytuację ponownego wdrożenia), a destroy przy zatrzymaniu, aczkolwiek nie jest to gwarantowane, np. podczas zatrzymania serwera aplikacyjnego.
Za pomocą GrailsUtil.environment() możemy określić środowisko, w którym uruchomiona jest aplikacja i podjąć stosowne czynności.
Domyślnie, Grails skonfigurowany jest z wbudowaną bazą danych HSQLDB w trybie pamięciowym (ang. in-memory). Tym samym każde uruchomienie aplikacji to pusta baza danych. W grails-app/config/DataSource.groovy konfigurujemy bazę (sekcja dataSource) i Hibernate (sekcja hibernate). Możliwa jest konfiguracja obu per środowisko w sekcji environments, która nadpisuje bardziej ogólną konfigurację w sekcjach dataSource i hibernate. Nie zapominajmy o umieszczeniu pliku jar sterownika bazy danych w katalogu lib w projekcie. Podczas tworzenia paczki wdrożeniowej Grails umieści go w WEB-INF/lib.
Konfiguracja (poziomu) komunikatów oparta jest na Apache Commons Logging oraz Apache log4j. Znajduje się w grails-app/config/Config.groovy. Grails posiada kilka specjalnych kanałów (ang. loggers) - grails.app.controller dla komunikatów wszystkich kontrolerów, grails.app.domain dla klas domenowych, grails.app.service dla usług oraz grails.app.taglib dla znaczników GSP.
Tworzymy paczkę wdrożeniową aplikacji poleceniem grails war. Autorzy sugerują jednak bardziej wyrafinowany sposób składający się z...7 kroków - pobranie aktualnej wersji z repozytorium, wykonanie testów, zmianę parametru app.version w application.properties samodzielnie bądź poleceniem grails set-version, aby ustawić wersję przygotowywanej aplikacji, np. w formacie X.Y.Z, grails clean, dopiero wtedy grails war (prawdopodobnie ze wskazaniem środowiska produkcyjnego, np. grails prod war), ponowna zmiana app.version i zatwierdzenie application.properties do repozytorium.
W sekcji "Deploying to an Application Server" autorzy piszą "a WAR file can be deployed to Java EE application servers such as JBoss, GlassFish, Apache Geronimo...". I to jest to, co mi się bardzo spodobało. Jest Apache Geronimo! Tylko dlaczego dopiero na 3. pozycji?!
Grails umożliwia uruchomienie aplikacji na porcie HTTPS poleceniem grails run-https. Poza domyślnym portem 8080, aplikacja będzie dostępna na 8443.
Grails nie udostępnia specjalnych poleceń upraszczających wdrożenie aplikacji. Zaleca się użycie narzędzia Gant do tego celu. Gant jest narzędziem automatyzującym pracę w projekcie przez połączenie cech Apache Ant z Groovy - z pierwszego mamy gotowe zadania, a z drugiego język do ich oskryptowania (zamiast korzystać tradycyjnie z XML w Ant). Tak na prawdę polecenia grails to uruchamianie odpowiednich "skryptów" Gant. Stworzenie nowego polecenia dla grails to napisanie skryptu Gant i umieszczenie go w dowolnym z poniższych katalogów - <katalog-domowy-użytkownika>/.grails/scripts, <katalog-projektu>/scripts, <katalog-projektu>/plugins/*/scripts oraz <katalog-domowy-grails>/scripts. Autorzy przedstawiają przykładowy skrypt - a tym samym nowe polecenie grails deploy - do wdrożenia aplikacji na serwerze JBoss AS. Więcej na stronie http://www.beginninggroovyandgrails.com (dlaczego dopiero teraz pojawia się wzmianka o tej stronie?!).
Podczas uruchomienia aplikacji poleceniem grails run-app(s) Grails sprawdza parametr app.grails.version w application.properties, który znajduje się w katalogu głównym projektu aplikacji. Jeśli wartość app.grails.version nie jest zgodna z bieżącą wersją Grails pojawi się komunikat informujący o rozbieżności wersji. Wykonanie grails upgrade uaktualni pliki Grails w projekcie...nadpisując już istniejące (!) Kolejny powód, aby utrzymywać projekt aplikacji w repozytorium.
Jest to ostatni rozdział dotyczący zagadnień projektowych Grails jako szkieletu webowego Java EE. Kolejny i tym samym ostatni będzie o tworzeniu różnego rodzaju klientów dla naszej aplikacji.
Grails dystrybuowany jest z całym środowiskiem rozwojowym opartym na Jetty oraz relacyjnej bazie danych HSQLDB. Wystarczy wykonać polecenie grails run-app, aby uruchomić aplikację w kompletnym środowisku uruchomieniowym - serwerem aplikacji i bazą danych. Brakuje w nim jednak cech środowisk produkcyjnych, z mechanizmami równoważenia obciążenia (ang. load balancing), wysokiej dostępności (ang. high availability) oraz klastrowania (ang. clustering) dla serwera aplikacyjnego oraz wydajnej i transakcyjnej bazy danych.
Wdrożenie (ang. deployment) aplikacji grailsowej składa się z trzech kroków. Najpierw definiujemy konfigurację aplikacji dla poszczególnych środowisk (rozwojowego, testowego i produkcyjnego), tworzymy wersję wdrożeniową w postaci pliku WAR (ang. Web ARchive), aby w końcu wdrożyć go na serwerze aplikacyjnym (kontenerze webowym/servletów).
W każdym ze środowisk, przyjdzie nam zdefiniować specyficzne parametry konfiguracyjne. Polecenie grails uruchamia środowisko w zależności od swojego drugiego parametru na linii poleceń lub w plikach konfiguracyjnych DataSource.groovy lub Config.groovy. Wyróżniamy trzy predefiniowane wartości dla każdego ze środowisk. Dla rozwojowego środowiska jest to dev (na linii poleceń) oraz development w plikach konfiguracyjnych, test (oba parametry) dla testowego oraz prod i production dla środowiska produkcyjnego. Możemy zdefiniować dodatkowe środowiska, np. testów integracyjnych, testów akceptacyjnych (ang. UAT - user Acceptance Tests) oraz testów wydajnościowych (ang. PT - Performance Tests) z dowolnie wybranymi przez nas identyfikatorami. Wskazanie własnego środowiska to wykonanie polecenia grails z parametrem grails.env, np. grails -Dgrails.env=uat run-app.
Grails zawiera 4 główne kategorie konfiguracyjne - konfiguracja adresów URL, domknięcie do wykonania przy uruchomieniu i zatrzymaniu aplikacji, źródła danych i poziomy komunikatów. Katalog grails-app/config jest katalogiem konfiguracyjnym Grails.
Domknięcie init z parametrem servletContext typu javax.servlet.ServletContext w grails-app/config/Bootstrap.groovy jest wykonywane każdorazowo przy uruchomieniu aplikacji (włączając w to sytuację ponownego wdrożenia), a destroy przy zatrzymaniu, aczkolwiek nie jest to gwarantowane, np. podczas zatrzymania serwera aplikacyjnego.
Za pomocą GrailsUtil.environment() możemy określić środowisko, w którym uruchomiona jest aplikacja i podjąć stosowne czynności.
Domyślnie, Grails skonfigurowany jest z wbudowaną bazą danych HSQLDB w trybie pamięciowym (ang. in-memory). Tym samym każde uruchomienie aplikacji to pusta baza danych. W grails-app/config/DataSource.groovy konfigurujemy bazę (sekcja dataSource) i Hibernate (sekcja hibernate). Możliwa jest konfiguracja obu per środowisko w sekcji environments, która nadpisuje bardziej ogólną konfigurację w sekcjach dataSource i hibernate. Nie zapominajmy o umieszczeniu pliku jar sterownika bazy danych w katalogu lib w projekcie. Podczas tworzenia paczki wdrożeniowej Grails umieści go w WEB-INF/lib.
Konfiguracja (poziomu) komunikatów oparta jest na Apache Commons Logging oraz Apache log4j. Znajduje się w grails-app/config/Config.groovy. Grails posiada kilka specjalnych kanałów (ang. loggers) - grails.app.controller dla komunikatów wszystkich kontrolerów, grails.app.domain dla klas domenowych, grails.app.service dla usług oraz grails.app.taglib dla znaczników GSP.
Tworzymy paczkę wdrożeniową aplikacji poleceniem grails war. Autorzy sugerują jednak bardziej wyrafinowany sposób składający się z...7 kroków - pobranie aktualnej wersji z repozytorium, wykonanie testów, zmianę parametru app.version w application.properties samodzielnie bądź poleceniem grails set-version, aby ustawić wersję przygotowywanej aplikacji, np. w formacie X.Y.Z, grails clean, dopiero wtedy grails war (prawdopodobnie ze wskazaniem środowiska produkcyjnego, np. grails prod war), ponowna zmiana app.version i zatwierdzenie application.properties do repozytorium.
W sekcji "Deploying to an Application Server" autorzy piszą "a WAR file can be deployed to Java EE application servers such as JBoss, GlassFish, Apache Geronimo...". I to jest to, co mi się bardzo spodobało. Jest Apache Geronimo! Tylko dlaczego dopiero na 3. pozycji?!
Grails umożliwia uruchomienie aplikacji na porcie HTTPS poleceniem grails run-https. Poza domyślnym portem 8080, aplikacja będzie dostępna na 8443.
Grails nie udostępnia specjalnych poleceń upraszczających wdrożenie aplikacji. Zaleca się użycie narzędzia Gant do tego celu. Gant jest narzędziem automatyzującym pracę w projekcie przez połączenie cech Apache Ant z Groovy - z pierwszego mamy gotowe zadania, a z drugiego język do ich oskryptowania (zamiast korzystać tradycyjnie z XML w Ant). Tak na prawdę polecenia grails to uruchamianie odpowiednich "skryptów" Gant. Stworzenie nowego polecenia dla grails to napisanie skryptu Gant i umieszczenie go w dowolnym z poniższych katalogów - <katalog-domowy-użytkownika>/.grails/scripts, <katalog-projektu>/scripts, <katalog-projektu>/plugins/*/scripts oraz <katalog-domowy-grails>/scripts. Autorzy przedstawiają przykładowy skrypt - a tym samym nowe polecenie grails deploy - do wdrożenia aplikacji na serwerze JBoss AS. Więcej na stronie http://www.beginninggroovyandgrails.com (dlaczego dopiero teraz pojawia się wzmianka o tej stronie?!).
Podczas uruchomienia aplikacji poleceniem grails run-app(s) Grails sprawdza parametr app.grails.version w application.properties, który znajduje się w katalogu głównym projektu aplikacji. Jeśli wartość app.grails.version nie jest zgodna z bieżącą wersją Grails pojawi się komunikat informujący o rozbieżności wersji. Wykonanie grails upgrade uaktualni pliki Grails w projekcie...nadpisując już istniejące (!) Kolejny powód, aby utrzymywać projekt aplikacji w repozytorium.
Jest to ostatni rozdział dotyczący zagadnień projektowych Grails jako szkieletu webowego Java EE. Kolejny i tym samym ostatni będzie o tworzeniu różnego rodzaju klientów dla naszej aplikacji.
02 lutego 2009
40. spotkanie Warszawskiej Grupy Użytkowników Technologii Java (Warszawa JUG)
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG) zaprasza na 40. spotkanie, które odbędzie się 03.02.2009 (wtorek) o godzinie 18:00 w sali 5440 Wydziału MIMUW przy ul. Banacha 2 w Warszawie.
Temat prezentacji: Liferay / WebSynergy - portal (miś) na miarę naszych możliwości
Prowadzący: Piotr Pietrzak
Prezentacja przedstawi funkcjonalność Liferay Portal, który jest kontenerem portletów. Zobaczymy jak dostosować portal do swoich wymagań (wygląd, polonizacja) oraz jak wygodnie/wydajnie można programować w środowisku portletowym. Porównane zostaną sposoby komunikacji międzyportletowej i wykorzystamy mechanizm Comet. Na koniec zobaczymy języki skryptowe (na przykładzie PHP) jako języki do tworzenia portletów.
Piotr Pietrzak jest pracownikiem Działu Aplikacji Komputerowych (DAK) Uniwersytetu Warszawskiego. Zainteresowany głównie Javą, bazami danych (najchętniej nierelacyjnymi), w wolnych chwilach troluje na grupach i tworzy ciekawe, lecz zupełnie nieprzydatne projekty w Javie, PHP i od niedawna w Erlangu.
Planowany czas prezentacji to 1,5 godziny, po której planuje się 15-30-minutową dyskusję.
Wstęp wolny!
Zapraszam w imieniu grupy Warszawa JUG!
Temat prezentacji: Liferay / WebSynergy - portal (miś) na miarę naszych możliwości
Prowadzący: Piotr Pietrzak
Prezentacja przedstawi funkcjonalność Liferay Portal, który jest kontenerem portletów. Zobaczymy jak dostosować portal do swoich wymagań (wygląd, polonizacja) oraz jak wygodnie/wydajnie można programować w środowisku portletowym. Porównane zostaną sposoby komunikacji międzyportletowej i wykorzystamy mechanizm Comet. Na koniec zobaczymy języki skryptowe (na przykładzie PHP) jako języki do tworzenia portletów.
Piotr Pietrzak jest pracownikiem Działu Aplikacji Komputerowych (DAK) Uniwersytetu Warszawskiego. Zainteresowany głównie Javą, bazami danych (najchętniej nierelacyjnymi), w wolnych chwilach troluje na grupach i tworzy ciekawe, lecz zupełnie nieprzydatne projekty w Javie, PHP i od niedawna w Erlangu.
Planowany czas prezentacji to 1,5 godziny, po której planuje się 15-30-minutową dyskusję.
Wstęp wolny!
Zapraszam w imieniu grupy Warszawa JUG!
01 lutego 2009
Przetwarzanie wsadowe w Grails - rozdział 11 z "Beginning Groovy and Grails"
Rozdział 11. "Batch Processing" w książce Beginning Groovy and Grails: From Novice to Professional omawia temat przetwarzania wsadowego w Grails. Zdumiewające jest pierwsze zdanie rozpoczynające rozdział "Grails is more than just a web framework - it is an application framework". Wydaje się, że może być to bardzo zdumiewające, nie tylko dla takich nowicjuszy grailsowych jak ja. Od jakiegoś czasu śledzę grupę dyskusyjną Grails User, przeglądałem dokumentację na oficjalnej stronie Grails i do tej pory nie trafiłem na podobne stwierdzenie.
Prawie wszystkie aplikacje zawierają funkcjonalność, która musi być wykonywana o określonych porach lub co zadany interwał, którą nazywamy przetwarzaniem wsadowym (ang. batch processing).
W Grails obsługa przetwarzania wsadowego opiera się na otwartym projekcie Quartz, który dostarczany jest w ramach podstawy infrastrukturalnej Grails - Spring Framework. Quartz jest podobny do uniksowego crona, który uruchamia zadania w przyszłości, z tą różnicą, że może korzystać z komponentów aplikacyjnych udostępnianych w ramach serwera aplikacyjnego.
Pracę z Quartz w Grails rozpoczynamy jego instalacją poleceniem grails install-plugin quartz. Wtyczka dostarcza nowe polecenie grails create-job.
Zadanie (ang. job) jest aplikacją, którą chcemy wykonać o zadanej porze. Określamy co i kiedy ma być wykonywane.
Tworzymy zadanie poleceniem grails create-job <nazwa-zadania>. Powstanie klasa <NazwaZadania>Job w grails/job. Konwencją Grails jest, że polecenia create-* tworzą klasy o zadanej przez użytkownika nazwie dodając przyrostek odpowiadający poleceniu, np. create-job first tworzy klasę FirstJob. Domyślna klasa zbudowana jest z atrybutu timeout, który określa, co ile wykonywane będzie zadanie zdefiniowane przez domknięcie execute().
W rozdziale znajduje się przykład tworzenia funkcjonalności tworzenia i rozsyłania raportów w trybie wsadowym oparte na klasach i usługach stworzonych w rozdziałach wcześniejszych.
Klasa zadania może zawierać opcjonalne atrybuty name oraz group. Definiują one, odpowiednio, nazwę zadania oraz jego grupę.
Domyślnie zadanie związane jest z sesją Hibernate, więc pobieranie danych z bazy nie wymaga specjalnych czynności. Wyłączenie wiązania zadania z sesją Hibernate jest możliwe, jeśli ustawimy atrybut sessionRequired na false.
Mamy dwie możliwości definiowania pory wykonania zadania - atrybuty startDelay z timeout lub cronExpression. Atrybut startDelay (domyślnie 0) określa, kiedy wykonane zostanie zadanie, licząc od uruchomienia aplikacji. Atrybut timeout (domyślnie 60000 ms = 1 min) określa interwał (w milisekundach) między kolejnymi wykonaniami zadania. Atrybut cronExpression to możliwość wykorzystania własnej wiedzy uniksowej dotyczącej demona cron. Deklarujemy wykonanie zadanie w formacie crontab.
Może się zdarzyć, że wykonanie zadania nie zakończy się, a kolejne zostanie uruchomione. Kontrola równoległego wykonywania zadań jest możliwa przez logiczny atrybut concurrent (false/true).
Format cronExpression składa się z 6 pól oddzielonych białym znakiem (spacja/tabulacja). Poszczególne pola odpowiadają sekundom, minutom, godzinom, dniom, miesiącom, dniom tygodnia i opcjonalnie, w 7. polu, latom. Specjalne znaki to gwiazdka (*), znak zapytania (?), myślnik (-), przecinek (,) oraz ukośnik (/).
Zadanie ma dostęp do automatycznego wiązania zależności bez specjalnej konfiguracji, więc dostęp do usługi grailsowej to po prostu zadeklarowanie pola o odpowiednim typie bądź nazwie. Tworzymy usługę poleceniem grails create-service Batch, a następnie w klasie zadania def batchService (alternatywnie BatchService batchService). Spring Framework zajmie się resztą i zagwarantuje, że pole nie będzie niezainicjowane.
Usługa BatchService pobiera wszystkich użytkowników z niepustym polem email (Listing 11-4):
W poprzedniej relacji z rozdziału 10. "Reporting" (patrz Raporty w Grails - rozdział 10 z "Beginning Groovy and Grails") mieliśmy okazję poznać sposób na dotarcie do ziaren springowych za pomocą atrybutu sesyjnego GrailsApplicationAttributes.APPLICATION_CONTEXT. Tym razem autorzy zademonstrowali inny, alternatywny sposób - użycie interfejsu ApplicationContextAware. Interfejs dostarcza metodę void setApplicationContext(ApplicationContext applicationContext), która przekazuje kontekst springowy, który z kolei możemy wykorzystać do pobrania dowolnego ziarna springowego:
Prawie wszystkie aplikacje zawierają funkcjonalność, która musi być wykonywana o określonych porach lub co zadany interwał, którą nazywamy przetwarzaniem wsadowym (ang. batch processing).
W Grails obsługa przetwarzania wsadowego opiera się na otwartym projekcie Quartz, który dostarczany jest w ramach podstawy infrastrukturalnej Grails - Spring Framework. Quartz jest podobny do uniksowego crona, który uruchamia zadania w przyszłości, z tą różnicą, że może korzystać z komponentów aplikacyjnych udostępnianych w ramach serwera aplikacyjnego.
Pracę z Quartz w Grails rozpoczynamy jego instalacją poleceniem grails install-plugin quartz. Wtyczka dostarcza nowe polecenie grails create-job.
Zadanie (ang. job) jest aplikacją, którą chcemy wykonać o zadanej porze. Określamy co i kiedy ma być wykonywane.
Tworzymy zadanie poleceniem grails create-job <nazwa-zadania>. Powstanie klasa <NazwaZadania>Job w grails/job. Konwencją Grails jest, że polecenia create-* tworzą klasy o zadanej przez użytkownika nazwie dodając przyrostek odpowiadający poleceniu, np. create-job first tworzy klasę FirstJob. Domyślna klasa zbudowana jest z atrybutu timeout, który określa, co ile wykonywane będzie zadanie zdefiniowane przez domknięcie execute().
W rozdziale znajduje się przykład tworzenia funkcjonalności tworzenia i rozsyłania raportów w trybie wsadowym oparte na klasach i usługach stworzonych w rozdziałach wcześniejszych.
Klasa zadania może zawierać opcjonalne atrybuty name oraz group. Definiują one, odpowiednio, nazwę zadania oraz jego grupę.
Domyślnie zadanie związane jest z sesją Hibernate, więc pobieranie danych z bazy nie wymaga specjalnych czynności. Wyłączenie wiązania zadania z sesją Hibernate jest możliwe, jeśli ustawimy atrybut sessionRequired na false.
Mamy dwie możliwości definiowania pory wykonania zadania - atrybuty startDelay z timeout lub cronExpression. Atrybut startDelay (domyślnie 0) określa, kiedy wykonane zostanie zadanie, licząc od uruchomienia aplikacji. Atrybut timeout (domyślnie 60000 ms = 1 min) określa interwał (w milisekundach) między kolejnymi wykonaniami zadania. Atrybut cronExpression to możliwość wykorzystania własnej wiedzy uniksowej dotyczącej demona cron. Deklarujemy wykonanie zadanie w formacie crontab.
Może się zdarzyć, że wykonanie zadania nie zakończy się, a kolejne zostanie uruchomione. Kontrola równoległego wykonywania zadań jest możliwa przez logiczny atrybut concurrent (false/true).
Format cronExpression składa się z 6 pól oddzielonych białym znakiem (spacja/tabulacja). Poszczególne pola odpowiadają sekundom, minutom, godzinom, dniom, miesiącom, dniom tygodnia i opcjonalnie, w 7. polu, latom. Specjalne znaki to gwiazdka (*), znak zapytania (?), myślnik (-), przecinek (,) oraz ukośnik (/).
Zadanie ma dostęp do automatycznego wiązania zależności bez specjalnej konfiguracji, więc dostęp do usługi grailsowej to po prostu zadeklarowanie pola o odpowiednim typie bądź nazwie. Tworzymy usługę poleceniem grails create-service Batch, a następnie w klasie zadania def batchService (alternatywnie BatchService batchService). Spring Framework zajmie się resztą i zagwarantuje, że pole nie będzie niezainicjowane.
Usługa BatchService pobiera wszystkich użytkowników z niepustym polem email (Listing 11-4):
def users = User.withCriteria {
isNotNull('email')
}a następnie, wyłącznie jeśli users jest niepuste, pobiera listę zadań dla każdego z nich (Listing 11-4): users?.each { user ->
def inputCollection = Todo.findAllByOwner(user)
}Niesamowita "skromność" kodu w Grails! Przypomina mi to dawne konkursy w C, w którym zawodnicy tworzyli zaawansowane programy w formie jednolinijkowców i z bardzo wyrafinowanymi konstrukcjami. Trzeba było nie lada umysłu i doświadczenia, aby docenić "zalet" takiego programowania. W Grails to "przykrycie" funkcjonalności Hibernate oraz Spring Framework wraz z dynamizmem Groovy (chociażby przez "doklejenie" metod bazodanowych) nasuwa mi takie skojarzenia. Kod nie jest jednak tak zawiły, jak to miało miejsce w tych jednolinijkowcach w C.W poprzedniej relacji z rozdziału 10. "Reporting" (patrz Raporty w Grails - rozdział 10 z "Beginning Groovy and Grails") mieliśmy okazję poznać sposób na dotarcie do ziaren springowych za pomocą atrybutu sesyjnego GrailsApplicationAttributes.APPLICATION_CONTEXT. Tym razem autorzy zademonstrowali inny, alternatywny sposób - użycie interfejsu ApplicationContextAware. Interfejs dostarcza metodę void setApplicationContext(ApplicationContext applicationContext), która przekazuje kontekst springowy, który z kolei możemy wykorzystać do pobrania dowolnego ziarna springowego:
EMailProperties eMailProperties = applicationContext.getBean("eMailProperties")Tak też można, skoro Grails to "nakładka" na Spring Framework, a Groovy to "nakładka" na Javę. Nie zapomnieliśmy o tym, prawda?
Subskrybuj:
Posty (Atom)