31 maja 2009

Rozpoczynam lekturę "Programming Groovy: Dynamic Productivity for the Java Developer" Venkata Subramaniama

1 komentarzy
Zabrałem się za kolejną książkę z serii Groovy+Grails, tym razem dedykowaną wyłącznie językowi Groovy - "Programming Groovy: Dynamic Productivity for the Java Developer" Venkata Subramaniama z The Pragmatic Programmers. Po dwóch, wcześniejszych poświęconych Grails - The Definitive Guide to Grails, Second Edition oraz Beginning Groovy and Grails: From Novice to Professional - w których mogłem jedynie powierzchownie poznać możliwości Groovy i zmierzyć się z jego wyróżnikiem - domknięciami i metaprogramowaniem, mam możliwość skosztowania pełni jego smaku. I po pierwszej części książki - "Part I. Beginning Groovy" (130 stron) - nie mam złudzeń, że było warto. Książkę czyta się niezwykle lekko, a mnogość przykładów z towarzyszącymi im wynikami ich działania sprawia, że komputer nie jest zupełnie potrzebny. Nawet wcześniejsza pobieżna znajomość tematu nie przeszkadza. Byłem początkowo sceptyczny lekturze tej książki, bo autor wydał mi się zbyt egzotyczny, aby przedstawić temat w sposób chociaż porównywalny do tego, którym raczyli mnie przez ostatnie tygodnie panowie Graeme Rocher i Jeff Brown w "The Definitive Guide to Grails, Second Edition". Już po pierwszych stronach wiedziałem, jak bardzo się myliłem. A ile nowych słówek angielskich! Autorowi najwyraźniej sprawia dużo uciechy zabawa z językiem angielskim i robi to po mistrzosku. Potrzebujesz książki o Groovy i wielu dodatków rozszerzających wiedzę o samym programowaniu, nie tylko w Javie, sięgnij po tę pozycję. Akurat leje za oknem, więc zamiast siedzieć przed kompem czy telewizorem zabierz się za "Programming Groovy". Dobra zabawa murowana. Nawet dowcipy są takie właściwe i we właściwej ilości podane. I na koniec początku - książka przedstawia Groovy 1.5.4, więc na niektóre opisy należy wziąć poprawkę.

Książka zaczyna się wymownym cytatem o ciągłem zmianie i dostosowywaniu się do niej - "As moves the world, to move in tune with changing times and ways is wisdom". Takie nastrajające, co? A później peany na temat możliwości Groovy. Nie ma co liczyć na bezstronne spojrzenie na język Groovy - gość jest rozkochany w nim i to czuć od pierwszych kartek.

Języki dynamiczne charakteryzują się tym, że potrafią modyfikować program w trakcie działania, włączając w to strukturę obiektów, typów czy ich zachowanie. Jak to ujął autor - to co możemy w językach dynamicznych podczas uruchomienia, w językach statycznych możemy jedynie do czasu kompilacji. Wspomina się o Groovy i jego szkielecie referencyjnym Grails obok rozwiązań typu Ruby on Rails z Ruby, Django z Pythonem i Lift ze Scala (tak, o parze Lift i Scala pisze się coraz więcej, ale mnie kusi raczej do Clojure - języka funkcyjnego ala Lisp (i to zapewne tłumaczy ta mnogość wstawek w nawiasach)). Niedługo trzeba czekać, aby dotkąć kodu Groovy w książce i z początku będzie to raczej porównanie fragmentu w Javie z odpowiadającym mu funkcjonalnie fragmentowi w Groovy, aby ostatecznie poświęcić się wyłącznie cechom Groovy. Na 7. stronie pojawiają się dwa wiodące cechy Groovy - metaClass i domknięcie, które definiuje nową metodę. Autor nie zasypia gruszek w popiele.

Skrypty Groovy uruchamiamy za pomocą interaktywnego programu groovysh lub jego graficznego odpowiednika groovyConsole. Zapewne ostatecznie przyjdzie nam uruchamiać skrypty Groovy poleceniem groovy, bądź przez interpreter z poziomu Javy. W końcu jesteśmy na JVM! Jeśli wykonujemy skrypt poleceniem groovy to mamy cały kod poza klasą lub klasę z metodą static main(String[] args). Wspomina się o IDE i z nowym wydaniem Eclipse 3.5 postanowiłem sprawdzić Eclipse Groovy Plug-In (na stronie widnieje komentarz - Eclipse 3.5 : As of M7 the updateDev site appears to be functional), ale jak pisałem wczoraj w Wrażenia po instalacji Eclipse 3.5 (Galileo) RC1 i wtyczki Groovy Eclipse Plugin i później Tomek Nurkiewicz w komentarzu nie ma co liczyć na wyrafinowane wsparcie dla Groovy.

Rozdział 3. to prezentacja fragmentów kodu w Javie i Groovy oraz jego pułapek, które działają niekonwencjonalnie, tzn. działają tak, bo gdyby działały inaczej wciąż nie pozbyłyby się swej odmienności, np. użycie właściwości class na mapie. Zamiast mapa.class, która może wskazywać na klucz class albo próbę dostępu do właściwości class (przez metodę getClass()) zdecydowano postawić na to pierwsze - klucz o nazwie class. Groovy domyślnie importuje pakiety java.lang, java.util, java.io, java.net oraz java.math.BigDecimal, java.math.BigInteger z Javy i groovy.lang z groovy.util z Groovy.

Groovy rozszerza klasę java.lang.Object o metodę println (i kilka innych, o których później). Zamiast pisać metoda(param1, param2,...) można po prostu opuścić nawiasy i napisać metoda param1, param2,... W klasie java.lang.Integer znajdziemy nowe metody, a wśród nich - upto(), która pozwala na wykonanie pętli od-do, np. 0.upto(2) { print "$it " }. W tym przykładzie mamy do czynienia z kilkoma nowinkami Groovy - wspomniana metoda upto na typie Integer, przekazanie parametru do upto będącym domknięciem (mimo, że może wydawać się, że to jest ciało metody - to zabrało mi najwięcej czasu, aby zrozumieć) oraz ostatecznie wykorzystanie domyślnego parametru domknięcia it. Jeśli pętla będzie od 0 możemy wykorzystać metodę times, która jest upto od 0, np. 3.times { print "$it " }. Przeskok wartości w pętli to metoda step(doIlu, coIle), np. 0.step(10, 2) { print "$it " }. Metody i typy rozszerzające JDK nazywają się Groovy JDK (GDK). Pojawia się przykład ilustrujący uruchomienie procesu w Javie i jego odpowiednik-jednolinijkowiec w Groovy, tj. println "groovy -v".execute().text. Nie ma wątpliwości, co ma przyszłość (być leniwym zaczyna być zaletą :)). Wykonanie zmienna.własciwosc, to nic innego jak wykonanie metody getWlasciwosc().

Groovy udostępnia operator ?. - bezpieczny odczyt, który sprawdza, czy poprzedzająca wartość nie jest null i jeśli nie (tzn. nie jest null), wykonuje kolejne metody, np. str?.reverse().

W Javie musimy obsługiwać wyjątki kontrolowane (ang. checked exceptions), co często kończy się na pustym bloku catch (!) W Groovy nie, a nieobsłużone wyjątki są przekazywane wyżej, do wywołującego.

Reszta w kolejnej odsłonie, a jest tego jeszcze sporo, a że książkę czyta się lekko i przyjemnie, więc...wracam do lektury.

Przypominam, że w nadchodzący wtorek 2. czerwca 2009 z okazji wydania Eclipse 3.5 (Galileo) na MIMUWie (sala 5440, ul. Banacha 2, Warszawa) organizowana jest mini-konferencja Warszawski Eclipse DemoCamp Galileo 2009. Będzie 6 15-minutowych wystąpień związanych z Eclipse i okolic prezentowanych przez znawców tematu. Jeśli jesteś w pobliżu koniecznie zajrzyj. Już zarejestrowało się ponad 100 uczestników, więc i Ciebie nie powinno zabraknąć! Uprasza się o wcześniejszą rejestrację.

30 maja 2009

Wrażenia po instalacji Eclipse 3.5 (Galileo) RC1 i wtyczki Groovy Eclipse Plugin

1 komentarzy
Niedawno wyszła nowa wersja Eclipse 3.5 (Galileo) RC1 (zakładka Development Builds), więc postanowiłem popróbować się z nią i wtyczką Groovy Eclipse Plugin.

Na początku zaskoczyło mnie bardzo szybkie uruchomienie Eclipse (w porównaniu do wcześniejszych wersji, IntelliJ IDEA 8.1.2 i NetBeans 6.7). Myślałem, że to wynik "skrojenia" dostępnych wtyczek. I faktycznie, bardzo skromne About..., wręcz niezwykle skromne.


Pamiętam, że przejrzenie charakterystyki Eclipse przez menu About zawsze trwało. Tym razem trwa...niepokojąco krótko. Wciskam Installation Details i przechodzę po kolejnych zakładach bez żadnego oczekiwania.


Mylyn jest dostarczany domyślnie.


Ogólnie początkowe wrażenia bardzo pozytywne. Mam wrażenie, że chyba wrócę do Eclipse.

Pora na wtyczkę Groovy Eclipse Plugin. Już na początku zaskoczenie, tym razem nie tak przyjemne jak przy Eclipse. Instalacja wtyczki jest inna niż ta opisana na jej stronie domowej. Już samo początkowe menu do instalacji jest różne - Help -> Install New Software.... Definiuję repozytorium wtyczki (http://dist.codehaus.org/groovy/distributions/update/) w polu Work with i Add... Definiuję repozytorium i potwierdzam OK. Musiałem wyłączyć opcję Group items by category, aby pojawiły się składowe wtyczki.


Jest nawet rozszerzenie do Grails - Grails Eclipse Feature.


Wybieram wszystkie rozszerzenia i Next.


Musiałem wyłączyć Groovy TestNG Feature ze względu na brak rozszerzenia org.testng.eclipse, który blokował instalację.


Next i wtyczka gotowa do instalacji. Wszystko przygotowane.


Next i możemy podziwiać dodatki instalowane ekstra.


Zaznaczam "I accept the terms of the license agreements"


i wciskam przycisk Finish.


Idzie. Po chwili, którą spożytkowałem na czytanie forów, mam


Wciskam Yes i faktycznie po chwili Eclipse działa ponownie, rozszerzony o...przynajmniej nową ikonkę WTP w About :)


W Installation Details pojawią się jednak obie wtyczki Grails Eclipse Feature i GroovyFeature, więc chociaż Eclipse wie o ich istnieniu.


Pojawiły się również nowi asystenci - New Grails Project oraz Groovy Class i Groovy Unit Test.


Przejście Create a Groovy Project też obfituje w niespodzianki. Po pierwsze nie ma magicznego przycisku New Groovy Project. W zamian możemy stworzyć projekt javowy i przypisać do niego obsługę Groovy - Add Groovy Nature.


Okazuje się, że obsługiwana wersja Groovy to 1.5.7, co jest delikatnie ujmując trochę przestarzałe - obecnie mamy wersję 1.6.3.


Przeglądając repozytoria wtyczki okazuje się, że w tym rozwojowym - http://dist.codehaus.org/groovy/distributions/updateDev/ - jest wersja z 1.6.1, więc choć trochę bliższe ideałowi. Jest kategoria Groovy, więc nie trzeba wyłączać Group items by category, aby wybrać wtyczkę do instalacji.


Next i idzie dalej.


Po instalacji, restart i w projekcie pojawia się groovy-all-1.6.1.jar.


Znacznie lepiej (acz wciąż nie jest to Groovy 1.6.3). Wtyczka nieaktualna, strona również - i jak ona ma konkurować ze wsparciem oferowanym przez IntelliJ IDEA 8.1.2, albo jej ostatnią, rozwojową wersją 9.0 (Maia)? IDEA jest produktem komercyjnym, ale to żaden problem dla prelegentów JUGów, bo mają licencję bezpłatnie (!)

28 maja 2009

Warszawski Eclipse DemoCamp Galileo 2009 w nadchodzący wtorek

3 komentarzy
W ramach promocji najnowszego wydania Eclipse IDE 3.5 (Galileo) na całym świecie organizowane są spotkania osób zainteresowanych nowymi funkcjonalnościami oferowanymi przez znane zintegrowane środowisko programistyczne dla programistów wszelakiej maści językowej. Jest to doskonała okazja na poznanie możliwości Eclipse, wspieranych technologii (w końcu, nie samym programowaniem w "czystej" Javie człowiek żyje) oraz, a może przede wszystkim, osób z branży. Wszystko w miłej atmosferze, a w dodatku, zgodnie z opisem wydarzenia na stronie Eclipse DemoCamps Galileo 2009 - "You don't need to be a software developer to attend!".

Właśnie w takim stylu Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG) zaprasza na Warszawski Eclipse DemoCamp Galileo 2009, które odbędzie się 02.06.2009 (wtorek) w godzinach 18:00-20:00 w sali 5440 Wydziału Matematyki, Informatyki i Mechaniki Uniwersytetu Warszawskiego (MIMUW) przy ul. Banacha 2 w Warszawie.

Code-House - Wspieramy Open Source  

Spotkanie jest wspierane przez firmę Code-House oraz fundację Eclipse.org, pod patronatem Wydziału Matematyki, Informatyki i Mechaniki Uniwersytetu Warszawskiego (MIMUW).

Harmonogram obejmuje następujące prezentacje:

18:00-18:15 Spring IDE, czyli o wsparciu dla Springa wewnątrz IDE Łukasz "splatch" Dywicki
18:20-18:35 Wyślij swoją myszę na urlop, czyli o skrótach i szablonach w Eclipse Wojciech Erbetowski
18:40-18:55 Wtyczka do Eclipse w 5 ... no może 15 minut Mateusz Zięba
19:00-19:15 Rozszerzanie JDT dzięki Equinox Aspects i AJDT weaving service Michał "migi" Grzejszczak
19:20-19:35 Z Eclipsem w chmurach w 15 minut, czyli jak użyć GoogleApp Engine wraz z pluginem do Eclipse, aby uruchomić aplikację w 15 minut Łukasz Lenart
19:40-19:55 Oracle JRockit Mission Control, czyli demonstracja profilowania i diagnostyki aplikacji Java przy użyciu Eclipse Waldemar "waldi" Kot

Wystąpienia będą 15-minutowymi prezentacjami technicznymi o ciekawostkach związanych z Galileo i okolic. Nie zabraknie dobrej porcji wiedzy i...pizzy (zainteresowani uatrakcyjnieniem strawy uprasza się o kontakt z organizatorami - patrz strona spotkania).

Wstęp na spotkanie jest całkowicie wolny od jakichkolwiek zobowiązań. Uruchomiono rejestrację celem zagwarantowania wszystkim przybyłym strawy - reszta gwarantowana. Warto również potwierdzić rejestrację w skrzynce pocztowej, aby nie wpaść na "Ta lista zawiera adresy osób, które wypełniły formularz rejestracyjny, ale nie kliknęły w odsyłacz potwierdzający. Zwykle oznacza to, że dana osoba nie sprawdziła jeszcze poczty albo pomyliła się wpisując adres.".

24 maja 2009

Recenzja książki "The Definitive Guide to Grails, Second Edition"

11 komentarzy
Po intensywnych miesiącach lektury książki "The Definitive Guide to Grails, Second Edition" i jej relacji na moim blogu przyszła kolej na spisanie wrażeń w całości. W ten sposób udało mi się choć trochę podziękować autorom za niezwykle ciekawą książkę o Grails 1.1 (w trakcie powstawania książki Grails 1.1 był w wersji BETA, ale mimo to książka nie straciła na swojej aktualności z jego wydaniem finalnym). Spędziłem ten czas bardzo mile i jestem niezwykle szczęśliwy, że miałem przyjemność przeczytać tą książkę. Jest ona zdecydowanym liderem na mojej półce książek o technologiach Java. Dzięki niej poznałem wiele okolicznych projektów i jeśli poszukujesz arcydzieła na temat Grails, to DGG2 jest nim bez wątpienia. Polecam każdemu, komu potrzebna jest lektura o Grails, Spring, Hibernate i w ogóle o funkcjonalnościach, które powinny być nieobce javowym szkieletom webowym.

Kompletna recenzja w języku angielskim, zgodnie z wymogami wydawnictwa w programie "Recenzja za książkę", jest dostępna jako Book review: The Definitive Guide to Grails, Second Edition.

22 maja 2009

Automatyczna aktualizacja i konfiguracja IntelliJ IDEA - zdumiewające!

4 komentarzy
IntelliJ IDEA nie przestaje mnie zdumiewać. Kilka dni temu, podczas pracy z projektem Apache OpenEJB, IDEA stwierdziła, że ma za mało pamięci i proponuje jej zmianę.

Dzisiaj było jeszcze ciekawiej. Pojawiła się nowa wersja, więc IDEA grzecznie zapytała o aktualizację.

Nie było na co czekać i klepnąłem "Download Patch and Restart". Po chwili pojawiło się okienko dialogowe z pytaniem, czy na pewno przeprowadzić aktualizację


aby za chwilę upewnić się, czy chcę kontynuować, kiedy to IDEA wykryła zmienioną konfigurację (ta wcześniej związana z pamięcią).

Nie zastanawiałem się długo - poszło "Proceed". Po krótkiej chwili aktualizacja zakończyła się z ostrzeżeniem, że reszta w moich rękach.

Pozostało ponowne uruchomić IDEA i wszystko działało jak poprzednio. Znaczy się aktualizacja przebiegła pomyślnie, a ja i tak nie wiem, jakie nowe funkcjonalności mam dostępne, a że IDEA działa, więc jest wszystko w należytym porządku. To mi się podoba! Czekam na podobne funkcjonalności w innych IDEach.

20 maja 2009

48. spotkanie Warszawa JUG - "DWR wprowadzenie" z Filipem Matuszewskim

0 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG) zaprasza na 48. spotkanie, które odbędzie się 26.05.2009 (wtorek) o godzinie 18:00 w sali 5440 Wydziału MIMUW przy ul. Banacha 2 w Warszawie.

Temat prezentacji: DWR wprowadzenie
Prelegent: Filip Matuszewski

Podczas prezentacji Filip opowie o Direct Web Remoting (DWR), czyli bibliotece javowej, która umożliwia dynamiczne wywoływanie metod Javy (po stronie serwera) z JavaScriptu (z przeglądarki) wraz z właściwą serializacją przesyłanych obiektów.
Podczas prezentacji zobaczymy jak skonfigurować DWR jako serwlet oraz w kontekście Spring Framework, a także wtyczkę DWR do Grails. Zobaczymy również podstawowe funkcje JavaScript API oraz kilka przykładów, co możemy osiągnąć dzięki obiektom DWR. Prezentacja zostanie okraszona fragmentami kodu.

Filip Matuszewski jest studentem Wydziału Elektroniki Politechniki Warszawskiej. Od 3 lat pasjonuje się programowaniem. Miłośnik Javy, Spring Framework, Grails oraz dynamicznego wytwarzania aplikacji.

Planowany czas prezentacji to 1,5 godziny, po której planuje się 15-30-minutową dyskusję.

Wstęp wolny!

Zapraszam w imieniu prelegenta i grupy Warszawa JUG!

18 maja 2009

Z rozdziału 17. o Hibernate i istniejących konfiguracjach bazodanowych w Grails z DGG2

2 komentarzy
Dotychczasowe przedstawienie cech Grails w książce "The Definitive Guide to Grails, Second Edition" dotyczyło obsługi bazy danych, którą tworzono na potrzeby aplikacji, bez wcześniejszych ograniczeń nakładanych przez istniejącą architekturę. Taki stan autorzy określają jako "a green field application" (patrz sekcja dotycząca inżynierii programowania). Zero ograniczeń, cudo projekt. W rzeczywistości jednak możemy zapomnieć o takich projektach, bo one istnieją jak istnieje najwyższa wygrana w TOTKA, która będzie należała do Ciebie :)

W rozdziale 17. "Legacy Integration with Hibernate" autorzy przedstawiają możliwości, jakie udostępnia ORM DSL w Grails, którego zadaniem jest uproszczenie konfiguracji Hibernate, a tym samym współpracy z istniejącymi konfiguracjami baz danych. To jest sytuacja, gdzie nie wystarczy powiedzieć, że potrafimy korzystać z bazy danych w aplikacji grailsowej, ale potrzeba wykazać się wiedzą jak dopasować aplikację do już działającej bazy danych (potencjalnie z pewnymi danymi dostępnymi jedynie w trybie do odczytu).

Temat był już omawiany w dedykowanym ORM DSL rozdziale 10. "Grails ORM" z moimi relacjami w Z rozdziału 10. o Grails ORM (GORM) z DGG2 oraz Dokończenie rozdziału 10. o Grails ORM (GORM) z DGG2.

Konfiguracja odwzorowania klasy dziedzinowej na reprezentację relacyjną jest możliwa w statycznej zmiennej mapping, która przyjmuje na wejściu domknięcie. W niej definiujemy nazwę tabeli przez metodę table z pojedynczym argumentem określającym nazwę tabeli i poszczególnych kolumn z metodą, której nazwa odpowiada nazwie odwzorowywanemu atrybutowi klasy dziedzinowej, która akceptuje mapę, a w której z kolei parametr column wskazuje na nową nazwę kolumny (uff, można nabrać powietrza), np. (Listing 17-3):
 class Album {
String title
...
static mapping = {
table "RECORDS"
title column: "R_TITLE"
}
}
Jeśli nazwa klasy dziedzinowej lub atrybutu tworzy nazwę tabeli lub kolumny, która jest niedozwolona w SQL (jest słowem kluczowym SQL), wtedy odwzorowujemy ją za pomocą lewego (wstecznego) apostrofu, np.
 table "`order`"
Zmiana nazwy kolumny łączącej w odwzorowaniu jeden-do-jednego lub wiele-do-jednego jest identyczna do typowej zmiany nazwy kolumny, np. (Listing 17-4):
 class Album {
static belongsTo = [artist:Artist]
...
static mapping = {
// domyślnie ARTIST_ID
artist column: "R_CREATOR_ID"
}
}
Konfiguracja odwzorowania jeden-do-wielu wymaga najpierw decyzji, czy ma być jednokierunkowa (ang. unidirectional) czy dwukierunkowa (zwrotna, ang. bidirectional). Za pomocą joinTable zmieniamy nazwę i kolumny tabeli złączeniowej, np. (Listing 17-5):
 class Artist {
static hasMany = [albums:Album]
...
static mapping = {
albums joinTable:[name:'Artist_To_Records', key: 'Artist_Id', column: 'Record_Id']
}
}
Klucz key wskazuje na stronę wiodącą (jeden), a column na stronę docelową (wielu).

W przypadku dwukierunkowego odwzorowania jeden-do-wielu tablica złączeniowa nie jest wykorzystywana i opiera się na kluczu obcym.

Odwzorowanie wiele-do-wielu jest realizowane podobnie jak jednokierunkowe odwzorowanie jeden-do-wielu za pomocą tablicy złączeniowej - zmiana przez joinTable.

Hibernate wie jak odzworowywać wiele podstawowych typów javowych, np. java.lang.String staje się java.sql.Types.VARCHAR w SQL. Za pomocą parametru type można zmienić typ kolumny, np. (Listing 17-8):
 class Album {
...
String title
static mapping = {
title type: "text"
}
}
Typy Hibernate są wskazywane po nazwie i "text" odpowiada java.sql.Types.CLOB - patrz org.hibernate.Hibernate.

W książce autorzy przedstawiają odwzorowanie własnych typów w Grails ORM DSL na przykładzie pakietu JodaTime ze specjalizowanym typem org.joda.time.Duration (nie sądziłem, że jest on tak wyrafinowany, ale po zachwytach autorów nie mam złudzeń - "As an example, say you wanted to use the excellent JodaTime Java date and time API" - strona 525).

Zmiana konfiguracji odwzorowania typu kolumny może być dodatkowo określona przez parametr sqlType, np. (Listing 17-10):
 class Song {
...
org.joda.time.Duration duration
static mapping = {
duration type: org.joda.time.contrib.hibernate.PersistentDuration,
sqlType: "VARCHAR(120)"
}
}
Następnie pojawia się wystarczająco zaawansowany przykład stworzenia własnego typu w Hibernate i jego odwzorowanie w GORM DSL - MonetaryAmount. Wystarczająco zaawansowany, abym stwierdizł, że zdecydowanie za daleko zdryfowaliśmy od tematu głównego jakim jest Grails. Tutaj, fanatycy Hibernate znajdą coś dla siebie, czego mogliby nie znaleźć w innych książkach dedykowanych Hibernate. Interesujący sposób poznawania tajników Hibernate przez pryzmat Grails. Takie dwa w jednym :)

Domyślną strategią tworzenia identyfikatorów dla klas dziedzinowych w GORM jest poleganie na mechaniźmie właściwym dla bazy danych, np. dla MySQL GORM odpyta bazę danych ze wskazanej tabeli i jej kolumny id. Istnieje kilka mechanizmów tworzenia identyfikatorów w Hibernate, a tym samym i GORM DSL - increment, identity, sequence, hilo, seqhilo, uuid, guid, native, assigned, select, foreign oraz sequence-identity. Przypisanie wybranego to skorzystanie z parametru generator, np. (Listing 17-15):
 class Album {
...
static mapping = {
id generator: 'hilo', params:[table:'hi_value', column:'next_value', max_lo:100]
}
}
Znawcy Hibernate od razu zauważą podobieństwo mapy przekazywanej do parametru params z konfiguracją przez element param w hibernate'owym XMLu.

Możliwa jest konfiguracja identyfikatora złożonego składającego się z dwu lub więcej atrybutów odwzorowywanej klasy dziedzinowej przez parametr composite, np. (Listing 17-18):
 class Album implements Serializable {
String title
Artist artist
...
static mapping = {
id composite:["title", "artist"]
}
}
Identyfikator złożony wymaga, aby klasa realizowała interfejs java.io.Serializable. Odczyt egzemplarzy klasy dziedzinowej z identyfikatorem złożonym wymaga oczywiście podania wartości obu atrybutów, np.
 def a = Artist.findByName("Tool")
def album = Album.get(new Album(artist:a, title:"Lateralus"))
Grails ORM DSL znacznie upraszcza konfigurację odwzorowania klas dziedzinowych przez Hibernate, ale (strona 532) "this integration doesn't preclude you from using one of hibernate's other mapping strategies" (nie mogłem odmówić sobie przyjemności zacytowania zdania z "preclude" - tak rzadko się go spotyka :)).

Możliwe jest równoczesne wykorzystanie GORM DSL i typowej konfiguracji Hibernate do konfiguracji bazodanowej. Jeden nie wyklucza drugiego. Miejscem pliku hibernate.cfg.xml jest katalog grails-app/conf/hibernate. Kolejne 3 strony książki autorzy poświęcają przedstawieniu konfiguracji XMLowej w Hibernate dla hipotetycznej aplikacji GTunes, która tworzona jest przez całą książkę. Kolejny raz, gdzie miłośnicy Hibernate znajdą coś znajomego i (potencjalnie) ciekawego.

Kolejne strony rozdziału to przedstawienie tematu JPA w Grails i uruchomienia encji JPA, aczkolwiek (strona 535) "Grails doesn't support JPA directly (this support is still on the road map at the time of writing)". Wskazanie konfiguracji Grails opartej na adnotacjach wymaga konfiguracji w katalogu grails-app/conf (Listing 17-28):
 import org.codehaus.groovy.orm.hibernate.cfg.*
class DevelopmentDataSource {
def configClass = GrailsAnnotationConfiguration
...
}
Autorzy wskazują na ciekawy aspekt integracji JPA z Grails - encje JPA pisane są bezpośrednio w Javie, a mimo to "all of the dynamic finder and persistence methods work as if by magic" (strona 541). Za pomocą Groovy Meta Object Protocol (MOP), Grails rozszerza klasy o własne uproszczenia. W ten sposób możemy wykorzystać encje i konfigurację odzworowywań z istniejącej aplikacji bez konieczności jakichkolwiek zmian (!)

Na koniec autorzy przedstawiają temat mechanizmu kontroli poprawności atrybutów klas dziedzinowych przez statyczną zmienną constraints. Temat był przedstawiony w rozdziale 3. "Understanding Domain Classes" z moją relacją w Relacja z rozdziału 3. w "The Definitive Guide to Grails, Second Edition". I teraz najlepsze - związane ich z klasami javowymi (POJO) to stworzenie skryptu Groovy w tym samym pakiecie i katalogu (w ramach src/java), jak klasa, której dotyczy (!) Nazwa skryptu to złożenie nazwa klasy POJO zakończonego "Constraints", czyli dla pl.jaceklaskowski.encja.Pracownik byłby to skrypt o nazwie PracownikConstraints.groovy w katalogu src/java/pl/jaceklaskowski/encja. W ramach skryptu definiujemy wyłącznie pakiet i zmienną constraints, np. (Listing 17-30):
 package com.g2one.gtunes
constraints = {
number blank:false, maxSize:200
street blank:false, maxSize:250
...
}
Interesujące, nieprawdaż? Możemy pisać lub wykorzystać istniejące klasy dziedzinowe pisane w Javie bez żadnych zmian, a wciąż korzystać z zaawansowanych funkcjonalności Grails jak dynamiczne metody wyszukiwania, metody kryteriowe i rusztowanie. Właśnie mechanizm rusztowania jest niezwykle interesujący dla nieinwazyjnego wprowadzenia Grails do istniejących rozwiązań, jako chociażby interfejs administracyjny dla bazy danych pod kontrolą aplikacji pisanej bez udziału Grails. Cytując (strona 543): "The reality is that there are many cases where static typing is the better choice and conversely, there are many where dynamic typing is favorable". Nic dodać, nic ująć, tylko się zgodzić. Dla mnie bajka.

Tym samym doszliśmy do końca książki "The Definitive Guide to Grails, Second Edition", która jakkolwiek zawiera jeszcze dodatek opisujący język Groovy - Appendix "The Groovy Language", ale zapoznanie się z nim pozostawię zainteresowanym. Sam przechodzę do kolejnej książki "Programming Groovy: Dynamic Productivity for the Java Developer" Venkata Subramaniama z The Pragmatic Programmers, więc o Groovy będę miał dedykowane 284 stron.

15 maja 2009

Rozwiązywanie niezgodności binarnych z maven-shade-plugin

2 komentarzy
Moim ciągle niezrealizowanym zadaniem jest poznanie dwóch rozwiązań do zmiany bajtkodu (klas javowych w postaci binarnej) - asm i cglib. Pamiętam wystąpienie Piotra Kobzdy na ten temat podczas Javarsovii 2007, w którym chciałem uczestniczyć bardziej aktywniej niż to było mi dane - obowiązki organizatora i moja wrodzona natura gaduły dały się poznać. Skończyło się na krótkich urywkach wystąpienia Piotra i temat zamarł jako zbyt zaawansowany, a może po prostu z powodu niewielkiej wartości praktycznej - w końcu asm/cglib nie są tak często wykorzystywane wprost jak chociażby równie ciekawe rozwiązania typu Grails. Jest wiele podobnych tematów, których znajomość pomaga, ale nie będąc warunkiem koniecznym odkłada się je na półkę na bliżej nieokreśloną przyszłość. Możnaby mnożyć takich perełek bez liku, chociażby programowanie w języku funkcyjnym, albo nawet tak podstawowe jak wzorce projektowe. Znajomość innego myślenia pomaga w zrozumieniu problemów, w których nie mają zastosowania, ale przez swoją odmienność prowokują do bardziej wytężonego wysiłku umysłowego i wtedy, nieoczekiwanie otwierają się nieużywane dotąd obszary naszego umysłu. Przypomina mi to rozmowę z nowicjuszami, których często zbywa się sądząc, że mogą jedynie zająć czas, ale którzy, przez swoje nietypowe pytania dotykające podstaw, okazują się być idealnymi katalizatorami myślenia - jeśli tylko wytrwamy z ich niewiedzą możemy paradoksalnie uporządkować sobie swoją (nie)wiedzę. Paradoksalnie, Ci niewprawieni w boju, owi nowicjusze nie są jeszcze tak ograniczeni jak my - wiedza rozwija, ale jednocześnie nakłada na nas swoje ograniczenia.

Zaletą pracy przy projektach otwartych jest możliwość rozwiązywania problemów na długo wcześniej niż pojawią się we własnych projektach komercyjnych. Mamy możliwość doświadczenia innego sposobu myślenia i pojawiają się zaskakujące rozwiązania - zaskakujące swoją prostotą i odmiennością. To każdy lubi.

Powrót do mojej działalności w Apache OpenEJB zacząłem od czyszczenia mojego backlogu. Lista nie jest pokaźna, ale niezwykle leciwa. Jednym z zadań było rozwiązanie problemu niezgodności binarnej ASM między wersjami 1.5.3 a nowszymi, które wykorzystywane są przez OpenEJB i inne projekty, np. wszechobecny Hibernate, które mogłyby być użyte wspólnie z nim w ramach pojedynczej aplikacji, co nieuchronnie prowadzi do błędu:

java.lang.NoSuchMethodError: org.objectweb.asm.ClassReader.accept(Lorg/objectweb/asm/ClassVisitor;I)V

Jest to odprysk prac nad wsparciem dla @ApplicationException - Optional @ApplicationException inheritance, gdzie wymagana jest nowa wersja Apache XBean, która przychodzi z asm/cglib, więc w połączeniu ze wspomnianym Hibernate może narobić niezłego zamieszania. Jest kilka opcji rozwiązania i panowie ze SpringSource opisali trzy - ASM version incompatibilities, using Spring @Autowired with Hibernate. Jeśli Twój projekt jest oparty na Apache Maven możesz skorzystać z kolejnego rozwiazania opartego na wtyczce maven-shade-plugin, co opisałem w artykule Rozwiązywanie niezgodności binarnych z maven-shade-plugin. Znajdziesz w nim opis problemu i przedstawienie rozwiązania. Z wiadomych względów zdecydowanie polecam! :)

13 maja 2009

[WARNING] Using platform encoding... i project.build.sourceEncoding w Apache Maven 2.1.0

5 komentarzy
Migracja do nowej wersji Apache Maven 2.1.0 nie powinna nastręczać wielu problemów, ale nawet przy ich braku zaleca się przejrzenie komunikatów z budowania projektu. Z pewnością spotkamy się z nowym komunikatem na poziomie WARNING:

[WARNING] Using platform encoding (Cp1250 actually) to copy filtered resources, i.e. build is platform dependent!

Pojawia się on dwukrotnie w trakcie wykonania wtyczki maven-resources-plugin. Wystarczy jednak dodać do pom.xml następujący wycinek:
 <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
aby o temacie zapomnieć. Więcej szczegółów bezpośrednio u źródła w POM Element for Source File Encoding.

Dla zainteresowanych - stworzenie nowego projektu mavenowego to polecenie:
 $ mvn archetype:generate -B \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.0 \
-DgroupId=pl.jaceklaskowski -DartifactId=maven-encoding -Dversion=1.0
Teraz wystarczy zbudować projekt poleceniem mvn package (zamiast mvn install, który kopiuje artefakt projektowy do lokalnego repozytorium):
 $ mvn package
...
[INFO] [resources:resources]
[WARNING] Using platform encoding (Cp1250 actually) to copy filtered resources, i.e. build is platform dependent!
...
[INFO] [resources:testResources]
[WARNING] Using platform encoding (Cp1250 actually) to copy filtered resources, i.e. build is platform dependent!
...
[INFO] Building jar: c:\projs\sandbox\maven-encoding\target\maven-encoding-1.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
Po dodaniu project.build.sourceEncoding do pom.xml WARNING idzie w odstawkę. Od tej pory, dzienniki powinny być czyste.

11 maja 2009

Apache Maven: ${basedir} w pom.xml w projekcie wielomodułowym

3 komentarzy
To już nie pierwszy raz, kiedy testy jednostkowe w projekcie zarządzanym przez Apache Maven działają, kiedy są uruchomione z katalogu projektu, ale już nie, kiedy są uruchomione z katalogu projektu macierzystego. Za przykład możnaby wziąć projekt examples/webservices-ws-security z Apache OpenEJB, który wywołuje sun.security.tools.KeyTool - narzędzie, które jest narzędziem zewnętrznym w stosunku do mavena i dla którego ścieżki względne w pom.xml mają znaczenie. Jeśli więc umieścimy taki fragment w pom.xml:
 <property name="server.alias" value="serveralias"/>
<property name="server.keypass" value="serverPassword"/>
<property name="server.keystore" value="target/classes/META-INF/serverStore.jks"/>
<property name="server.storepass" value="keystorePass"/>
<property name="server.dname" value="'cn=serveralias'"/>

<java classname="sun.security.tools.KeyTool">
<arg line="-genkey" />
<arg line="-alias ${server.alias}" />
<arg line="-keypass ${server.keypass}" />
<arg line="-keystore ${server.keystore}" />
<arg line="-storepass ${server.storepass}" />
<arg line="-dname ${server.dname}" />
<arg line="-keyalg ${keyalg}" />
<permissions>
<grant class="java.security.AllPermission" />
</permissions>
</java>
to oczywiście zmienna server.keystore jest względna i czuła na miejsce uruchomienia poleceń mvn - w katalogu projektu wszystko jest cacy, ale już poza nim (chociażby w katalogu wyżej) pojawi się błąd braku wskazanego pliku (ścieżka wskaże nieistniejący plik, a nawet poszczególne katalogi)!

Szczęśliwie, rozwiązanie jest pod ręką - zmienna ${basedir}. Wystarczy poprzedzić ścieżki względne zmienną ${basedir}, aby uniezależnić je od miejsca wykonania poleceń w projekcie.

Ostatecznie zmiana dotyczy jedynie server.keystore z ${basedir}:
 <property name="server.keystore" value="${basedir}/target/classes/META-INF/serverStore.jks"/>
Poza tym, żadnych innych zmian.

Więcej o ${basedir} w dokumentacji Apache Maven - POM Reference::The BaseBuild Element Set oraz Maven Getting Started Guide (szukaj "basedir").

Wciąż pod wpływem Apache Maven, czy może powrót do korzeni, czyli Apache Ant z Apache Ivy? A może Apache Buildr? Zauważam coraz częściej potrzebę łączenia kilku narzędzi do zarządzania projektem, czyli Maven dobry, ale jest wciąż miejsce dla Ant, a nieśmiało zerkam w stronę Buildr.

10 maja 2009

Na kłopoty...Groovy!

5 komentarzy
Ostatnimi czasy zauważyłem u siebie pewien trend ku znacznemu wykorzystaniu Groovy do namierzania miejsc, które wymagają poprawy. Po prezentacji Apache OpenEJB podczas GeeCON 2009 postanowiłem ponownie wrócić do "deweloperki" przy nim i rozpocząłem boje z niedziałającymi testami jednostkowymi. Na moje (nie)szczęście na pierwszy ogień poszły przykłady związane z obsługą JAX-WS. Dwa przykłady w OpenEJB - webservices-security oraz webservices-ws-security kończyły się niejasnymi dla mnie komunikatami błędów. Jednym z nich był:
 -------------------------------------------------------------------------------
Test set: org.superbiz.calculator.CalculatorTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.703 sec <<< FAILURE!
testCalculatorViaWsInterface(org.superbiz.calculator.CalculatorTest) Time elapsed: 2.656 sec <<< ERROR!
javax.xml.ws.WebServiceException:
Could not find service named CalculatorWsPort in wsdl http://127.0.0.1:4204/CalculatorImpl?wsdl
at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:155)
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:143)
at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:55)
at javax.xml.ws.Service.<init>(Service.java:56)
at javax.xml.ws.Service.create(Service.java:680)
at org.superbiz.calculator.CalculatorTest.testCalculatorViaWsInterface(CalculatorTest.java:52)
...
Kompletnie nie miałem pojęcia, co z nim jest nie tak. Najpierw przyjrzałem się WSDL, ale nic nie mogłem namierzyć. Wszystko wydawało się w należytym porządku. Wpadłem na pomysł, aby zaprząc do pracy...Groovy. Tak na prawdę chciałem przygotować przykład, który wypisze mi wszystkie zdefiniowane usługi.
 jlaskowski@work /cygdrive/c/oss/openejb3/examples/webservice-security
$ groovysh
Groovy Shell (1.6.2, JVM: 1.6.0_13)
Type 'help' or '\h' for help.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
groovy:000> import javax.xml.ws.Service;
===> [import javax.xml.ws.Service;]
groovy:000> import javax.xml.namespace.QName;
===> [import javax.xml.ws.Service;, import javax.xml.namespace.QName;]
groovy:000> def calcService = Service.create(new URL("http://127.0.0.1:4204/CalculatorImpl?wsdl"), new QName("CalculatorWsService"));
ERROR javax.xml.ws.WebServiceException: CalculatorWsService is not a valid service.
Valid services are: {http://superbiz.org/wsdl}CalculatorWsService
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init> (WSServiceDelegate.java:192)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init> (WSServiceDelegate.java:159)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate (ProviderImpl.java:83)
at groovysh_evaluate.run (groovysh_evaluate:4)
...
groovy:000> exit
I jak widać, wystarczyło wykonać 3 instrukcje w Groovy, aby otrzymać komunikat, który powiedział mi wszystko - zamiast "CalculatorWsService" powinienem używać "{http://superbiz.org/wsdl}CalculatorWsService", a dokładniej, zamiast new QName("CalculatorWsService") powinno być new QName("http://superbiz.org/wsdl", "CalculatorWsService"), czyli jakimś cudem test nie uwzględniał przestrzeni nazewniczej "http://superbiz.org/wsdl".

Faktycznie jednak, rozwiązanie przyniosła mi całkowicie przypadkowa zmiana dostawcy JAX-WS z dosyć leciwego Apache CXF 2.0.9, który używany jest jeszcze przez OpenEJB na tego od Suna - trwają prace nad aktualizacją CXF w OpenEJB, więc następne komunikaty powinny być bardziej jasne (chyba, że w CXF nic się w tym obszarze nie zmieniło). Po zmianie wywołania z QName, testy zaczęły działać. Dokładnie tego oczekuję od dobrze dobranego narzędzia do zdiagnozowania problemu i Groovy spisał się wyśmienicie (aczkolwiek to faktycznie nie on, a zmiana dostawcy JAX-WS API, ale nie mogłem się oprzeć, aby nie pochwalić Groovy tym razem :)).

Skoro dotykam usług sieciowym pewnie powinienem użyć jakiegoś specjalizowanego narzędzia do przeglądania dostępnych usług w WSDL. Co mogłoby to być? Propozycje?

09 maja 2009

Wrażenia po moim "Making a breeze with Apache OpenEJB" na GeeCONie

3 komentarzy
The GeeCON 2009 conference was a great success. Congrats to the organizators for the awesome conference. Wystarczy tego angielskiego, co? Prezentacje po angielsku, ale za kulisami, w przerwach na GeeCON było zazwyczaj po polsku.

Zajechałem z moją żoną Agatą do Krakowa około południa i od razu wystartowaliśmy do Multikina. Nie, nie na film (chociaż przez moment przeszło nam to przez głowę), ale na konferencję GeeCON 2009 organizowaną przez Polish JUG, Poznań JUG i JUG z Czech we współpracy z GiK (być może kolejność powinna być inna, ale dla mnie ta wydaje się odpowiadać mojej rzeczywistości :)).

Pierwsze wrażenie przygniatające - jesteśmy w Multikinie, a tam...konferencja! Tego jeszcze nie było w Polsce. Do tej pory oglądając relacje z konferencji zagranicznych jedna rzecz, która przykuwała moją uwagę to były sale - duże, przestronne, z wygodnymi siedzeniami i wielki ekran, a prelegent gdzieś tam w dole. Po prostu marzenie. A tu proszę - GeeCON zrobił to! Tutaj pierwsze podziękowania dla organizatorów, którzy podnieśli poprzeczkę organizacji konferencji javowych w Polsce na kolejny poziom (w 2008 rozważaliśmy "umieszczenie" Javarsovii 2008 w Multikinie na Ursynowie, ale ceny były po prostu zaporowe - dla kina lepiej było puszczać reklamy przy pustej widowni niż udostępnić sale na organizację konferencji). Po rejestracji i rozmowie z Radkiem, Adrianem, Andrzejem "ags" (Polish JUG), Adamem (Poznań JUG) i kilkoma innymi (znamienitymi, ale teraz zapomniałem ich imion - wybaczcie!), przyszło moje 60 minut - Making EJB 3.1 development a breeze with Apache OpenEJB. Miałem niezłą tremę i za bardzo dbałem o doskonałość mojego angielskiego zamiast skoncentrować się przede wszystkim na temacie. Byłem tak spięty, że niejednokrotnie mnie dławiło i modliłem się w myślach, aby już było po wszystkim. Nie żartuję. Nie potrafię tego wytłumaczyć, ale już dawno nie czułem takiej tremy przed publicznym wystąpieniem i GeeCON przypomniał mi, że ona wciąż istnieje. Teraz znacznie bardziej rozumiem osoby, które niejednokrotnie mówiły mi, że wszystko jest proste, ale publiczne wystąpienia ich zabijają. Wiem teraz, co mówią i jako lekarstwo przepisałbym tylko jedno - publiczne wystąpienia. Nie raz, nie dwa, tłumaczyłem, że publika nie jest po to, aby wykończyć prowadzącego, ale żeby dowiedzieć się, czegoś co może przydać się. Uczestnicy poświęcają swój czas, więc ostatnią rzeczą, jaką można się po nich spodziewać, to wykończenie prelegenta. Słowa słowami, ale kiedy skończyłem moją prezentację głęboko odetchnąłem :) Na pewno nie szybko zapomnę tegorocznego GeeCONa.

Później było już spokojnie. Z żoną wystartowaliśmy na miasto, aby wieczorem wziąć udział w Beer Certification Path, czyli nocnej eskapady po krakowskich pubach - "Pod Jaszczurami", "Piwnica Pod Baranami", "Stary Port" i "Stajnia", która polegała na zbieraniu liter słowa JAVA i wypiciu w każdym pubie piwa całkowicie bezpłatnie! Najciekawiej było w "Starym Porcie", bo akurat w czwartki jest śpiewanie szant i w ten czwartek nie było inaczej. Klimat był nieziemski.

Plany na drugi dzień to Paweł Wrzeszcz z "Seam For Spring Developers" i Thomas Enebo "JRuby: Ruby on the JVM". Pojawił się jednak Grzegorz Duda i tyle było z mojego JRuby. Obgadaliśmy niejeden temat, ale mnie najbardziej interesowały plany podkastu Polish Java Podcast. Ostrzę sobie zęby na kolejny, w którym mógłbym pomóc Grzegorzowi i w ten sposób spróbować swoich sił jako autor podkastów. Kilka osób pytało o to i dałem się przekonać, że byłoby to ciekawym uzupełnieniem bloga. Dałem się nawet przekonać na Twittera, na którym możnaby chociażby "twicić" o przeczytanych artykułach z ich krótkimi recenzjami. To ma faktycznie jakiś sens. Zresztą zobaczymy. Grzegorz "twici" i zachwalał, więc nie ma co się opierać i samemu spróbować. Zainteresowani mogą mnie znaleźć pod adresem http://twitter.com/jaceklaskowski.

Wracając do konferencji, to z rzeczy niecałkiem dopieszczonych to z pewnością wyżywienie - obiad był do bani i tutaj widziałbym coś znacznie smaczniejszego oraz więcej aktywności między prelekcjami, które prowokowałyby do poznawania nowych osób - może grześkowe COOLuary? Jestem pełen podziwu dla wysiłku włożonego w przygotowanie GeeCONa i jestem dumny, że mogłem być nie tylko uczestnikiem konferencji, ale również jej prelegentem. Veni, vidi, vici :)

Jeśli nie byłeś/-aś na GeeCONie żałuj, ale przed Tobą kolejne wydarzenia - 2. czerwca Warszawski Eclipse DemoCamp w Warszawie oraz 4. lipca sztandarowa konferencja Warszawa JUG - Javarsovia 2009. Oba wydarzenia bezpłatne. Zapraszam!

Zainteresowanych moją prezentacją zapraszam tutaj.

05 maja 2009

47. spotkanie Warszawa JUG - "Java dla Pokolenia YouTube" z Antonim Jakubiakiem

0 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG) zaprasza na 47. spotkanie, które odbędzie się 12.05.2009 (wtorek) o godzinie 18:00 w sali 5440 Wydziału MIMUW przy ul. Banacha 2 w Warszawie.

Temat prezentacji: Java dla pokolenia YouTube
Prelegent: Antoni Jakubiak

Podczas prezentacji Antoni przedstawi nowe technologie związane z wideo w Internecie. Zobaczymy połączenie szkieletu aplikacyjnego Adobe Flex z serwerem multimediów Red5, poznamy protokoły komunikacyjne używane w Adobe Flash oraz dowiemy się o technologiach, które umożliwiają przetwarzanie wideo w czasie rzeczywistym, zarówno po stronie serwera jak i po stronie przeglądarki. Zobaczymy również jak przeglądarka radzi sobie z rozpoznawaniem twarzy oraz wykrywaniem wzorców w obrazie z kamery webowej.

Antoni Jakubiak jest absolwentem Politechniki Częstochowskiej. Od dziecka pasjonuje się programowaniem. Od 4 lat programuje w Javie. Obecnie, wspólnie ze Sławomirem Idziakiem, prowadzi projekt, którego celem jest społecznościowe tworzenie filmów z wykorzystaniem dobrodziejstw Internetu.

Planowany czas prezentacji to 1,5 godziny, po której planuje się 15-30-minutową dyskusję.

Wstęp bezpłatny!

Zapraszam w imieniu Antoniego i grupy Warszawa JUG!

03 maja 2009

Tylko 2 tygodnie na zgłoszenia do Javarsovii 2009

2 komentarzy
4. lipca 2009r. odbędzie się trzecia odsłona polskiej konferencji javowej Javarsovia 2009 organizowanej przez entuzjastów z grupy Warszawa JUG. Jeśli cena ma znaczenie, to warto podkreślić, że Javarsovia była i w tym roku również będzie całkowicie bezpłatna. Dzięki naszym, tegorocznym sponsorom: Google, Artegence, TouK, Code-House, NASK, pod patronatem Wydziału Matematyki, Informatyki i Mechaniki Uniwersytetu Warszawskiego (MIMUW) możemy zaproponować Wam wiele atrakcyjnych tematycznie wystąpień w doborowej obsadzie całkowicie bezpłatnie.

Klarują się sponsorzy, mamy miejsce w salach auli Wydziału Biologii, więc pozostaje jedynie dopiąć agendę, w której po prostu nie może zabraknąć Ciebie w roli prelegenta. "Prelegenta?!" - zapytasz. Uczestnikiem może być każdy, ale prelegentem tylko wybrani. Czym większa konkurencja, tym większa radość z możliwości wyboru. A jakie doświadczenie! Pozostało jeszcze tylko 2 tygodnie, aby zgłosić swój temat prelekcji na konferencję. Organizatorzy wciąż cierpliwie czekają zanim zamkną zbieranie propozycji i ogłoszą szczegółową agendę.

Jeśli chciał[a]byś wystąpić przed ogromną (sięgającą do 250 osób!), żądną wiedzy i nieprzewidywalną publiką Javarsovii z wybranym przez siebie tematem, wyślij jego krótki opis wraz z notką o sobie na adres c4p@javarsovia.pl. Fajnie móc wystąpić przed publiką, która wie, co w Javie piszczy. Opis może być po polsku lub angielsku. Nie zwlekaj!

p.s. W nadchodzący czwartek jest 2-dniowy GeeCON w Krakowie. Ja będę, moja żona i dzieciaki będą, więc i Ciebie nie może zabraknąć. Moja pierwsza obcojęzyczna konferencja w roli prelegenta on Polish soil. To już gwarantuje dużo dobrej zabawy :) Będzie ciekawie!

01 maja 2009

Z rozdziału 16. o integracji Spring z Grails z DGG2

0 komentarzy
W rozdziale 16. "Leveraging Spring" książki "The Definitive Guide to Grails, Second Edition" autorzy przedstawiają, czym jest Spring Framework i w jaki sposób Grails czerpie z jego możliwości. Cytując autorów:

"Spring is a huge framework in itself that provides wrappers and utility classes for pretty much every common problem found using Java technology."

Spring jest podstawą technologiczną dla Grails. Stąd też w Grails możemy korzystać z DI (ang. dependency injection), ale wyróżnikiem Grails jest jego przesłonięcie konfiguracji springowej w XML własnym DSLem zwanym Spring DSL.

Typowym użyciem Springa w aplikacji to utworzenie pliku konfiguracyjnego w XML (można również skorzystać z adnotacji) i skonstruować org.springframework.context.ApplicationContext. Ostatnio pisał o tym Piotr Kochański w Wstrzykiwanie zależności czyli Dependency Injection w 9 minut i 59 sekund. Część 4: wykorzystanie Spring-a.

Zamiast wszechogarniającego XMLa Grails udostępnia własny Spring DSL, co w połączeniu z konwencją ponad konfigurację znacząco upraszcza konfigurację Springa. Wystarczy zdefiniować właściwość def storeService w klasie kontrolera, usługi, znacznika czy klasy dziedzinowej, aby Grails automatycznie przekazał (wstrzelił) egzemplarz klasy usługi com.g2one.gtunes.StoreService.

Samodzielne wyszukiwanie ziaren springowych sprowadza się do implementacji org.springframework.context.ApplicationContextAware, co informuje Grails, aby przekazał (wstrzelił) obiekt typu ApplicationContext, np. (Listing 16-3):
 import org.springframework.context.*

class StoreController implements ApplicationContextAware {
ApplicationContext applicationContext


StoreService getStoreService() { applicationContext.getBean("storeService") }
...
}
Jeśli chcielibyśmy zejść na poziom konfiguracji Spring z XML możemy to zrobić z grails-app/conf/spring/resources.xml.

Konfiguracja Springa ze Grails Spring DSL jest możliwa z pomocą grails.spring.BeanBuilder. Grails wczytuje wszystkie skrypty Groovy w katalogu grails-app/conf/spring. Domyślnie jest tam skrypt resources.groovy, którego głównym elementem jest atrybut beans (odpowiada <beans>), któremu z kolei przypisujemy domknięcie. Zdefiniowanie ziarna springowego w Grails Spring DSL to wykonanie metody o nazwie odpowiadającej nazwie ziarna, której argumentem jest nazwa klasy. Kolejnym argumentem jest domknięcie Groovy z parametrem typu org.springframework.beans.factory.support.AbstractBeanDefinition, np. (Listing 16-5):
 myDataSource(org.apache.commons.dbcp.BasicDataSource) { bean ->
bean.destroyMethod = "close"
driverClassName = "org.hsqldb.jdbcDriver"
url = "jdbc:hsqldb:hsql://localhost:9001"
}
Poza atrybutem destroyMethod, który odpowiada atrybutowi destroy-method elementu <bean> w pliku XML, mamy autowire (true, byName, byType lub byConstructor), abstract, dependsOn, factoryBean, initMethod, parent i scope.

Jeśli ziarno nie posiada bezparametrowego konstruktora możemy je utworzyć podając typ i parametry wejściowe konstruktora, np. helloWorldString(String, "hello world!"). Możemy również przekazać listę parametrów wejściowych konstruktora po nazwie, np. theBeansAlbum(Album, title:"The Bends", genre:"Alternative).

Dowolne ziarno definiowane przez Grails możemy przesłonić przez stworzenie ziarna o tej samej nazwie w grails-app/conf/spring/resources.groovy lub w pliku XML. Grails definiuje ziarna: dataSource (typu javax.sql.DataSource), jspViewResolver (org.springframework.web.servlet.ViewResolver), localeResolver (org.springframework.web.servlet.LocaleResolver), messageSource (org.springframework.context.MessageSource), multipartResolver (org.springframework.web.multipart.MultipartResolver), sessionFactory (org.hibernate.SessionFactory) oraz transactionManager (org.springframework.transaction.PlatformTransactionManager).

Każda wtyczka może definiować własne ziarna w domknięciem doWithSpring, który oprogramowujemy ze składnią BeanBuilder.

Powiązania między ziarnami springowymi definiujemy przez przypisanie lub metody ref (dla ziaren jeszcze nie zdefiniowanych lub które są tworzone przez Grails), np. (Listing 16-8):
 mySessionFactory(org.springframework.orm.hibernate3.LocalSessionFactoryBean) {
dataSource = myDataSource
}
lub dataSource = ref("dataSource").

Wewnętrzne ziarna springowe definiujemy przez zanurzenie definicji ziarna ze Spring DSL w ramach definicji innego ziarna, np. (Listing 16-10):
 mySessionFactory(org.springframework.orm.hibernate3.LocalSessionFactoryBean) {
dataSource = { org.apache.commons.dbcp.BasicDataSource bd ->
...
}
}
Przypisanie zasięgu ziarnom to zdefiniowanie bean.scope w ramach jego domknięcia, np.
 frenchCalendar(calendarBean) { bean ->
bean.scope = "prototype"
}
Mamy do dyspozycji prototype, request, flash, flow, conversation, session oraz singleton.

Pamiętajmy, że konfiguracja Springa jest realizowana przez skrypty Groovy, więc mamy do dyspozycji cały arsenał możliwości Groovy do konfiguracji Grails, np. (Listing 16-13):
 def dataSources = [firstDataSource: 9001, secondDataSource: 9002]

dataSources.each { name, port ->
"$name"(org.apache.commons.dbcp.BasicDataSource) { bean ->
bean.destroyMethod = "close"
...
}
}
Przykład prezentuje wykorzystanie wykonanie metod jako parametrów tekstowych z Groovy.

Następnie autorzy prezentują użycie Spring DSL do zdefiniowania MDB i JMS z Apache ActiveMQ. Przykładowa konfiguracja to (Listing 16-15):
 jmsFactory(org.apache.activemq.ActiveMQConnectionFactory) {
brokerURL = "tcp://localhost:61616"
}

jmsTemplate(org.springframework.jms.core.JmsTemplate) {
connectionFactory = jmsFactory
}
Klasy dziedzinowe to również ziarna springowe, więc przy tej konfiguracji wystarczy zadeklarować właściwość transient jmsTemplate (transient, aby egzemplarz JmsTemplate nie został zserializowany).

Jako podsumowanie jak mocna, a wciąż niezauważalna jest integracja między Spring a Grails warto przywołać zdanie z zakończenia rozdziału (str. 516):

"Grails provides such a clean abstraction over Spring that often users of Grails simply don't know Spring is there."