30 grudnia 2010

Embeddable EJB 3.1 z GlassFish 3.1 i NetBeans IDE 7.0

1 komentarzy
Biorąc pod uwagę liczbę dni do końca roku, ten wpis będzie co najwyżej przedostatnim wpisem na moim blogu, a na pewno ostatnim dotykającym tematu Java EE 6, EJB 3.1 i in.

Korzystając z okazji, chciałbym życzyć Tobie wszystkiego dobrego w nowym roku 2011 i nakłaniam do jeszcze większej aktywności. Nie czekaj, aż powiedzą, ale mów, proponuj, bądź liderem w swojej społeczności. Dla poszukujących natchnienia polecam lekturę wpisu na blogu Damiana Nowaka - Apprenticeship – długa droga ku Software Craftsmanship. Nie wiem, czy to styl pisania Damiana, czy może sama książka, ale tylko takich wpisów życzę nam w nadchodzącym roku. Niech kasa pójdzie w zapomnienie - niech będzie jej tyle, aby nie stanowiła kwestii do rozwiązania - a czas spędzajmy na tworzeniu - nowego i użytecznego oprogramowania, społeczności przez chociażby dzielenie się wiedzą. Nie ważne jaki był (i jeszcze będzie przez kolejne 2 dni) rok 2010, ale ważne, ile możesz zrobić, aby 2011 był jeszcze lepszy. Zalatuje socjotechniką, ale dobre myślenie poprawia mój nastrój, więc może i Twój również, a to może przełożyć się na coś wyjątkowego.

W takim tonie przedkładam Tobie do oceny mój nowy artykuł Embeddable EJB 3.1 z GlassFish 3.1 i NetBeans IDE 7.0, w którym...

Rozdział 22. Embeddable Usage specyfikacji Enterprise JavaBeans (EJB) 3.1 opisuje nową cechę specyfikacji, która pozwala na uruchomienie kontenera EJB i zarządzanych przez niego komponentów EJB poza serwerem aplikacyjnym Java EE 6 - jedynie na poziomie środowiska Java SE. W ten sposób autorzy specyfikacji przewidują (a my programiści im wierzymy) uproszczenie procesu testowania, przetwarzania wsadowego (w którym użycie transakcji jest kluczowe) czy użycie EJB w samodzielnych aplikacjach desktopowych. Innymi słowy, mamy wszystko, co oferuje kontener EJB 3.1 bez konieczności uruchamiania pełnego serwera aplikacyjnego Java EE, którego sama konfiguracja uruchomieniowa mogła przyprawić o ból głowy.

Zainteresowanych lekturą nie zatrzymuję już i jeszcze tylko na odchodne dorzucę nieśmiało, aby komentować, pytać i kwestionować. Wszyscy zostaną *odpowiednio* potraktowani :-)

28 grudnia 2010

Google Guice z Clojure - niebagatelna rola IRC w moim rozwoju

3 komentarzy
Do moich poczynań z JRuby on Rails i komentarzy do wpisu Świąteczne próby z JRuby on Rails wrócę w kolejnym wpisie. Dzisiaj będzie o czymś troszkę innym.

Zdumiewające, jak wiele wiedzy można zdobyć stosując wciąż konwencjonalne sposoby nauki. IRC to narzędzie stare jak sam Internet i pamiętam, ile sprawiało mi przyjemności i satysfakcji, kiedy spędzałem godziny siedząc przed terminalem na uczelni klepiąc dyskusje na jakimś bliżej nieokreślonym kanale. Nie miało znaczenia, gdzie, z kim i o czym, byle można było odsiedzieć swoje przez terminalem. Człowiek nic nie robi i czas mu leci - wtedy to był boski stan.

Przez długi czas nie uważałem IRCa za poważne narzędzie. Kojarzyło mi się właśnie z tym błogim stanem nic-nie-robienia, bo w zasadzie w Sieci jeszcze niewiele można było wtedy robić. Kiedy przyłączyłem się do Apache OpenEJB moje postrzeganie IRCa nieznacznie przesunęło się w stronę większego użycia przy rozwiązywaniu problemów - łatwiej było dopytać o szczegóły działania tego czy innego ustrojstwa. Raczej z rzadka tam zaglądałem, bojąc się nieprzerwanych dyskusji, które fajnie było prowadzić, ale w podsumowaniu wyglądały mizernie.

Nie wiem dlaczego, ale postanowiłem uruchomić Google Guice z poziomu Clojure. Czasami takie pomysły są zarzewiem kolejnych, więc nie zastanawiając się długo, zabrałem się za temat.

Początek był trywialny. Chwila zastanowienia i...potrzebny jest Guice w CLASSPATH do Clojure REPL. Nie inaczej, kiedy klasa javowa chce wywołać inną - obie muszą (zwykle) siebie widzieć przez CLASSPATH. Uruchamiam Clojure 1.3.0-alpha4 z odpowiednimi bibliotekami Guice.
jacek:~
$ CLASSPATH=~/apps/guice/guice-3.0-rc1.jar:~/apps/guice/javax.inject.jar:~/apps/guice/aopalliance.jar clj -13
CLOJURE_DIR:  /Users/jacek/apps/clojure
CLOJURE_CONTRIB_JAR:  /Users/jacek/apps/clojure-contrib-1.3.0-alpha3.jar
Clojure 1.3.0-alpha4
user=>
Pierwsza biblioteka oczywista, a dwie pozostałe wyszły "w praniu", kiedy kolejno uruchamiałem potrzebne elementy Guice.

Skracając znacznie moją historię, dotarłem do momentu, w którym miałem następujący stan:
user=> (import '(com.google.inject Guice AbstractModule))
com.google.inject.AbstractModule
user=> (def module (proxy [AbstractModule] [] (configure [] (println "configure called"))))
#'user/module
user=> (Guice/createInjector module)
IllegalArgumentException No matching method found: createInjector  clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:77)
I tu mała zagwozdka. W javadoc dla com.google.inject.Guice jest metoda createInjector, która powinna akceptować mój moduł. Zresztą niejedna.

I tak stan dumania, co by tu począć, trwał cały dzień. W zasadzie trochę dłużej, bo już wczoraj odnotowałem sobie, gdzie stanąłem i zabrałem się za dalsze dumanie z samego rana.

Wieczorem miałem dosyć. Postanowiłem napisać na grupę użytkowników clojure i iść spać. I już miałem pisać, kiedy przypomniałem sobie o kanale #clojure. I to był strzał w dziesiątkę!
[11:22pm] jlaskowski: hi
[11:23pm] jlaskowski: I'm having troubles with java.lang.IllegalArgumentException: No matching method found: createInjector
[11:23pm] jlaskowski: CLASSPATH=`pwd`/guice/guice-3.0-rc1.jar:`pwd`/guice/javax.inject.jar:`pwd`/guice/aopalliance.jar clj -13
[11:23pm] jlaskowski: CLOJURE_DIR:  /Users/jacek/apps/clojure
[11:23pm] jlaskowski: CLOJURE_CONTRIB_JAR:  /Users/jacek/apps/clojure-contrib-1.3.0-alpha3.jar
[11:23pm] jlaskowski: Clojure 1.3.0-alpha4
[11:23pm] jlaskowski: (def mm (proxy [AbstractModule] [] (configure [] (println "configure called"))))
[11:23pm] jlaskowski: (bean mm)
[11:24pm] jlaskowski: {:class user.proxy$com.google.inject.AbstractModule$0}
[11:24pm] jlaskowski: and when I call (Guice/createInjector mm)
[11:24pm] jlaskowski: it spits out the exception
[11:24pm] jlaskowski: http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/AbstractModule.html
[11:25pm] jlaskowski: how can I find out what is wrong exactly?
[11:25pm] jlaskowski: how do I find out what Clojure can call upon a class?
[11:26pm] jlaskowski: any helpful reflection methods to use?
[11:26pm] amalloy: jlaskowski: createInjector takes an array of Modules, not a single module
[11:27pm] amalloy: java's Foo.bar(Whatever...) is sugar for arrays
[11:27pm] jlaskowski: right
[11:27pm] jlaskowski: but have a look at the full stack trace
[11:27pm] jlaskowski: user=> (.printStackTrace *e)
[11:27pm] jlaskowski: java.lang.IllegalArgumentException: No matching method found: createInjector
[11:27pm] jlaskowski: at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:77)
[11:27pm] jlaskowski: at clojure.lang.Reflector.invokeStaticMethod(Reflector.java:202)
[11:27pm] jlaskowski: at user$eval17.invoke(NO_SOURCE_FILE:4)
[11:27pm] jlaskowski: at clojure.lang.Compiler.eval(Compiler.java:6201)
[11:27pm] jlaskowski: at clojure.lang.Compiler.eval(Compiler.java:6168)
[11:27pm] jlaskowski: at clojure.core$eval.invoke(core.clj:2680)
[11:27pm] jlaskowski: at clojure.main$repl$read_eval_print__5619.invoke(main.clj:179)
[11:27pm] jlaskowski: at clojure.main$repl$fn__5624.invoke(main.clj:200)
[11:27pm] jlaskowski: at clojure.main$repl.doInvoke(main.clj:200)
[11:27pm] jlaskowski: at clojure.lang.RestFn.invoke(RestFn.java:422)
[11:27pm] jlaskowski: at clojure.main$repl_opt.invoke(main.clj:266)
[11:27pm] jlaskowski: at clojure.main$main.doInvoke(main.clj:361)
[11:27pm] jlaskowski: at clojure.lang.RestFn.invoke(RestFn.java:437)
[11:27pm] jlaskowski: at clojure.lang.Var.invoke(Var.java:409)
[11:27pm] jlaskowski: at clojure.lang.AFn.applyToHelper(AFn.java:169)
[11:27pm] jlaskowski: at clojure.lang.Var.applyTo(Var.java:518)
[11:27pm] jlaskowski: at clojure.main.main(main.java:37)
[11:27pm] amalloy: augh do not do that
[11:27pm] amalloy: http://gist.github.com
[11:28pm] jlaskowski: amalloy: ok, will use it
[11:29pm] amalloy: anyway, yes. it can't find a method with that name whose parameters are (Foo), only one whose parameters are (Foo[])
[11:29pm] jlaskowski: you're right!
[11:29pm] jlaskowski: so how can I call a method that accepts an array?
[11:29pm] amalloy: you can find this out for yourself with clojure.contrib.repl-utils/show
[11:30pm] amalloy: jlaskowski: ##(doc into-array) is one way; in this case it looks like Guice will also accept an Iterable, so you can just pass it a clojure vector
[11:30pm] sexpbot: ⟹ "([aseq] [type aseq]); Returns an array with components set to the values in aseq. The array's component type is type if provided, or the type of the first value in aseq if present, or Object. All values in aseq must be compatible with the component type. Class objec... http://gist.github.com/756642
[11:31pm] jlaskowski: HURRAYY - you saved my day, amalloy
[11:31pm] jlaskowski: it works fine now
[11:32pm] Luyt_: Freenode's channels are a great resource, because of all the friendly and knowledgeable people on it!
[11:32pm] jlaskowski: it's awesome how quickly it's sorted out!
[11:32pm] Luyt_: ...and some communities are really great.
[11:32pm] lancepantz: we just have a great community 
[11:32pm] jlaskowski: it's not the first time I just enter the channel
[11:33pm] jlaskowski: and get an answer in secs
[11:33pm] jlaskowski: unbelievable
[11:33pm] jlaskowski: thanks again
[11:34pm] Luyt_: as long as you don't become a Help Vampire (http://slash7.com/2006/12/22/vampires/) it's allright 
[11:35pm] Luyt_: and you can always give back to the community, of course. Like lurking and answering questions from noobs, which are too tedious for the advanced clojurists in here. (Same works in #python)
I to było dokładnie to, czego potrzebowałem! Niecały kwadrans i odpowiedź już jest. W zasadzie odpowiedź była minutę po tym, kiedy skończyłem pisać - użyć tablicy zamiast po prostu przekazywać moduł. Ech, człowiek ślepnie na starość.

Wystarczy użyć operatora tablicowego i Guice będzie kontent.
user=> (Guice/createInjector [module])
configure called
#<InjectorImpl Injector[bindings=[ProviderInstanceBinding[key=Key[type=com.google.inject.Injector, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Injector>], ProviderInstanceBinding[key=Key[type=java.util.logging.Logger, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Logger>], InstanceBinding[key=Key[type=com.google.inject.Stage, annotation=[none]], source=[unknown source], instance=DEVELOPMENT]]]>
Tylko, po co mi to było?! :)

23 grudnia 2010

Kolorowanie map z Clojure i Danielem Janusem - prezentacja-cudo

0 komentarzy
Ostatnie, 74. spotkanie Warszawa JUG zaczęło się z prawie 30-minutowym poślizgiem. Około 17:00 zaczął w Warszawie padać intensywny śnieg i zdecydowałem się na dojazd metrem, aby później przez Pola Mokotowskie dotrzeć do MIMUWu. Warto było, bo to, co działo się na ulicach, wołało o pomstę do nieba - wszystko stało, a to, co jechało, to w zasadzie wlekło się. Daniel zdecydował się na dojazd tramwajem i, ku jego zaskoczeniu, z nimi też nie było lepiej. W końcu prezentacja rozpoczęła się. Słuchaczy było 7 plus nasz prelegent.

Prezentację nagrałem i plik z nagraniem jest już gotów do wystawienia. Niestety nie zdążyłem go opublikować przed wyjazdem i zrobię to w nadchodzącym tygodniu. Widziałem, że Poznań JUG wystawił kilka prezentacji na blip.tv i pomyślałem, że może tam trafią i nasze. Usiądę nad tym w przyszłym tygodniu - teraz pora na święta i prezenty. Jeśli znalazłby się ktoś, kto zechciałby mi pomóc w temacie nagrań, ich obsługi i zarządzania ich publikacją, koniecznie niech się ze mną skontaktuje. Pomoc zawsze mile widziana.

Co można było zobaczyć na prezentacji? Było wprowdzenie do Clojure - slajdy poprzeplatane przykładami w REPL, praktycznie, aby ostatecznie całość wiedzy wykorzystać do stworzenia aplikacji webowej z wyświetlanym plikiem SVG z mapą Europy. Daniel pokazał Emacs z SLIME (upewnił mnie, że to nie jest narzędzie dla mnie i nie mam złudzeń, aby tego zestawu NIE dotykać), następnie wczytywanie i zapis plików XML, którego reprezentantem był właśnie SVG i na koniec Ring (nakładka funkcyjna na javowe Servlety w Clojure). Prezentacja-cudo. Interaktywnie zaprezentowany kawał dobrej wiedzy praktycznej i sam przykład przykuwał uwagę - pojawiające się i znikające kolory państw były dla mnie niezwykle interesujące. To jest ten rodzaj prezentacji, gdzie przy tworzeniu aplikacji poznajemy nowe rozwiązanie - tym razem język programowania funkcyjnego Clojure. Brakuje mi takich prezentacji, w których poznawanie nowego jest obok tworzenia interesującej wizualnie aplikacji (niekoniecznie funkcjonalnie, ale jeśli również, to tym lepiej).

Pamiętam podobny przykład z OSGi, w którym aplikacja okienkowa była rozbudowywana przy włączaniu/wyłączaniu kolejnych pakunków. Uważam, że dopasowana aplikacja demonstracyjna podczas prezentacji jest jej kluczowym elementem. Podczas mojego wykładu na PWSZ w Tarnowie udało mi się pokazać coś podobnego - tworzyłem aplikację okienkową w Clojure REPL i nie mogłem uwierzyć, jak wielkie zrobiło to wrażenie. Pamiętam, jaki zadowolony byłem, kiedy wpadłem na ten pomysł i nie inaczej było ze słuchaczami. Ciągle sobie obiecuję, żeby to nagrać, ale jakoś tak schodzi na innych aktywnościach. Brakuje jeszcze umiejętności tworzenia slajdów. Mimo, że zwykle uważa się je za niekonieczne przy prezentacjach technicznych, to ja uważam, że posiadanie ich może znacznie poprawić zrozumienie tematu. Wierzę, że kiedyś i mi się uda nabrać takiego doświadczenia, aby tworzyć przykuwające oko slajdy i dopasować do nich aplikację demonstracyjną. To jest ten moment, w którym życzenia nabierają szczególnej mocy :]

W przyszłym roku będzie kilka okazji, aby popróbować się z tematem - trwają rozmowy z uczelnią krakowską o moim wykładzie w marcu, będzie konferencja 33rd degree w Krakowie i już wiem, że pojawię się również na infoshare.pl w Gdańsku. Pojawił się również pomysł konferencji w Toruniu na UMK w Wydziale MiI w pierwszym kwartale 2011 (zgoda władz wydziału już jest, więc potrzeba jedynie zestawić agendę, czym zajmę się na początku 2011). Chciałbym również odcisnąć swoje piętno (w pozytywnym tego słowa znaczeniu) na jvarsovii 2011.

Tym samym zakończyliśmy spotkania WJUGa w roku 2010. Zapraszam na kolejne w 2011. Pierwsze spotkanie już 11.01.2011, w którym Maciek Próchniak przedstawi Activiti – BPMN 2.0 nadchodzi. Ten temat bardzo mnie interesuje służbowo - wiele czasu spędzam z rozwiązaniem konkurencyjnym - IBM WebSphere Process Server czy IBM WebSphere Business Modeler i ciekaw jestem, co oferuje Activiti. Mógłbym poznać na własną rękę, ale poczekam na prezentację. Będzie nagrywane.

Korzystając z okazji, chciałbym złożyć serdeczne życzenia świąteczne, dużo prezentów i pomysłów na nowe aplikacje z jeszcze bardziej nowatorskimi technologiami, np. Clojure. Nie zapomij o przesłaniu mi ich na priv :-)

20 grudnia 2010

EJB 3.1 z OpenEJB 3.1 i NetBeans IDE 7.0

3 komentarzy
Jest wiele sposobów na naukę nowych technologii i dobór odpowiednich narzędzi może znacząco usprawnić ten proces. W przypadku EJB 3.1 możemy skorzystać z projektu Apache OpenEJB 3.1, podpierając się NetBeans IDE 7.0 jako zintegrowanym środowiskiem programistycznym z asystentami tworzenia ziaren EJB z Apache Maven w tle.

Zastosowanie EJB 3.1 jest zwykle podyktowane względami praktycznymi, kiedy wybór serwera aplikacyjnego Java EE 6 mamy już za sobą i pozostaje wykorzystać jego usługi. Ich kompletność i gotowość do użycia najlepiej doświadczyć, kiedy konieczne jest wykorzystanie transakcji, podłączenia do bazy danych z możliwością przypisania komu i co wolno, udostępnić Web Service z wykorzystaniem REST w ramach aplikacji webowej czy podobne "deklaratywne czynności". Nie ma konieczności zestawiania gotowej konfiguracji usług, a konwencja ponad konfigurację znacznie przyspiesza dostarczanie kompletnych rozwiązań. Przenośność aplikacji jest również istotnym aspektem wyboru stosu technologicznego. Dodając do tego łatwość testowania aplikacji korporacyjnych i Java EE 6 (JEE6) wydaje się być idealną platformą aplikacyjną.

W tym artykule przedstawię uruchomienie bezinterfejsowego, niestanowego ziarna sesyjnego EJB (ang. no-interface stateless session bean) z użyciem projektu Apache OpenEJB 3.1.4, który stworzę w NetBeans IDE 7.0 (wersja rozwojowa z dnia 15.12.2010). Celem jest maksymalne zminimalizowanie czasu koniecznego do uruchomienia środowiska. Kolejną zaletą zastosowania OpenEJB jest możliwość wykonanywania wszystkich operacji projektowych (budowanie i testowanie) poza IDE, dzięki użyciu Apache Maven wspieranym przez NetBeans IDE 7 "z pudełka".

Więcej w artykule EJB 3.1 z OpenEJB 3.1 i NetBeans IDE 7.0.

18 grudnia 2010

Book review: WebSphere Application Server for Developers V7

0 komentarzy
Właśnie ukończyłem lekturę książki, a właściwie publikacji, jak to zwykle nazywa się IBM Redbooks - WebSphere Application Server for Developers V7. Publikacja jest całkowicie bezpłatna w formie elektronicznej i, jak to ująłem w recenzji, niestaty nie zasługuje na swój tytuł. Jest aż nadto skoncentrowana, aby wprowadzić czytelnika w aspekt administracji WASv7 niż na przedstawieniu Java EE 5 i niewiele można znaleźć informacji nt. czego oczekuje się od programisty, który ma wdrożyć taką aplikację na WAS7. Nie powiem, żeby było mało, ale zdecydowanie za mało, jak na książkę z takim tytułem. Dodatkowo, rozdział dotyczący EJB3 oraz JPA jest wręcz nie-JEE5.

Dla mnie osobiście było to swego rodzaju podsumowanie wiedzy nt. okiełznania WAS7, aby nie sprawiał problemów, kiedy przyjdzie mi wdrażać aplikacje korporacyjne. Nie całkiem niskopoziomowo, ot akurat, aby panować nad sytuacją. Książkę czyta się niezwykle szybko i wiedza sama wchodzi do głowy, zakładając, że WAS7 jest tym materiałem, który w głowie czytającego powinna się w ogóle znaleźć. Osąd pozostawiam Tobie.

Pełną recenzję w języku angielskim można przeczytać na moim Wiki w Book review: WebSphere Application Server for Developers V7.

15 grudnia 2010

74. spotkanie Warszawa JUG - Daniel Janus z "Jak Clojure koloruje mapy"

2 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG)Warszawska Grupa Użytkowników Javy (Warszawa JUG) zaprasza na 74. spotkanie, które odbędzie się w najbliższy wtorek, 21. grudnia o godzinie 18:00 w sali 5440 Wydziału MIM UW przy ul. Banacha 2 w Warszawie.

Temat: Jak Clojure koloruje mapy
Prelegent: Daniel Janus

Podczas prezentacji Daniel opowie o:

- co powstaje po przemieszaniu liter w słowie Clojure i co z tego wynika
- dlaczego programowanie w Clojure przypomina operowanie na żywym organizmie
- jak na różne sposoby pokolorować mapę Europy za pomocą Clojure
- jak skonstruować do tego interfejs webowy
- jak dorobić obsługę arkuszy kalkulacyjnych
- jak zbudować łatwo instalowalną aplikację w postaci jednego pliku .jar

A wszystko to podczas prezentacji przeplatanej z tworzeniem kodu "na żywo". Nie zakłada się żadnej znajomości Clojure -- objaśnienia kolejnych cech języka pojawi się w miarę jak będą potrzebne, bez wgłębiania się w szczegóły.

Daniel Janus zajmuje się językami funkcyjnymi od dziesięciu lat, programuje w językach z rodziny Lisp od czterech lat, a od ponad roku współtworzy firmę Fablo, w której Clojure jest główną używaną technologią. Na swoim blogu pisze m.in. o Clojure po polsku.

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

Wstęp wolny

Zapraszam w imieniu prelegenta i grupy Warszawa JUG!

14 grudnia 2010

33rd degree i ja z "EJB 3.1 vs Contexts and Dependency Injection (CDI) and Dependency Injection for Java in Java EE 6"

5 komentarzy
Skoro większość z Was wskazuje na Java EE 6 jako temat przewodni grudnia, to może niech i tak zostanie w nadchodzącym roku 2011. Ot, taka mała zapowiedź dalszych poczynań w blogosferze oraz konferencyjnie.

W mojej skrzynce pocztowej znalazłem wiadomość o nadchodzącej konferencji 33rd degree. Niewiele o niej wiadomo, bo temat bardzo, bardzo świeży. Mógłbym założyć, że na tyle, że jestem pierwszym, który pisze o tym na blogu (poza zapowiedzią u samych organizatorów - Wymarzona konferencja nadchodzi).

Piszę o tym, gdyż jest to kolejna konfencja javowa w Polsce, obok JDD, NYAC, GeeCON, Javarsovia, warsjawa, java4people czy 4Developers. Mimo, że wiele z nich cieszy się renomą, widać, że wciąż jest miejsce dla kolejnej. Do grona "uczestników" sceny konferencyjnej dołącza 33rd degree. Jak na tak niewielki kraj, możemy powiedzieć, że tyle u nas konferencji co partii politycznych (!) Może kiedyś dojdzie do jakiś fuzji konferencyjnych?! Tak czy owak, będzie wiele okazji, aby się spotkać i wymienić doświadczeniami. Będę miał w tym swój wkład!

Należy dodać, że markę 33rd degree chce się zbudować na "Top quality speakers that usually talks at big conferences and were chosen many times as Rock Stars" oraz "All speakers were invited personally and validated in practice. No surprises expected. Only great talks." (za stroną domową konferencji).

I teraz o moim wkładzie, a raczej wykładzie. Tak, tak, będę miał swoje 60 minut na przedstawienie tematu EJB 3.1 vs Contexts and Dependency Injection (CDI) and Dependency Injection for Java in Java EE 6. Na razie mam jedynie szkic, co chciałbym przekazać słuchaczom i w jaki sposób, aby dotrzymać kroku innym wystąpieniom, gdzie slajdy należy potraktować za...relikt przeszłości i eksponat muzealny. Sprawa się będzie klarowała w kolejnych miesiącach.

Pora na rozlosowanie specjalnych kodów promocyjnych. Mam ich 10 (i nie zawaham się ich użyć pro publico bono). Niech jednak będzie to transakcja wiązana (bodaj jedyna legalna forma obdarowywania bezkosztowo w PL), gdzie ja Tobie, a Ty mi i jesteśmy kwita. Proszę o wyrażenie swojej opinii nt. połączenia wystąpienia z wcześniej przygotowanymi nagraniami (coś ala skrinkasty) i lokalnym repozytorium wersji kodów źródłowych, aby zamiast klepania (rękoma i ustami) interakcja między prelegentem a uczestnikami przebiegała znacznie szybciej i bez ryzyka utraty tempa czy toku rozumowania. Rola prelegenta sprowadziłaby się do zaprezentowania nagrań i uzupełniania ich słowno-muzycznie. Czy to ma rację bytu? Wsród osób, które wyrażą swój głos w komentarzu do tego wpisu rozlosuję po jednym specjalnym kodzie promocyjnym na konferencję 33rd degree.

09 grudnia 2010

Temat przewodni na grudzień - Java EE 6

3 komentarzy
Ankieta określająca temat przewodni na miesiąc grudzień 2010 dobiegła końca z 85 głosami, w których specyfikacja Java EE 6 zdobyła najwięcej głosów, nieznacznie więcej niż EJB 3.1 i JSF 2.0. Bardzo zdumiewające dla mnie było wskazanie na OSGi jako bardziej interesującego niż CDI. A może nie jest to wskazanie na bardziej interesującą technologię, ale na mniej rozpoznaną?!
Wyniki ankiety tematu przewodniego grudnia 2010
Tym samym rozpoczynam analizę JEE6, w której głównymi graczami będą - dokument standaryzacyjny JSR 316: Java Platform, Enterprise Edition 6 (Java EE 6), serwery aplikacyjne: GlassFish 3.1, Apache Geronimo 3.0, IBM WebSphere Application Server V8 ze zintegrowanymi środowiskami programistycznymi NetBeans IDE 7.0 i IBM Rational Application Developer V8.

Akurat teraz prowadzę 4-dniowe autorskie warsztaty dla programistów (korzystających z Java EE 5 z RAD8) i administratorów WAS7, w których staram się minimalizować przedstawienie tematu od strony teoretycznej, kładąc nacisk na praktyczną stronę pracy z w/w produktami. Skłamałbym, gdybym powiedział, że udało mi się odpowiedzieć na wszystkie pytania, a było również wiele niezwykle inspirujących. Zebrałem tym samym mnóstwo tematów do przyszłych skrinkastów, więc można spodziewać się ich jeszcze kilka w tym roku i wszystkie (a przynajmniej ich większość) wokół JEE. Końcówka 2010 zapowiada się pracowita nagraniowo. W końcu pojawiła się wena, z którą zamierzam wejść w 2011!

p.s. Uruchomiłem nową ankietę "Preferowany sposób nauki JEE6", w której badam zainteresowanie różnym sposobem prezentacji JEE6. Znajdziesz ją po prawej na moim blogu. Zapraszam.

06 grudnia 2010

Odkrywcze podobieństwo Java SE i Java EE z CDI na czele

5 komentarzy
Każdy, kto programuje w Javie "siedzi" na poziomie Java Standard Edition, w skrócie Java SE, czy wręcz JSE. Obecna wersja to 6.0. Mamy do dyspozycji cały zestaw interfejsów i klas - wszystko objęte terminem Java SE API. Dokumentacja do aktualnej wersji znajduje się na stronach Java Platform, Standard Edition 6 API Specification. To powinno być oczywiste i należy do podstawowej wiedzy programisty Java.

Co jednak nie jest już tak oczywiste, to jak niewiele różni obecnie JSE od kolejnego zestawu Java API o nazwie Java Enterprise Edition, w skrócie Java EE, albo po prostu JEE. Zwracam Twoją uwagę na termin "kolejny zestaw Java API". Od lat siedzę przy obu zestawach - JSE i JEE, a jednak dopiero teraz dotarło do mnie, jak niewiele je różni - wszystko za sprawą środowiska uruchomieniowego, które określa zachowanie naszej aplikacji.

Do wersji JSE 5.0 wcale nie było oczywistym, że umiejętność programowania na platformie JSE jest równoznaczna z JEE. Nie grzebiąc za długo w historii JEE postawię tezę, że umiejętność posługiwania się JSE była dalece niewystarczająca od posługiwania się JEE. Wiele się być może nie zmieniło chyba, że nie mówimy o właściwym użyciu API (semantyce), a jedynie umiejętności użycia konstrukcji (składni). Tu widzę duże uproszczenia.

Od wersji JSE5 mamy adnotacje. Możliwość dopisywania metainformacji na różnym poziomie naszych bytów javowych - interfejsów, klas, pól i metod. Szybko zauważono ich zaletę i zaraz wprowadzono na JEE. I jakkolwiek tworzenie aplikacji na poziomie JSE zmieniło się nieznacznie, to w przypadku JEE postęp jest ogromny.

Poniżej klasa do uruchomienia na platformie JSE.
package pl.jaceklaskowski.blog;

public class BlogEntry {
    private String title;

    public BlogEntry(String title) {
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
    
    public BlogEntry create(String title) {
        return new BlogEntry(title);
    }
}
Od wersji JSE5 można dodawać do klasy metadane w postaci adnotacji. Dwoma z adnotacji dostarczanych w ramach zestawu JEE5 są @Entity oraz @Id.
package pl.jaceklaskowski.blog;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class BlogEntry implements Serializable {

    @Id
    private int id;
    private String title;

    protected BlogEntry() {
    }

    public BlogEntry(String title) {
        this.title = title;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public BlogEntry create(String title) {
        return new BlogEntry(title);
    }
}
Poza dodaniem tych dwóch adnotacji pojawiły się również zmiany w samym kodzie klasy. I jakkolwiek samo użycie adnotacji nie wymaga ich, to użycie na platformie JEE może uczynić je obowiązkowymi do poprawnego użycia klasy. Aby ujawniła się ich obowiązkowość konieczne jest uruchomienie klasy w ramach platformy JEE, tj. serwera aplikacyjnego JEE (którego zadaniem jest udostępnienie usług respektujących wytyczne specyfikacji JEE) oraz użycie konstrukcji aktywujących daną funkcjonalność. Innymi słowy, samo uruchomienie w ramach serwera aplikacyjnego JEE nie jest równoznaczne z użyciem usługi, która interpretuje adnotacje. Nie zamierzam jednak tym razem wnikać w szczegóły i unikam wyjaśnień wskazując podręcznik The Java EE 6 Tutorial, a szczególnie rozdział Part VI Persistence. Obowiązkowa lektura dla każdego, któremu marzy się tworzenie aplikacji korporacyjnych w JEE, o których w kolejnych wpisach.

I te małe dodatki - metadane w postaci adnotacji - mnie dzisiaj zachwyciły. Podczas lektury artykułu w Sieci na temat tworzenia Web Services, olśniło mnie, że aplikując adnotacje do klasy i uruchamiając ją w ramach serwera aplikacyjnego dostajemy wiele przy tak niewielkim nakładzie pracy.

Przyjrzyj się poniższej klasie.
package pl.jaceklaskowski.blog;

public class BlogPanel {
    public Blog createBlog(String title) {
        return new Blog(title);
    }
}
Niewiele w niej cech aplikacji korporacyjnej, którą cechuje użycie bazy danych (często wielu równocześnie), dostęp do innych zasobów transakcyjnych, różne protokoły dostępowe (wszechobecny HTTP może być uzupełniany przez chociażby FTP czy IMAP) czy bezpieczeństwo. To tylko niektóre z możliwych usług serwera aplikacyjnego JEE.

Przyjrzyjmy się kolejnej wersji wcześniejszej klasy BlogPanel, która różni się jedynie adnotacją @Stateless.
package pl.jaceklaskowski.blog;

import javax.ejb.Stateless;

@Stateless
public class BlogPanel {
    public Blog createBlog(String title) {
        return new Blog(title);
    }
}
Tym razem, poza @Stateless, nic więcej się nie zmieniło. Czyżby?

Jeśli uruchomisz tę klasę na serwerze aplikacyjnym JEE, okaże się, że wykonanie metody createBlog(String title) pociągnie za sobą wzbudzenie monitora transakcji i uruchomienie dedykowanej transakcji, która rozpocznie się i zakończy z rozpoczęciem i zakończeniem wykonania ciała metody. Dodatkowo, każdemu będzie wolno wykonać tę metodę, ale samo sprawdzenie zostanie wykonane. Jak widać, użycie tak niewinnie wyglądającej adnotacji @Stateless może odmienić zachowanie aplikacji, a jej czas wykonania wydłuży się kosztem opakowania jej usługami serwera.

Tak wiele, tak niewielkim kosztem - odkrywcze podobieństwo między JSE a JEE.

W JEE6 pojawiło się rozszerzenie oferowanego API o pakiety javax.enterprise.inject, javax.enterprise.context oraz javax.enterprise.event, które materializują wytyczne specyfikacji JSR 299: Contexts and Dependency Injection for the Java EE platform, w skrócie CDI. Sama specyfikacja jest częścią Java EE 6 i przez to obowiązkowa w ramach serwerów aplikacyjnych JEE6 (tu należy zwrócić uwagę na wersję wspieranego zestawu JEE - musi być 6).

I tutaj było moje największe odkrycie, a w zasadzie faktyczne przetrawienie wszystkiego, co do tej pory usłyszałem na temat JEE6, EJB 3.1, JSF 2.0, JPA 2.0, Servlets 3.0 i kilku innych.

Wszystkie byty na platformie JEE6 są opisywalne przez adnotacje.

Z tego płynie bardzo istotna wiedza pozwalająca zrozumieć sedno działania serwera aplikacyjnego JEE i związywania usług do odpowiednich składowych (komponentów) naszej aplikacji. Wystarczy zaaplikować adnotację i jak za dotknięciem czarodziejskiej różdżki pojawi się automagicznie pożądana funkcjonalność (ortogonalna do funkcjonalności biznesowej, którą oprogramowujemy i tu jest właśnie miejsca dla naszej inwencji twórczej).

Skoro CDI to specyfikacja odnosząca się do definiowania kontekstu funkcjonowania bytu zwanego ziarnem zarządzanym (ang. managed bean) - wcześniej termin zarezerwowany przez specyfikację JSF) i to właśnie kontekst wyznacza jego cykl rozwojowy (ang. lifecycle) - przejścia między stanami, w których wyróżnionymi są utworzenie i zniszczenie obiektu, wtedy można postawić tezę, że wszystko, co mamy do dyspozycji jako programiści JEE6 można oprzeć na CDI.

W ten sposób Resin - kontener webowy - oferuje EJB 3.1 przez CanDI. Pewnie będzie można zauważyć podobny trend w innych serwerach aplikacyjnych.

CDI jest również możliwe do uruchomienia na platformie JSE6, ale w takiej konfiguracji będziemy musieli rolę serwera przejąć na siebie i oprogramować w ramach aplikacji. Nawet, jeśli CDI i JEE6 nie są doskonałe, to są standardem, który zmierza w dobrym kierunku. Po czasach rozterek JEE vs Spring Framework+Hibernate mam wrażenie, że wybór staje się bardziej oczywisty. Mnie to cieszy.

02 grudnia 2010

73. spotkanie Warszawa JUG - Andrzej Salwicki z "O obiektach aktywnych, obcym wołaniu metod takich obiektów i problemie otwartym?"

0 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG)Warszawska Grupa Użytkowników Javy (Warszawa JUG) zaprasza na 73. spotkanie, które odbędzie się w najbliższy wtorek, 7. grudnia o godzinie 18:00 w sali 5440 Wydziału MIM UW przy ul. Banacha 2 w Warszawie.

Temat: O obiektach aktywnych, obcym wołaniu metod takich obiektów i problemie otwartym?
Prelegent: prof. dr hab. Andrzej Salwicki

Podczas prezentacji omówię obiekty aktywne (rodzaj wątków) i oryginalną, obiektową koncepcję komunikacji/synchronizacji obiektów aktywnych zaproponowaną przez Bolka Ciesielskiego w 1988. Metody obiektu aktywnego mogą dynamicznie zmieniać swój status:
prywatny -> publiczny -> prywatny -> publiczny -> ...
enable m disable m
Wywołanie z obiektu Y metody m w obiekcie X wygląda zwyczajnie (* call *) X.m(...). Różnice sprowadzają się do kilku punktów:
- chociaż obiekt aktywny Y wywołuje metodę m w obiekcie X, to obiekt X ma ją wykonać,
- aby mogło do tego dojść, metoda m obiektu X musi być publiczna (ang. enabled),
- takie obce wołanie metody może być zrealizowane w sposób synchroniczny, spotkanie instrukcji wywołania (w Y) z instrukcją accept (w X), lub w sposób asynchroniczny (wywołanie metody PRZERYWA wykonywanie wątku X'a - X wykonuje metodę m - i wraca do dalszego ciągu swego wątku.

Odczyt przedstawi szczegóły i omówi zalety takiego rozwiazania. Pomysł ten jest wykonalny (sprawdzono w Loglanie'82).

Na zakończenie przedstawimy interfejs AO (obiekt aktywny) i sformułujemy wyzwanie: zaimplementować ten interfejs w Javie lub udowodnić, że nie mozna tego zrobić bez modyfikacji JVM. Za rozwiązanie problemu przysługuje nagroda!

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

Wstęp wolny

Zapraszam w imieniu prelegenta i grupy Warszawa JUG!

01 grudnia 2010

Java EE 6 webapp development with CDI, GlassFish and NetBeans 7

9 komentarzy
Próbowałem się z NetBeans IDE 7.0 (wersja rozwojowa z dzisiaj) i kiedy sprawdzałem możliwości CDI z przekazywaniem (aka wstrzykiwaniem) zależności do servletu przyszło mi do głowy, aby nagrać moje doświadczenia. Nie są one wyrafinowane, ale chodziło mi raczej o popróbowanie się ze skrinkastami w kwadrans, aby nabrać większej umiejętności w tego typu przekazie niż na samej oprawie czy treści. Chciałem również sprawdzić, czy uda mi się opublikować nagranie na YouTube w formacie 1080p.

Zero podkładu głosowego, zero muzyni, niewiele treści merytorycznej, ale nagranie w Full HD jest. Tym samym 3-minutówka znalazła się na YouTube do oceny publiczności.

Teraz kolej na Ciebie. Zadanie na dziś to obejrzenie filmiku i ocena jego przydatności, a właściwie wskazanie niedoskonałości i tym samym zagwarantowanie sobie bardziej przyzwoitej treści w kolejnych odsłonach.

Zapraszam na swój kanał na YouTube do obejrzenia Java EE 6 webapp development with CDI, GlassFish and NetBeans 7.

p.s. Uruchomiłem ankietę "Temat przewodni na grudzień", której celem jest określenie tematyki, którą chciał(a)byś, abym rozpracowywał w ostatnim miesiącu tego roku - grudniu 2010. Zainteresowanych wyrażeniem swojego zdania zapraszam na blog, gdzie po prawej u góry znajduje się ankieta. Sugestie w postaci odpowiedzi "Inne?!" proszę o rozwinięcie na priv, albo w komentarzu do tego wpisu.

29 listopada 2010

Po wykładzie na PWSZ w Tarnowie

14 komentarzy
O planach związanych z wykładem pisałem w poprzednim wpisie - Wykład akademicki na PWSZ w Tarnowie - 29.11 od 9:30 do 18:00 i jak to w życiu bywa - plany swoje, a życie swoje.

Mając niemałe obawy o zakres merytoryczny wykładu, postanowiłem przelecieć większość z tego, co nazwałbym interesującym wycinkiem mojej wiedzy technicznej, aby choć na moment móc podzielić się czymś nowym z uczestnikami. Sądziłem, że uczestnicy większość tematów mają już za sobą, więc pojawiły się produkty IBM, o których, jeśli słyszano, to niewiele praktycznie i choć one gwarantowały mi możliwość przekazania czegoś niezbadanego. Po ostatnich szkoleniach z IBM WebSphere BPM z programowania i administracji nie miałem złudzeń, że w ostateczności wejdę na niskopoziomowe "rozbieranie" trzewi WPS V7 czy WAS V8. Sądziłem, że coś w końcu będzie wartościowe, aby spędzić kilka chwil i wziąć udział w wykładzie.

Do ostatniej chwili nie byłem pewien, czy dobrze dopasowałem tematykę. Czym bliżej wystąpienia, tym nachodziła mnie większa ochota, aby w niej pomajstrować. Wziąłem kilka książek, aby tam znaleźć coś unikatowego, a jednocześnie wartościowego, zabrałem się za lekturę podręczników, itp. Zacząłem odczuwać tremę przed niewstrzeleniem się w oczekiwania (które mogły być podkręcone moimi wycieczkami w różne strony rozwiązań javowych).

Zaplanowałem całkiem pokaźny bagaż tematyczny (vide poprzedni wpis z harmonogramem) i wszystko miało odbyć się bez nawet najdrobniejszego slajdu, aby ostatecznie okazać się, że z grupy około 50 osób niewiele ponad 3 osoby miały styczność z Javą (!) To było chyba najbardziej dla mnie szokujące. Ja tu zmagałem się z JEE6 i poziomy wyżej, przy SCA i BPEL, a okazało się, że należało zacząć od samego początku - samego poznawania języka Java. Trafiłem do mekki programistów C!

Jako, że przygotowany byłem na wprowadzenie do dostępu do bazy danych, przez JDBC, Hibernate, Spring Framework, Hibernate+Spring Framework, JPA i EJB, w zasadzie byłem gotowy zacząć pierwsze kilka kwadransów na wprowadzenie do Javy - bez wycieczek w programowanie OO. Pozostałem przy prostych konstrukcjach typu wyświetl na ekran, pobierz z ekranu i na tym się skończyło wprowadzenie.

Zabrałem się za dostęp do bazy danych. MySQL sprawowało się znakomicie, a NetBeans IDE (wersja rozwojowa z dnia poprzedniego) całkiem sprawnie uwijała się przy składaniu kolejnych części aplikacji. Tutaj i Java Tutorial się przydał, aby pokazać, w jaki sposób można przejść podobną ścieżkę, którą właśnie przechodziliśmy (gdyby komuś przyszło do głowy odtworzyć nasze wspólne poczyniania samodzielnie). Od czasu do czasu NetBeans IDE czkał zamrażając się na dobre kilkadziesiąt sekund, co złożyłem na braku dostępu do Sieci i jego młodzieńczego wieku (w końcu to wersja rozwojowa). Na moment przełączyłem się do Eclipse IDE, ale i jemy przypomniało się, aby zaktualizować/sprawdzić coś w Sieci i zamarzł. Wróciłem do NetBeans IDE.

Na zakończenie pierwszego bloku wykładów pokazałem coś, co określiłbym - impress me. Skąd wzięło się to cudo? Chcąc dopasować się do oczekiwań uczestników, zapytałem, co jeszcze mógłbym im pokazać i padło "Zaimponuj nam czymś w Javie, co sprawiłoby, że zechcielibyśmy się nią zająć". Od razu zabrałem się za...Clojure.

Pewnie pomyślisz sobie, zwłaszcza jeśli znasz mój poziom znajomości tego języka, że to był najgorszy z możliwych wyborów. Co to, to nie. Zdecydowanie NIE. Ja wręcz uważam, że właśnie tym najbardziej ująłem ich za serce i przy tym właśnie temacie miałem wrażenie zdobyłem ich największą uwagę. Takie odniosłem wrażenie i jeśli jakikolwiek temat miał swoje komentarze, to Clojure był zdecydowanym liderem. Dlaczego? Kwintesencją dobrej prezentacji jest dopasowanie przykładu do tematu. I tak właśnie było z Clojure.

Podczas sesji z Clojure pokazałem, jak interaktywie tworzyć aplikację okienkową, gdzie rozpoczynam od "gołej" aplikacji na bazie JFrame i dodaję kolejne elementy graficzne. Kiedy pierwszy raz wpadłem na ten pomysł, wiedziałem, że to będzie cudo. Na dole miałem terminal z Clojure REPL, na górze właśnie otworzone okienko przyszłej aplikacji okienkowej, a pod nimi Eclipse z odtwarzanym skryptem, w którym widać było wpisywane linie kodu w Clojure. Zamierzam, to nagrać w postaci skrinkastu, więc chwila i sam przekonasz się, o czym się tutaj pisze.

Clojure nie jest tutaj jakimś specjalnym czymś, co sprawiłoby, że jest to możliwe. Po prostu, jako język skryptowy - podobnie jak Groovy, JRuby, Rhino, Scala, Jython - daje możliwość nauki API przez wprowadzanie kolejnych wywołań w czymś ala Clojure REPL i natychmiastowego otrzymywania rezultatów z ich uruchomienia. Możnaby to przyrównać do środowiska ciągłej nauki API. Bajka!

Po przerwie, przeszliśmy przez Hibernate, Spring Framework i tworzenie aplikacji z servletami (obsługa formularza) z niewielkim EJB uruchamianym w ramach aplikacji webowej (nowość JEE6). W zasadzie 7 osobom udało się wytrwać do 18:00, kiedy to punktualnie zakończyłem wykład.

Bardzo pomocny okazał się stoper firmy Apimac, który odmierzał równe 40-tominutówki i późniejsze 10-ciominutowe przerwy. Super rozwiązanie, aby zagwarantować pewność utrzymania czasu przez prowadzącego. Polecam!

Czego mi brakowało podczas tego wykładu, to większego udziału publiczności. Znalazło się kilku bardziej aktywnych, ale ogólnie panowała cisza i trudno było zorientować się, czy temat ciekawił, czy warto byłoby poruszyć inne aspekty i w ogóle sprawić, aby spędzony czas był wartościowy merytorycznie. Nieskromnie powiem, że bardzo ucieszyła mnie moja lekkość w zmianie tematu, tempa i dopasowanie do poziomu, ale wolałbym bardziej skrupulatne zajęcie się pojedynczym tematem, np. JEE6 niż przejściem od Java, Clojure, Hibernate, Spring, servlety i EJB. Trochę przypominało groch z kapustą, aczkolwiek zagwarantowało, że wykład spędziłem nie nudząc się ani na chwilę. Liczę, że uczestnicy również.

Sam Tarnów bardzo spokojny. Akurat dzisiaj spadło sporo śniegu, więc wszystko zasypane, ale i tak udało mi się dostrzec tlące się piękno tego miejsca. Po 18:00 w zasadzie zero otwartych sklepów i niepokojąca cisza na ulicy. Może poza Rynkiem jest inaczej?! Ach, zastanawiam się, dlaczego zegar na Ratuszu wybija połówki, kwadrans przed pełną i pełną godzinę?

p.s. Wykład prowadzony był w ramach programu Unii Europejskiej wspierającej wymianę doświadczeń między praktykami i firmy a uczelniami, z korzyścią dla nowej kadry informatycznej - studentów. Pewnie i na Twojej uczelni jest to możliwe. Wystarczy zapytać. Resztą się zajmę. Pisz na priv z prośbą o szczegóły. Na prawdę warto.

27 listopada 2010

Wykład akademicki na PWSZ w Tarnowie - 29.11 od 9:30 do 18:00

5 komentarzy
W nadchodzący poniedziałek, 29.11 będę na Wydziale Informatyki Państwowej Wyższej Szkoły Zawodowej (PWSZ) w Tarnowie (ul. Eljasza Goldhammera) u Tomasza Potempy i jego studentów, z którym zorganizowaliśmy mój wykład dotyczący tematu Java i okolice. Głównymi odbiorcami mają być studenci 4 roku, którzy kończą semestr z końcem grudnia, aby w styczniu skupić się na pisaniu pracy inżynierskiej.

Jak to ze mną bywa przy tego typu otwartych tematach, pomysłów mam wiele i byłbym rad, o kilka wskazówek pod kątem możliwości czasowych i znaczenia rynkowego poszczególnych tematów. Celem nie jest przekazanie pełnego obrazu danego rozwiązania, ale raczej naszkicowanie możliwości, aby wybrać do dalszego rozpoznania to, co może być interesujące.

Mam do dyspozycji 2 bloki 5-godzinne (w sensie lekcyjnym nie zegarowym, czyli 45 minut). Można założyć, że w każdym bloku będzie to samo, ale to zależy od ogólnego zainteresowania uczestników oraz mojego przekonania o sensowności dalszego brnięcia w temat. Tym samym nie ma gwarancji, że drugi blok będzie odpowiadał merytorycznie pierwszemu.

Zaczynam o godzinie 9:30, aby zakończyć o 18:00 z 1-godzinną przerwą obiadową w okolicach 13:15. Okazuje się, że będzie okazja spotkać się z Tomkiem Łabuzem, którego można było poznać podczas konferencji Javarsovia 2010, podczas której prezentował temat "AOP, ThreadLocal i JPA".

Planuję przeprowadzić autorski cykl tematyczny, którego mottem byłoby "Od prostoty do większej prostoty, tj. w każdym kroku ukrywamy złożoność problemu". Nie planuję prezentować slajdów, a jedynie siedzieć przed komputerem, prezentując budowanie aplikacji i machając rekoma ze wstawkami krasomówczymi.

Konspekt

Środowiska programistyczne i uruchomieniowe, darmowe i komercyjne:
  • NetBeans IDE i Eclipse IDE
  • IBM Rational Application Developer 8 i IBM WebSphere Integration Developer 7
  • GlassFish i IBM WebSphere Application Server 8 
Klient bazodanowy - tradycyjne podłączenie do bazy danych z użyciem JDBC
  • Apache Derby (wbudowane)
  • MySQL
Hibernate - warstwa pośrednia między baza danych a aplikacja
  • ORM - zapytania bliższe programiście nie adminowi bazy danych
Hibernate + Spring Framework
  • zniesienie konieczności zarządzania bytami Hibernate
  • środowisko IoC/DI
Apache Maven - zarządzanie zależnościami projektowymi
  • zniesienie konieczności dbania o zależności poza ich deklarację
  • tworzenie projektu od zera
    • z linii poleceń
    • z IDE (NetBeans IDE)
Leiningen - Maven w Clojure
  • bez XML z językiem Clojure (wrócimy do niego niebawem)
GlassFish (w NetBeans IDE) i WAS 8 - serwer aplikacyjny JEE6 (z RAD8):
  • dostęp do bazy danych (zarządzanie transakcjami)
    • JPA
    • EJB31
  • servlet - obsługa HTTP
  • JSF - budowanie widoku
    • facelets
  • CDI
EJB 3.1
  • Apache OpenEJB
  • Serwer aplikacyjny - GlassFish i WAS8
OSGi - modularność
  • podział projektu na moduły w Apache Maven był podziałem funkcjonalnym (jak OSGi)
  • samodzielna aplikacja
Clojure - język funkcyjny
  • dynamiczne tworzenie aplikacji okienkowej
Service Component Architecture (SCA) i procesy BPEL (WID/WPS)
  • odseparowanie kontraktu (interfejsu) od implementacji
  • odseparowanie szczegółów komunikacyjnych od implementacji
Wyjeżdżam z Tarnowa dopiero we wtorek, więc jeśli ktoś reflektuje na spotkanie, proszę o kontakt.

20 listopada 2010

72. spotkanie Warszawa JUG - Jacek Laskowski z "Clojure praktyczniej: REPL, Eclipse CCW, Eclipse Mylyn, monady i defrecord"

0 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG)Warszawska Grupa Użytkowników Javy (Warszawa JUG) zaprasza na 72. spotkanie, które odbędzie się w najbliższy wtorek, 23. listopada o godzinie 18:00 w sali 5440 Wydziału MIM UW przy ul. Banacha 2 w Warszawie.

Temat: Clojure praktyczniej: REPL, Eclipse CCW, Eclipse Mylyn, monady i defrecord
Prelegent: Jacek Laskowski

Kontynuacja relacji z mojej nauki języka funkcyjnego na wirtualnej maszynie Javy - Clojure. Tym razem przedstawię bardziej praktyczną część mojej nauki Clojure, od strony środowiska, w którym go poznaję z pewnymi elementami języka. Zaprezentuję Clojure REPL, wsparcie narzędziowe oferowane przez wtyczki Eclipse: CounterClockWise (CCW) i Mylyn oraz wstęp do monad i defrecord. Sądzę, że dzięki tej wiedzy będzie łatwiej rozpoczać samodzielną naukę Clojure.

Jacek Laskowski jest założycielem i liderem grupy warszawskich użytkowników Javy - Warszawa JUG. Prowadzi bloga Notatnik Projektanta Java EE, w którym przedstawia swoje użycie Javy i okolic. Zawodowo w IBM jako specjalista produktów z rodziny WebSphere, głównie WebSphere BPM z flagowymi produktami: IBM WebSphere Dynamic Process Edition i IBM WebSphere Lombardi Edition. Nadaje na falach twittera jako @jaceklaskowski.

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

Wstęp wolny

Zapraszam w imieniu swoim i grupy Warszawa JUG!

18 listopada 2010

Praca inżynierska z JSF2? Może jednak CDI i OSGi?

4 komentarzy
Kilkakrotnie pytano mnie o tematy prac inżynierskich i magisterskich, a wtedy zaczyna się główkowanie, który byłby tym jedynym, interesującym. Kiedy wyszła Java EE 5 byłem zachwycony zmianami, podobnie z JEE6. Było też zainteresowanie OSGi i okolicami, teraz programowanie funkcyjne z Clojure, a w odwodzie kilka innych, mniej lub bardziej ciekawych zagadnień. Nawet dzisiaj zostałem poproszony o wyznaczenie tematów do przedstawienia studentom w ramach praktyk studenckich w IBM i w mgnieniu oka miałem 10 sztywno określonych i jeden otwarty, który rozpoczynał się od "Rozpoznanie wybranej funkcji* produktu z rodziny IBM WebSphere BPM". Współpraca ze studentami to niezwykle ciekawy i produktywny sposób na poznawanie nowego (człowieka i jego sposobu myślenia oraz samego tematu). Wszyscy zadowoleni.

Postanowiłem rzucić temat wyszukania czegoś ciekawego na bloga licząc, że ktoś ma pomysł w zakresie JavaServer Faces (JSF) 2.0, a boryka się z problemem braku czasu na jego dogłębne rozpoznanie w postaci pracy licencjackiej (to jakby nie patrzeć rok ślęczenia nad tematem!).

Autor ostatniej prośby napisał:

Czy istnieje możliwość nawiązania współpracy w zakresie mojej pracy inżynierskiej, naturalnie związanej z korporacyjną Javą. Chciałbym zrealizować temat nie tylko wartościowy merytorycznie ale i również interesujący z punktu widzenia programisty, wolałbym uniknąć pracy odtwórczej i skupić się na tym co mógłbym poprzez swoją pracę dyplomową wnieść od siebie. Jestem już po wstępnej rozmowie z moim promotorem, z którym rozważaliśmy możliwość podjęcia tematu związanego mniej lub bardziej z JSF 2.0. Wiem, że jesteś otwarty na różnorodne propozycje, dlatego po cichu liczę na email od Ciebie przesiąknięty entuzjazmem, który mnie nie opuszcza nawet na krok podczas rozważań nad tematem mojej pracy.

Na moją odpowiedź, raczej w tonie ostrożnej aprobaty, otrzymałem taką:

Dzięki za zainteresowanie moją propozycją, tak jak już wcześniej wspomniałem chciałbym poprzez swoją pracę dyplomową wnieść coś od siebie. Wykorzystanie JSF2 do zbudowania przykładowej aplikacji webowej jest ostatecznym rozwiązaniem, którego nawet nie chcę brać pod uwagę. Idealnym rozwiązaniem byłby temat oryginalny oraz interesujący.

W kwestii tematu właśnie liczyłbym na Twoją pomoc, z pewnością są zagadnienia związane z JSF2, którymi zainteresowany jesteś najbardziej. Wiedzę w tej dziedzinie masz nieporównywalnie większą niż moja, stąd zapewne mógłbyś zaproponować kilka interesujących pomysłów. Może istnieje jakieś komercyjne narzędzie (lub jego część), które czeka na swoją ogólnodostępną implementację? A może masz zupełnie inny pomysł na temat pracy?


I tutaj pojawiła się moja odpowiedź, już z wstępnym szkicem zakresu technologicznego pracy:

JSF2 jest ciekawe, ale coś mi mówi, że wiele tu już zrobiono i ciekawym mogłoby być użycie innej technologii tworzenia UI niż facelets czy JSP. Przyjrzałbym się jednak bardziej użyciu CDI w JSF i co do tej pory zrobiono. CDI jako rozwiązanie javowe weszło dopiero w JEE6, więc jest bardzo młode i pewnie wiele tutaj do zrobienia. Gdybym miał szukać ciekawego tematu właśnie koło CDI kręciłbym się, może w połączeniu z OSGi?! Właśnie CDI + OSGi wydaje się być nietrywialnym tematem dotykającym dwa rozwiązania. To byłoby cudo techniczne!

Uważacie, że JSF2, CDI i OSGi mogłoby być "produktywnym" stosem technologicznym? Co mógł(a)byś Ty zaproponować delikwentowi? Mnie zawsze intrygowało, czy dałoby się tak użyć JSF, aby zbudować aplikację desktopową? W końcu JSF dotyka warstwy widoku i aplikacje webowe są jedynie/aż implementacją referencyjną demonstrującą oferowane możliwości (albo ich brak) budowania niebagatelnego interfejsu użytkownika. Gdyby relacjonować JSF2, czy byłoby cokolwiek, co stanowiłoby dla Ciebie szczególnie ciekawe zagadnienie? Wszelkie propozycje będą uważnie rozpatrzone, a upublicznione mają niemałe szanse na realizację. Dla mnie będzie to stanowiło magnes do powrotu do Java EE 6, które zeszło na plan drugi po pojawieniu się Clojure, dla Ciebie zrealizowanie pomysłu cudzymi rękoma, a pytającemu zapewnią ciekawe spędzenie czasu przy pracy inżynierskiej. Wszyscy są do przodu!

[*] Dowiedziałem się dzisiaj, że nie ma liczby mnogiej od "funkcjonalność", a można mówić jedynie o funkcjach produktu (!)

10 listopada 2010

Monady maybe odsłona kolejna - rozwiązanie problemu nr 1

5 komentarzy
Logo ClojurePamiętamy 2 problemy z wpisu "O warsjawie i monadach w Clojure - nauka wspólnie jako sposób własnego rozwoju"? Daniel zaproponował rozwiązanie w Clojure (nota bene, tam dowiedziałem się o możliwości nazywania bytów w Clojure tak nieszablonowo jak "kraj->waluta"!), a Grzesiek w Scali. Grzesiek postawił kolejny problem: "Nie mam pojecia jaki zwiazek maja zaproponowane przez Ciebie problemy z monadami", na który postaram się dać odpowiedź w tym wpisie.

Rozwiązanie do problemu 1. polega na wychwyceniu sytuacji, w której poszukiwana wartość nie istnieje, której wystąpienie powinno zatrzymać kolejne obliczenia. Pozwoliłem sobie na użycie terminu obliczenie jako zastępstwa dla "funkcja", aby przywyczajać do pewnej abstrakcji, którą wprowadzają monady, z którymi są one nierozerwalnie skojarzone.

W Javie obsłużylibyśmy taką sytuację przez zastosowanie "wzorca"
if (nieZnaleziono) return null;
zanim wykona się kolejne obliczenie. To nakłada pewną dyscyplinę na programistę, aby pamiętał o takiej konstrukcji lub innym, właściwym obsłużeniu oraz (co bardziej istotne) niepotrzebnie zaciemnia treść metody. Są inne, ładniejsze rozwiązania i liczę na ich prezentacje w postaci komentarzy do tego wpisu (które wykorzystam do kolejnych odsłon "monadycznych").

Rozwiązanie Daniela, jakkolwiek bardzo twórcze i wiele się można z niego nauczyć, jest jednak obarczone problemem ignorowania sytuacji wyjątkowej, w której nieistnienie elementu w zbiorze nie powoduje zatrzymania kolejnych obliczeń, a więc w którymś momencie może doprowadzić do NPE (!) Można się o tym przekonać modyfikując nieznacznie zaproponowane rozwiązanie.
user=> (defn printlnX
  [v]
  (do
    (println "Wykonano z:" v) ; wyświetl wartość
    v                         ; zwróć ją
    ))
user=> (defn pracownik->waluta [p] (-> p printlnX pracownik->departament printlnX departament->kraj printlnX kraj->waluta printlnX))
#'user/pracownik->waluta
user=> (pracownik->waluta "Daniel")
Wykonano z: Daniel
Wykonano z: nil
Wykonano z: nil
Wykonano z: nil
nil
Co oznacza ni mniej ni więcej, że każde z kolejnych obliczeń było wykonane.

A co powiecie o takim rozwiązaniu?
user=> (defn pracownik->waluta
  [p]
  (domonad maybe-m
    [dept (pracownik->departament p)
     kraj (departament->kraj dept)
     waluta (kraj->waluta kraj)]
    waluta))
Tym razem opieram się na wykorzystaniu monady maybe, której działanie można streścić tak: "Jeśli dowolne obliczenie w serii obliczeń zwróci nil/null/wartość nieporządaną, kończymy". Sprawdźmy (musimy wcześniej dodać do niej "magiczne" printlnX).
user=> (defn pracownik->waluta
  [p]
  (domonad maybe-m
    [_ (printlnX p)
     dept (pracownik->departament p)
     _ (printlnX dept)
     kraj (departament->kraj dept)
     _ (printlnX kraj)
     waluta (kraj->waluta kraj)]
    waluta))
user=> (pracownik->waluta "Daniel")
Wykonano z: Daniel
nil
Konwencją w Clojure jest oznaczenie wartości przez podkreślnik "_", jeśli nie interesuje nas.

Czy teraz widać różnicę? Dzięki monadzie maybe kolejne obliczenia nie są wyliczane, co często nazywa się "szybkim przerwaniem" - jeśli już wystąpi błąd, to nie ma sensu wykonywać kolejnych kroków w ciągu obliczeń. Podobnie działa LinQ.

Na zakończenie jeszcze jeden przykład, który może uzmysłowić znaczenie monady maybe i transformat monadycznych, czyli możliwości składania lub modyfikowania monad.

Załóżmy, że nasza aplikacja zawiera serię ekranów. Jeśli użytkownik wciśnie "Zatrzymaj" albo "Anuluj", kolejne - z oczywistych względów - nie powinny być wyświetlone. Dobrze byłoby móc zająć się jedynie wyświetlaną treścią bez konieczności dbania o detale obsługi zdarzenia zatrzymaj czy anuluj. To pozostawiamy pewnemu, bardziej generycznemu rozwiązaniu, które co najwyżej konfigurujemy dopasowując do naszych potrzeb. I tutaj właśnie widzę zastosowanie dla monady maybe. Tym razem wartością szczególną będzie 1.
user=> (def screen-maybe-m (maybe-t maybe-m 1))

user=> (import 'javax.swing.JOptionPane)

user=> (defn showConfirmDialog
  [step]
  (JOptionPane/showConfirmDialog nil (str "Step" step ": Continue?") "Monads" JOptionPane/YES_NO_OPTION))
  
user=> (defn screen1
  []
  (showConfirmDialog 1))

user=> (defn screen2
  []
  (showConfirmDialog 2))

user=> (defn screen3
  []
  (showConfirmDialog 3))

user=> (domonad screen-maybe-m
  [_ (screen1)
   _ (screen2)
   _ (screen3)]
    "Wykonano całość")
Tylko, jeśli użytkownik zaakceptuje wszystkie z wyświetlonych ekranów, nastąpi wyświetlenie "Wykonano całość". Sprawdzenie prawdziwości tego stwierdzenia pozostawiam Tobie.

08 listopada 2010

Clojure, wyrażenia regularne i ćwiartowanie

1 komentarzy
Logo ClojureIleż to razy obiecywałem sobie, że przysiądę nad wyrażeniami regularnymi. Pamiętam, jak proste było ich użycie w Groovy, a teraz, kiedy spędzam część mojego czasu z Clojure, nie jest inaczej - ponownie łatwizna. Zgoda, nie jest łatwo, jeśli nie wiadomo, jak się je konstruuje, ale jest prościej niż w Javie (co miało być potworzone, już jest gotowe do użycia). Dzisiaj miałem 2 bliższe spotkania z wyrażeniami regularnymi i oba były olśniewające.

Potrzebowałem odszukać definicji fn* w Clojure. Wszedłem na kanał #clojure na IRC i w niecałą minutę, może dwie, miałem swoją odpowiedź - fn* to specjalny symbol w Clojure (zainteresowanych źródłami odsyłam do klasy clojure.lang.Compiler).

Kiedy poszukiwałem fn* z grep wiedziałem, że muszę wyłączyć specjalność gwiazdki, więc do poszukiwań użyłem grep "fn\*" src/clj/clojure/core.clj. Prościzna. Czego jednak nie wiedziałem, to że w vi gwiazdka jest również specjalna (w końcu vi to wizualny sed, a ten wyrażenia regularne traktuje podobnie jak grep). Jakież było moje zdumienie, kiedy szukając w vi ciągu znaków "fn*" skakałem początkowo po wyrazach for, software, found, i takie tam. Dopiero wtedy uzmysłowiłem sobie, że gwiazdka oznacza 0 lub więcej wystąpień i fn* pasuje do wymienionych idealnie, bo vi traktuje gwiazdkę specjalnie. Wystarczyło ponownie odszukać "fn\*".

Jakby tego było mało, chwilę później na kanale @learnclojure na twitterze, trafiłem na cudowny kawałek kodu z...wyrażeniem regularnym! Czyż to nie podwójnie olśniewające?!
(defn vectorize-date-str [ds]
  (let [[date m d y] (re-matches #"(\d{1,2})\/(\d{1,2})\/(\d{4})" ds)]
    [y m d]))

(vectorize-date-str "12/02/1975")
;=> ["1975" "12" "02]
Funkcja vectorize-date-str opiera się na dwóch użytecznych funkcjonalnościach wbudowanych w język Clojure - "ćwiartowanie"* parametrów (ang. destructuring) oraz funkcji re-matches. Obie konstrukcje dzielą parametr wejściowy, którym jest ciąg znaków reprezentujący datę w formacie mm/dd/YYYY na listę rok, miesiąc, dzień.

Przyznaję się bez bicia, że propozycja rozwiązania tego problemu z użyciem wyrażeń regularnych byłaby ostatnia w zaproponowanych, jeśli w ogóle pojawiłaby się (!) Już przekonałem się do "ćwiartowania" parametrów (więcej w Special Forms/(let [bindings* ] exprs*)), jako wstępnego przygotowania parametrów wejściowych (i swego rodzaju kontraktu między klientem funkcji, a nią samą), ale wyrażenia regularne wciąż były przeze mnie traktowane po macoszemu. Od dzisiaj koniec z tym!

[*] Propozycje tłumaczenia destructuring mile widziane. Proszę o coś bardziej wyrafinowanego niż destrukturyzacja.

06 listopada 2010

71. spotkanie Warszawa JUG - Cezary Bartoszuk z "Sztuczki w językach programowania"

0 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG)Warszawska Grupa Użytkowników Javy (Warszawa JUG) zaprasza na 71. spotkanie, które odbędzie się w najbliższy wtorek, 9. listopada o godzinie 18:00 w sali 5440 Wydziału MIM UW przy ul. Banacha 2 w Warszawie.

Temat: Sztuczki w językach programowania
Prelegent: Cezary Bartoszuk

Rozwijane obecnie języki programowania pełne są sztuczek: technik, wzorców, metod lub przepisów, których przyjęło się używać do osiągnięcia konkretnego celu. Sądzę, że aby poszerzyć swoją wiedzę o programowaniu warto poznać smaki ciekawych sztuczek stosowanych w różnych językach programowania.

Pogadankę o "sztuczkach" (jak będę je nazywał ze względu na to, że są bytami bardzo różnych rodzajów) podzieliłem na trzy zasadniczo różne części:

1) Typowanie
2) Przepływ danych
3) Przepływ sterowania

W każdej z tych części w sposób dość popularnonaukowy (i w dużej mierze opierając się na intuicjach) omówię kilka sztuczek, jakie stosowane są w językach programowania. Każda sztuczka będzie miała charakter informacyjny wraz z krótkim przejrzeniem plusów i minusów danego rozwiązania.

Do worka ze sztuczkami wrzucę między innymi: funkcje i typy wyższych rzędów, kontynuacje, jedną lub dwie monady i polimorfizm w różnych smakach.

Cezary Bartoszuk jest studentem Wydziału Matematyki, Informatyki i Mechaniki, kierunku informatyka. Interesuje się programowaniem funkcyjnym, współbieżnością i clean-codem. Zawodowo programista Pythona.

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

Wstęp wolny

Zapraszam w imieniu prelegenta i grupy Warszawa JUG!

03 listopada 2010

Samodoskonalenie zwinnych zespołów

3 komentarzy
3 dni wolnego, to doskonały moment, aby się chwilę zastanowić. Można się było nawet zastanawiać, nad czym by się tu zastanowić (!) Szacunek dla szczęśliwców.

Mnie wzięło na rozmyślania o terminie samodoskonalenie w połączeniu ze zwinnym zespołem. Wciąż rozmyślam, jakich sposobów używać, aby zachęcić do większej aktywności w ramach społeczności typu Warszawa JUG. Niby jest ponad 400 członków, a ruch na grupie, jakby było nie więcej niż 50. Czyżby pozostali nie posiadali własnego zdania?! Niemożliwe.

W tym kontekście, rozmyślam, jak wyglądałby mój doskonały zespół, gdyby mi przyszło prowadzić jakiś. Czy byłby zwinny i tym samym samodoskonalił się? Jak stałby się zwinny? I kiedy mógłbym stwierdzić, że jest samodokonalający się?

W moim przekonaniu samodoskonalenie jest wpisane w kontrakt zwinnego zespołu. Po prostu, jeśli jesteś zwinny (technicznie), to musisz się ciągle rozwijać. Możnaby postawić tezę, że siła zwinności liczona jest przez ilość czasu poświęcanego na rozwój siebie i "okolicy". Od ludzi posiadających taką cechę, czym ona mocniejsza, tym bardziej emanuje na innych. Taki zespół nie czeka na prośbę podzielenia się wiedzą, ale robi to regularnie i otwarcie. Jednym z "objawów" jest m.in. posiadanie własnego bloga (przez "własny" rozumiem taki, z którym się identyfikujemy - rzeczywiście własny lub całego zespołu).

Mam nieodparte wrażenie, że powszechnie pojęcie zwinnego zespołu kojarzy się głównie z posługiwanymi się narzędziami i technikami, które określa się jako zwinne - techniki Agile. Uważam, że to tylko jeden z trybików. Zgodnie z definicją słowa na pwn.pl "zwinny" to 1. «wykonujący szybkie, zręczne ruchy», 2. «o ruchach, poruszaniu się kogoś lub czegoś: szybki i zgrabny». Dokładnie odpowiada mojemu postrzeganiu zwinnego zespołu - jest zręczny, szybki i zgrabny (wszystko w kontekście jego "wyglądu" i zachowania stricte technicznego)

W moim rozumieniu zręczność techniczna zespołu jest cechą jego przygotowania do zastosowania odpowiedniego narzędzia do problemu. Tutaj liczy się znajomość wszystkich "cudów świata" - czym więcej języków programowania, bibliotek, szkieletów, produktów, tym lepiej. Niech znajomość ich będzie pobieżna, ale wystarczająca do podjęcia decyzji o zastosowaniu jednego vs drugiego.

Szybkość zespołu jest cechą, w której sama znajomość jest poparta pewnością wyboru narzędzia i umiejętnością jego wdrożenia - implementacji. Z szybkością kojarzy mi się bardziej pewność działania (ale nie arogancja!) niż czas. Tutaj liczy się posiadanie speców od danej technologi, którzy wykazują się większą niż przeciętna znajomością tematu. Nie oznacza to jednak, że całe ich dnie wyglądają podobnie - wciąż wałkują ten sam temat, a raczej szczególniej mu się przyglądają. Powiedzmy, że ta szczególność polega na poświęceniu tematowi 20% więcej czasu.

Zgrabność zespołu jest cechą, w której umiejętnie dopasowuje się do sytuacji. "Ciągłe ćwiczenia są kluczem do sukcesu" świetnie tutaj pasuje. Ciągłe próbowanie się z nowym i ciągłe dzielenie się wiedzą, aby w końcu ciągle następował przepływ wiedzy, którą można korygować, wzbogacać i ostatecznie zastosowywać. Niech wiedzą, kto wie, abyśmy wiedzieli, że wiemy :) Łatwo wpaść w zniechęcenie, kiedy człowiek sobie uzmysławia, jak niewiele wie. Pozytywne sygnały z zewnątrz mogą być niezwykle motywujące.

Kluczem jest wiedza i chęć jej zdobywania.

To, ile czasu poświęcamy na poznawanie, zależy wyłącznie od nas samych. To, ile czasu poświęcamy na dzielenie się wiedzą, również. Zastanawiam się więc, skąd tak niewielu z nas ma na to ochotę? Poznawajmy, próbujmy, dzielmy się wynikami, spostrzeżeniami i dyskutujmy. Niech Ci, co wiedzą, wiedzą, że my nie wiemy, a Ci, którzy nie wiedzą, wręcz przeciwnie, wiedzieli, że my wiemy. W końcu musi nadejść moment, w którym komuś zacznie się wszystko składać w coś sensownego i podzieli się z innymi, oszczędzając nam wysiłku, abyśmy mogli zabrać się za kolejny problem.

W jaki sposób uczyć się? Polecam czytanie, duuuużo czytania. Kiedy skończy się czytanie, warto podzielić się swoimi przemyśleniami - zacznijmy od bloga, w postaci krótkiej notki, albo wręcz mikrobloga (ala twitter lub delicious), gdzie pojawi się choćby ślad naszej aktywności w danym obszarze. Może też być podczas 30-minutowego spotkania zespołu pod koniec tygodnia, np. w czwartek, albo wystąpienia na spotkaniu JUGowym (mamy ich ponad 10 w Polsce!) W zasadzie, niech będzie wszystko po trochu. Czym szybciej wyłożymy nasze problemy do publicznego osądu, tym szybciej uda nam się dotrzeć do rozwiązania. Ludzie z natury są życzliwi i chcą pomóc. Są jednocześnie samolubni, więc widząc, że jest gość, który przygotuje, a później zreferuje, przyjdą i zadadzą pytanie bądź dwa. W ten sposób, osoba ucząca się zdobędzie postrzeganie innych, a oni w zamian dostaną naszą relację, nasze streszczenie tematu. Obie strony będą usatysfakcjonowane. Nikt nie traci.

Podsumowując: uczmy się i innych. Starajmy się dzielić wiedzą i inspirować innych do działania, ciągłego działania. Jeśli on to robi i Ty zaczniesz, to koniec końców znajdą się wreszcie inni, którzy widząc naszej sukcesy, zechcą pójść w nasze ślady (porażki również odnotowujemy w kolumnie sukcesów, bo nic tak nie "pionuje" jak solidna dawka porażki). Któż nie chciałby osiągać celu krócej? Satysfakcja gwarantowana.

Zastanawiasz się, od czego należałoby zacząć?! Zakładasz bloga i raz w tygodniu umieszczasz podsumowanie swojej tygodniowej działalności (nie masz co pisać, powinno być odczytywane jako strata tygodnia i pora zabrać się za inne, bardziej twórcze zajęcie). Potraktuj każde z wykonywanych czynności, jako możliwość nauki. Chcą, abyś coś sprawdził, sprawdź i jeszcze dodaj coś od siebie, np. niech to kolejnym razem będzie automatycznie, albo niech będzie spisane. Pomyśl o spotkaniach zespołu, podczas których dzielicie się ostatnimi doświadczeniami - coś ala retrospekcja, czy podsumowanie iteracji, czy jak to tam się mogłoby nazywać. Chodzi o bezpośredni kontakt z zespołem. Gdzieś ostatnio przeczytałem (w wolnym tłumaczeniu) "Skoro już jesteś, bądź zauważonym". Lans jeszcze nikomu nie zaszkodził :) Tylko z umiarem.

Sądzę, że po kilku tygodniach śmiało można będzie nazwać Cię liderem zwinnego zespołu. Gratulacje!

28 października 2010

monad w Clojure ciąg dalszy - o ich wewnętrznej reprezentacji

0 komentarzy
Logo ClojureZaczniemy od podniesienia wersji Clojure i Clojure Contrib w naszym środowisku. Nie ma ku temu żadnego, praktycznego powodu, a jedynie poznawanie nowego przez jego użytkowanie (w ten sposób można nawet nie zorientować się, że znamy nowe, bo po prostu było, to się używało). Pamiętamy o ciągłej nauce, samodoskonaleniu, ku uciesze członków zespołu? :-)

Wersja Clojure 1.3.0-alpha2 dostępna jest na jego stronie domowej (sekcja Downloads).

Podniesienie wersji Clojure nie wystarczy do korzystania z monad (w wersji 1.2).
devmac:~ jacek$ clj
Clojure 1.3.0-alpha2
user=> (use 'clojure.contrib.monads)
CompilerException java.lang.ClassNotFoundException: clojure.set, compiling:(clojure/contrib/accumulators.clj:121)
Konieczne jest pobranie standalone-1.3.0-alpha2.jar (z repo clojure.contrib) i umieszczenie w CLASSPATH dla Clojure REPL. Od tej chwili można cieszyć się dobrodziejstwem inwentarza.

Oczywiście w projektach zalecane jest skorzystanie z narzędzia w stylu Apache Maven, np. dla Clojure byłby nim Leiningen, a później należy postępować zgodnie z clojure-contrib 1.3.0-alpha2 deployed to build.clojure.org.

Po tych zmianach uruchamiamy REPL i wczytujemy przestrzeń c.c.monads, w której definiowane są monady.
devmac:~ jacek$ clj
Clojure 1.3.0-alpha2
user=> (use 'clojure.contrib.monads)
nil
Rozgrzewkę mamy za sobą.

Wracając do tematu przewodniego, tym razem nie będzie, do czego służą monady programistom czy matematykom, ale jak się je definiuje w Clojure i czym są w tym języku (ich wewnętrzną reprezentacją). Mam nieodparte wrażenie, że wiele zostało powiedziane o monadach i ten obszar został już dostatecznie zagospodarowany (zainteresowanym polecam przeczytać artykuły, które mam za sobą nt. monad ze znacznikiem "monads" na delicious.com).

Już wiemy (patrz poprzednie wpisy w kategorii clojure), że matematycznie i praktycznie monada to trójka składająca się z konstruktora typu - obliczenia, z którym związane są dwie, obowiązkowe funkcje - w terminologii Clojure będą to m-bind i m-result.

Poznawanie monad w Clojure opieram w dużej mierze na czytaniu artykułów, ale zauważam postęp w zrozumieniu ich sensu, kiedy poza materiałem literackim, uzupełniam go o przegląd źródeł c.c.monads z ich testami (dostępne w repo Gita - clojure-contrib/modules/monads).

Makro monad

Pierwsza konstrukcja tworzenia monad w Clojure to makro monad, które definiuje monadę jako mapę nazw funkcji i ich implementacji (coś ala klasa w Javie). W monadzie-mapie znajdziemy wskazanie na dwie, obowiązkowe funkcje m-result i m-bind oraz opcjonalne m-zero i m-plus.
user=> (monad
[m-result identity
 m-bind (fn [mv f] (f mv))
])
{:m-plus :clojure.contrib.monads/undefined, :m-zero :clojure.contrib.monads/undefined, :m-bind #<user$eval919$m_bind__920 user$eval919$m_bind__920@45570f5c>, :m-result #<core$identity clojure.core$identity@20773d03>}
W ten sposób zdefiniowaliśmy monadę. Tylko, co można z nią zrobić? Nic. W Javie mogłoby to odpowiadać konstrukcji new PewnaKlasa() bez przypisania jej do zmiennej (nie wliczając skutków ubocznych, co jest możliwe, ale nierekomendowane, np. wykonanie statycznej metody, albo stworzenie wątku). W Clojure nie ma zmiennych (to jest koncept języka imperatywnego), a jedynie symbole (koncept języka funkcyjnego).

Innymi słowy, monada w Clojure jest niczym innym jak mapą składającą się z nazw funkcji w postaci kluczy :m-plus, :m-zero, :m-bind i :m-result z ich implementacją (jeśli podana na wejściu).

Dobrze byłoby przypisać nazwę takiej strukturze, np. za pomocą (def nazwa (monad ...)).
user=> (def moja-monada (monad 
 [m-result identity
  m-bind (fn [mv f] (f mv))
  ]))
#'user/moja-monada
user=> moja-monada
{:m-plus :clojure.contrib.monads/undefined, :m-zero :clojure.contrib.monads/undefined, :m-bind #<user$fn__923$m_bind__924 user$fn__923$m_bind__924@54c707c1>, :m-result #<core$identity clojure.core$identity@20773d03>}
user=> (type moja-monada)
clojure.lang.PersistentArrayMap
c.c.monads dostarcza już takiego makro - defmonad.
user=> (doc defmonad)
-------------------------
clojure.contrib.monads/defmonad
([name doc-string operations] [name operations])
Macro
  Define a named monad by defining the monad operations. The definitions
    are written like bindings to the monad operations m-bind and
    m-result (required) and m-zero and m-plus (optional).
nil
user=> (defmonad moja-monada-2 
 [m-result identity
  m-bind (fn [mv f] (f mv))
  ])
#'user/moja-monada-2
user=> moja-monada-2
{:m-plus :clojure.contrib.monads/undefined, :m-zero :clojure.contrib.monads/undefined, :m-bind #<user$fn__927$m_bind__928 user$fn__927$m_bind__928@67b14530>, :m-result #<core$identity clojure.core$identity@20773d03>}

Makro with-monad

Kolejnym makro w c.c.monads jest with-monad. Dzięki niemu operacja monadyczna zostaje związana z konkretną implementacją w danej monadzie.

Weźmy za przykład monady: maybe-m, sequence-m oraz state-m. Każda z nich musi dostarczać dwie metody - m-bind oraz m-result. Każda z nich musi działać na z góry ustalonej strukturze obliczeniowej. Zobaczmy.
user=> (with-monad maybe-m (m-result 1))
1
user=> (with-monad sequence-m (m-result 1))
(1)
user=> (with-monad state-m (m-result 1))
#<monads$fn__774$m_result_state__775$fn__776 clojure.contrib.monads$fn__774$m_result_state__775$fn__776@65cb048e>
W przypadku funkcji m-result jej wynikiem jest zwrócenie wartości monadycznej dla podanej na wejściu - dla maybe-m będzie to po prostu podana wartość, sequence-m zwróci listę jednoelementową z podaną wartością, a state-m zwróci funkcję, która na wejściu wymaga podania stanu (środowiska, w którym będzie działało ciało funkcji "stanowej") i w wyniku jej wykonania dostaniemy parę - wartość, która została podana na wejściu m-result oraz aktualny stan (nim może być cokolwiek i najczęściej jest kolejna mapa z przypisaniami symbol - wartość, jak zmienne w Javie). Sprawdźmy.
user=> (def f-stanowa (with-monad state-m (m-result 1)))
#'user/f-stanowa
user=> (f-stanowa 5)
[1 5]
user=> (f-stanowa {:a 5 :b 7})
[1 {:a 5, :b 7}]
I teraz najlepsze: gdyby sobie wyobrazić (a może po prostu przypomnieć), że każdy program (w dowolnym języku) wykonuje się na pewnym stanie, który moglibyśmy reprezentować jako mapę - zmienna-wartość, to z monadą state-m możemy wykonać program napisany w języku funkcyjnym bez pojęcia stanu, emulując stan monadą. Tworzymy środowisko - stan początkowy - i każde wykonanie funkcji w jego ramach będzie dotyczyło jedynie tego stanu. Zamiast przekazywać stan z funkcji do funkcji (przez ich szeregowanie) można skorzystać z monady state-m i zjąć sobie ten kłopot z barków, wykonując funkcje tak, jakby ten stan po prostu był. Zdecydowanie upraszcza testowanie i zrównoleglanie obliczeń, bo zakłada się, że funkcje nie mają skutków ubocznych i działają w zamkniętej przestrzeni. To było dla mnie niezwykle odkrywcze w swojej prostocie.

Wystarczy tych pieśni na dzisiaj. Jutro kolejna porcja moich znalezisk monadycznych. Pytania i uwagi mile widziane. Jako podsumowanie można oczekiwać prezentacji na Warszawa JUG. Ach, następne będzie 9. listopada z Cezarym Bartoszukiem, który przedstawi temat "Przegląd języków programowania i ich funkcjonalności".

27 października 2010

Geronimo, JMX i Groovy

3 komentarzy
Apache GeronimoDostałem zadanie rozpracowania dostępnych obiektów Java Management Extension (JMX) - MBeans - w serwerze aplikacyjnym Apache Geronimo. Osoba zlecająca potrzebowała monitorować Geronimo i kiedy dowiedziałem się o tym, od razu zaproponowałem wykorzystanie JMX. W końcu, po to ta technologia została stworzona.

I przyszło mi stworzyć klienta ("Trzeba było się nie wychylać", ktoś mógłby krzyknąć).

Przeglądając różne materiały dotyczące JMX API, brakowało mi spójnego przykładu. Natchnęło mnie, aby napisać własnego. Chwila namysłu i padło na...Groovy. W końcu do tego typu zadań świetnie się nadaje.

(Gdyby nie fakt, że poszukiwanie rozwiązania trwało i musiałem sobie przypomnieć programowanie w Groovy, zacząłbym od...) Po chwili miałem działające rozwiązanie w groovysh.
import javax.management.ObjectName
import javax.management.remote.JMXConnectorFactory as JmxFactory
import javax.management.remote.JMXConnector as JmxConn
import javax.management.remote.JMXServiceURL as JmxUrl

serverUrl = 'service:jmx:rmi://localhost/jndi/rmi://localhost:1099/JMXConnector'

url = new JmxUrl(serverUrl)
creds = ["system", "manager"] as String[]
env = ["jmx.remote.credentials":creds]
jmxc = JmxFactory.connect(url, env)

server = jmxc.MBeanServerConnection;

for (d in server.domains) { println d }

mbeanName = "geronimo:J2EEServer=geronimo,name=JVM,j2eeType=JVM"
mbean = new ObjectName(mbeanName)

println server.getAttribute(mbean, "kernelBootTime")

jmxc.close();
Trzeba jeszcze skrypcik lekko podrasować, aby użyć produkcyjnie, ale ogólny zarys już jest. Usprawnienia mile widziane.

Mam nieodparte wrażenie, że zastosowałem właściwe narzędzie do problemu. A jak Ty podszedłbyś/podeszłabyś do tematu?

p.s. Podczas rozpoczęcia konferencji warsjawa 2010 pozwoliłem sobie zrobić dygresję, taki drobny żarcik, odnośnie kobiet na sali, kiedy to na moje pytanie - już nie pamiętam jakie - padła odpowiedź damskim głosem. Natychmiast przypomniałem sobie skecz z Monty Pythona - Stoning i ledwo udało mi się utrzymać powagę. Skecz bajka! Że też zawsze musi mnie "natchnąć" w trakcie publicznych wystąpień (!)

26 października 2010

Krótko o clojure.test

3 komentarzy
Logo ClojureZaczęło się od lektury Testing Clojure Code – Awesome “are”. Przypomniałem sobie, że jednym z pytań w trakcie mojego wykładu o Clojure podczas 70. spotkaniu Warszawa JUG było "Jak testować kod napisany w Clojure?" Wiemy, że Clojure kompilowany jest do bajtkodu, więc to, testujemy w Javie jest do wykorzystania z Clojure.

Jednak dla mnie pytanie wskazywało raczej potrzebę zrozumienia, jak to jest testować aplikacje Clojure w Clojure. Trafiłem na clojure.contrib.test-is, gdzie znalazłem informację, że teraz Clojure oferuje clojure.test.

Sprawdźmy, jak to działa. Krótko.
devmac:~ jacek$ clj
Clojure 1.2.0
user=> (use 'clojure.test)
nil
user=> ; Czy 5 == 4?
user=> (is (= 5 (+ 2 2)))

FAIL in clojure.lang.PersistentList$EmptyList@1 (NO_SOURCE_FILE:5)
expected: (= 5 (+ 2 2))
  actual: (not (= 5 4))
false
user=> ; Test mianowany "Crazy arithmetic"
user=> (is (= 5 (+ 2 2)) "Crazy arithmetic")

FAIL in clojure.lang.PersistentList$EmptyList@1 (NO_SOURCE_FILE:6)
Crazy arithmetic
expected: (= 5 (+ 2 2))
  actual: (not (= 5 4))
false
user=> ; Można również definiować zestawy testowe makrem deftest
user=> (deftest addition
  (is (= 4 (+ 2 2)))
  (is (= 7 (+ 3 4))))
#'user/addition
user=> ; ...i je uruchamiać funkcją run-tests
user=> (run-tests)

Testing user

Ran 1 tests containing 2 assertions.
0 failures, 0 errors.
{:type :summary, :test 1, :pass 2, :fail 0, :error 0}
Można też uruchomić testy z innej przestrzeni nazewniczej (aka pakietach w Clojure). W ten sposób oddzielamy sam test od testowanego kodu.
user=> ; Definiujemy nową przestrzeń testy
user=> (ns testy)
nil
testy=> (use 'clojure.test)
nil
testy=> ; W niej definiujemy zestaw testowy makrem deftest
testy=> (deftest addition
  (is (= 7 (+ 3 4))))
#'testy/addition
testy=> ; Zmieniamy aktualną przestrzeń
testy=> (ns user)
nil
user=> ; Wykonujemy testy z innej przestrzeni
user=> (run-tests 'testy)

Testing testy

Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
{:type :summary, :test 1, :pass 1, :fail 0, :error 0}
p.s. Wczoraj wyszła wersja Clojure 1.3 Alpha 2, ale poza tym, że jest i podobno jest ciekawa, nic więcej :)

23 października 2010

warsjawa 2010 za nami - o Javarsovii 2011 już myślimy

3 komentarzy
Przygotowania do konferencji warsjawa 2010 trwały około 3 tygodnie. Wśród organizatorów znalazły się następujące osoby: Bartek Zdanowski, Marcin Zajączkowski, Łukasz Lenart oraz Jacek Laskowski. Każdy zabrał się za swoją działkę, ale i tak większość decyzji podejmowana była wspólnie (zdaje się, że mimo pełnej samodzielności, każdy z nas czuł się w obowiązku zrelacjonować postępy, aby pozostali mogli śmiało powiedzieć, że wiedzą, co się chociażby ogólnie dzieje).

Uruchomienie rejestracji uzmysłowiło nam, że istnieje niemałe zapotrzebowanie na tego typu inicjatywy. Po kilku dniach "dobiliśmy" do poziomu konferencji z 214 zarejestrowanymi uczestnikami. To przerosło szacunki każdego z nas, organizatorów. Kiedy pomyślę sobie, że początkowo planowałem warsjawę na poziomie 100 osób, a 150 traktowałem jako marzenie, a nie cel, pojawia mi się lekkie powątpiewanie w możliwości mojego szacowania możliwości "objętościowych" na przyszłoroczną Javarsovię 2011. Aż strach pomyśleć, o jakich liczbach możemy myśleć w aspekcie uczestników oraz sponsorów i ich wsparcia finansowego.

A skoro o tym, to warsjawa 2010 uzmysłowiła mi rosnące poparcie firm informatycznych dla inicjatyw Warszawa JUG. Jeszcze przy Javarsovia 2010, to my odpytywaliśmy sponsorów o udział w konferencji. Tym razem było zauważalnie inaczej. Wielu ze sponsorów kontaktowało się z nami. Najpierw Altkom, później SoftwareMill, Pragmatists, CoCoNet, Accenture i ej-technologies. MIMUW jako patron użyczył nam swoich sal, co na samym początku zagwarantowało sukces przedsięwzięcia. Rozmowa ze sponsorami zwykle kończyła się przy pierwszej iteracji, gdzie padały nasze możliwości i potrzeby, a sponsor przystawał na nie. Bajka.

Tym samym chciałbym podziękować wszystkim sponsorom za ich udział w warsjawie 2010. Bez Was nie byłoby takiej oprawy konferencyjnej.

Konferencja zaczęła się wystąpieniem Wojtka Erbetowskiego, później wystąpił Paweł Lipiński, Dariusz Łuksza, Marcin Rzewucki z Janem Rychterem, Adam Michalik i Rafał Rusin. Z każdej prezentacji wyniosłem coś wartościowego - czy to ze względu na sposób prezentacji (tutaj moim faworytem stał się Jan Rychter z 30-minutowym przedstawieniem Clojure okiem praktyka!) oraz merytorycznie (tutaj wskazałbym na wstęp Darka Łukszy o EGicie oraz prezentacja Adama Michalika z bajtkodem). Szkoda jeszcze, że tak niewielu z nas czuje potrzebę podzielenia się swoimi doświadczeniami zawodowymi podczas konferencji. Pamiętam, że wcale nie było pewne, czy uda nam się ostatecznie zebrać 6 prelegentów. Doświadczenie prezenterskie to umiejętność, którą idzie wyćwiczyć, ale jak ze wszystkim, trzeba próbować i "platforma" Warszawa JUG jest doskonałym miejscem. Za 1,5 tygodnia kolejne spotkanie i wystarczy się zgłosić w roli prelegenta. Ot, takie to proste.

W trakcie prezentacji, szczęśliwa 30-tka miała możliwość uczestniczenia w szkoleniu z pisania wtyczek do Eclipse, prowadzonym przez Krzysztofa Daniela z poznańskiego IBM Eclipse Support Center. Udało mi się jedynie posłuchać początku i odniosłem wrażenie, że będzie słodko (dosłownie w postaci rozdawanych batonów jako nagroda za poprawną odpowiedź i w przenośni).

Uczestnicy nie zawiedli. Już od rana można było mówić o około 100 uczestnikach i widać było żywo prowadzone dyskusje. Miałem okazję porozmawiać z osobami ze Szczecina, Lublina, Krakowa, Radomia, Płocka i oczywiście Warszawy (ciekawym, jakiego miasta nie wymieniłem?!) U wszystkich zauważyć można było chęć organizowania spotkań, czy to w ramach JUGów, czy konferencji. Chętnie pomogę i wystarczy zapytać, aby dowiedzieć się, że można, nie jest to specjalnie trudne i choćby 30 osób jest warte wysiłku. Kluczem do sukcesu jest wiara w powodzenie przedsięwzięcia, a jedynie rozmiary mogą deprymować, co zdecydowanie nie powinno być przeszkodą, aby w ogóle podjąć się wysiłku. Warto, bo w krótkim czasie można dowiedzieć się więcej niż samodzielnie rozpracowując temat, a kontakty towarzystkie nie dadzą się zastąpić nawet najlepiej napisanym CV, kiedy potrzeba zmienić pracę i zaczepić się w ciekawym zespole. Później, na swoim, podobno są one wręcz niezbędne.

Na koniec konferencji rozlosowano nagrodę w postaci PlayStation3. Gratuluję wygranemu, tym bardziej, że samemu ostrzyłem sobie zęby na niego. Następnym razem.

Później, w ponad 10-osobowej grupie spotkaliśmy się w Jeff'sie. Jedzenie dobre, atmosfera pozytywna, więc można liczyć, że to nie ostatnia inicjatywa Warszawa JUG. Miło się móc spotkać bezpośrednio i omówić różne sprawy (niekoniecznie informatyczne, aczkolwiek te wyraźne nadawały ton).

Na minus konferencji trafiają niewystarczająca ilość napojów, szczególnie po pizzy oraz projektor o niskiej rozdzielczości. Nad obiema sprawami należy się pochylić przy kolejnych konferencjach, jeśli mają być zauważalnie lepsze od poprzednich.

Nagrania są i czekają na obróbkę. Wierzę, że szybko pojawią się na parleys. Kiedy? Hmmm, tego nawet najstarsi górale nie wiedzą.

Do zobaczenia na spotkaniach Warszawa JUG i Javarsovia 2011.

Relacje uczestników warsjawa 2010:

20 października 2010

Wrażenia z 70. spotkania WJUG - Clojure i ja w akcji...zaginęliśmy?

2 komentarzy
To była dopiero przeprawa - droga przez męki dla słuchających mojego wystąpienia podczas 70. spotkania Warszawa JUG.

Zaczęliśmy około 18:10 z projektorem, który komunikatem o swojej niedyspozycji (coś związanego z wentylatorem, czy innym swoim podzespołem) zajął połowę wyświetlanego slajdu, centralnie. Próbowałem udać, że nie powinno popsuć nam to spotkania.

Pamiętając moje dokonania na polu utrzymania czasu prezentacji i że wielu przykłada do tego równie wielką wagę, jak do strony merytorycznej, poprosiłem uczestników, abyśmy równo o 19:30 zakończyli spotkanie. Od tej godziny, wyjście z sali nie mogło być okraszone złowrogim spojrzeniem prowadzącego. Takie ukonstytuowaliśmy prawo. Bez względu na miejsce w mojej prezentacji, 19:30 stała się godziną graniczną chyba, że znajdą się tacy, którzy poproszą o więcej. I tacy się znaleźli! Wtedy się dopiero zaczęło bezpardonowe zmaganie z czasem. Skończyliśmy o 21:15 w sali, w gronie około 15 osób , aby kończąc dyskusje przy wejściu - tym razem już w gronie 7 osób - zakończyć całość około 21:45. W domu pojawiłem się po 22:00 (!)

Gdyby tylko liczba uczestników, dyskusje i poszczególne czasy na odcinkach - właściwa prezentacja, dyskusje po, w sali i przy wejściu, miały być wyznacznikiem sukcesu, powiedziałbym, że był ogromny. Zawsze uważam z przymiotnikami, które podobnie jak gusta, mają różne zabarwienia dla różnych ludzi, ale tym razem nic poza "ogromny" nie przychodzi mi do głowy.

Merytorycznie? Cóż, mogło być lepiej. Z mojego "prezenterskiego" punktu widzenia nie popisałem się. To znaczy, popisałem się, ale niewiedzą, a to zdecydowanie nie było tematem spotkania. O Clojure było conieco, może trochę więcej o samym programowaniu funkcyjnym i w zdecydowanej przewadze wiele o (bez?)sensowności użycia Clojure w projektach, które obecnie są przez nas obsługiwane Javą.

Tutaj sypiąc głowę popiołem, kajam się przed uczestnikami, prosząc o wybaczenie, że dałem się ponieść próbie porównywania Clojure do Javy, kiedy wcale nie byłem do tego przygotowany, a w dodatku, wcale nie miałem zamiaru tego robić (!) Języka Java zacząłem uczyć się w czasach appletów, kiedy to one były jedynym sposobem, aby ożywić strony HTMLowe. To była era wszechobecnego CGI z perlem i znajomość rozwiązania tego akronimu albo umiejętność wyjaśnienia, o co w nim chodzi znaczyły wiele (coś, co teraz porównałbym do Java EE i zasad rządzących serwerami aplikacyjnymi). Java z appletami była czymś praktycznym i w zasadzie nie było innego wyboru. Obecnie nie ma tego luksusu - nie tylko, że wybór jest między .Net a Java EE, ale mnogość rozwiązań w samej Javie - czy to języki programowania (ale tutaj można założyć, że zaleca się Javę), czy szkieletów aplikacyjnych - może przyprawić o ból głowy. Jest zauważalnie trudniej wejść nowicjuszowi w świat języka Java i Java EE. I gdzie tu miejsce dla poznawania programowania funkcyjnego i to jeszcze w wykonaniu Clojure. Ma to jakiś sens?

To nie było pytanie, na które zamierzałem odpowiedzieć i nie odpowiedziałem.

Tematem mojej prezentacji był "Wstęp do programowania funkcyjnego z Clojure". Podkreślam słowo "wstęp" i rezerwowałem sobie wręcz rozumienie go jako "wstęp do wstępu". Raczej służyło to zebraniu postrzegania nauki innego paradygmatu programowania niż imperatywno-obiektowy w wykonaniu Javy. Postarałem się o wdrożenie podejścia "Release early, release often", z tym, że tym razem chodziło nie o namacalny produkt, a wiedzę.

Jakkolwiek moja strona prezentacyjna szwankowała, to uważam, że strona przeciwna (w sensie analogicznym do pary lewa-prawa a nie za-przeciw), czyli słuchacze, spisała się wyśmienicie. Na sali znalazło się 5 osób, które na pytanie "Czy programujesz w języku funkcyjnym?" odpowiedziały "Tak" - dwie czysto hobbistycznie, jedna programująca w Clojure w Fablo.pl, inna, która właśnie przeszła (jak to ujęła) z "naukowego" Haskella na bardziej finansowo-zorientowaną Scalę i ostatnia, która swoją przygodę z programowaniem zaczęła od programowania funkcyjnego i, jak się okazało później, zna około 30 języków programowania z Javą okrzykniętą jako ten język, który nie tylko, że ma się dobrze, ale będzie wiodącym przed długie lata. Pozostała, bodajże 35-cioosobowa, grupa to programiści Java, którzy albo mieli zajęcia z programowania funkcyjnego na studiach, albo przymierzają się do języka Scala, albo kto wie, co w pozostałych głowach siedzi.

Rozmawialiśmy o wsparciu IDE dla programowania funkcyjnego w dowolnym języku - przewijał się Groovy, Scala i Clojure, naprzemiennie. I można było zauważyć ogólnie panujące przekonanie, że brak wsparcia IDE w postaci podpowiedzi, refactoringu, przeglądania hierarchii klas w górę/dół, przeskakiwania między wywołaniem funkcji, a jej definicją, w zasadzie skreśla język jako możliwy do zastosowania w projekcie komercyjnym, w którym "więcej się czyta kod niż pisze". Tego nie brałem wcześniej pod uwagę, a to kładę na karb mojego, niewielkiego udziału w projektach programistycznych. Pojawiła się teza, że przy pewnej skali projektu, można przyjąć sensowność użycia dynamicznie-typowanego języka zamiast Javy, powiedzmy przy 100k linii kodu (wartość wyjęta z kapelusza, ale ma być dostatecznie mała, aby dało się to ogarnąć). Mieszanie składniowe języków na JVM, np. Java i Clojure, w projekcie nie zdobyło entuzjazmu, przede wszystkim dlatego, że późniejsze utrzymanie może znacząco podnieść koszty. Sensowne rozumowanie, z którym trudno się nie zgodzić.

Zaprezentowałem Clojure z mojego, javowego punktu widzenia, który pozwala mi tworzyć rozwiązania Java EE z aplikacjami webowymi w roli głównej. Tutaj Java ma się świetnie i jakkolwiek mamy do dyspozycji Grails z Groovy, Lift ze Scala, Ruby on Rails z JRuby, to nie zauważyłem akceptacji wśród uczestników dla ich powszechnego stosowania, przede wszystkim z powodu obecnego stanu wsparcia narzędziowego i późniejszego utrzymywania mieszanki składniowej Java-nieJava. Uknęliśmy wręcz termin "podejście dogmatyczne", któremu przyświeca minimalizowanie języków na JVM ze wskazaniem na Javę.

Gdybym ja był słuchaczem, nie dostrzegłbym sensu nauki programowania funkcyjnego, a już tym bardziej Clojure.

Podczas mojego wystąpienia o Clojure nie pokazałem niestety nic, co nie byłoby możliwe w Javie i Java EE, a biorąc wsparcie narzędziowe i ogólny stan świadomości programistycznej o nich, to, wespół z moim prawie zerowym teoretycznym, a zerowym, praktycznym doświadczeniem, takie podejście nie miało racji zaistnienia. Za dużo jeszcze we mnie myślenia javowego, a za mało Clojure i PF. Kiedy dodać do tego brak prezentacji chociażby Clojure STM i tak podkreślanej prostoty zrównoleglania zadań w językach funkcyjnych, rozumowanie, że da się zrobić w Clojure, to, co potrafimy i robimy na codzień w Javie jest dalece niewystarczająca. Jest niewystarczające również, aby myśleć o nauce, której nie towarzyszy przeświadczenie, albo chociaż nadzieja na możliwe, przyszłe użycie praktyczne. Pełna zgoda i tutaj upatruję swoje braki. Chociażby Clojure STM jest rozwiązaniem do użycia z poziomu Javy, jako biblioteka i tu właśnie widziałbym sens prezentacji Clojure jako wzbogacenia naszego przybornika programisty. To da się użyć natychmiast. Później dopiero widziałbym ewangelizację Clojure przez pryzmat zrównoleglania, a w kolejnych odsłonach i tylko przy założeniu, że poprzednie są zrozumiałe, a być może i wykorzystywane, wchodziłbym w temat innej składni i samego programowania funkcyjnego w ogólności. To jest moja nauka na przyszłość, która wyznacza dalsze kierunki rozwoju w Clojure.

Z pozostałych tematów, które uczestnicy wyrazili jako wartościowe do pokazania w ramach naszych spotkań Warszawa JUG pojawiły się: testowanie, refactoring, wykorzystanie skryptu jako klasy, jak efektywny jest bajtkod Clojure, monady z przykładami, TCO w rekurencjach na przykładzie chociażby ciągu Fibonacciego i równoległe rysowanie kółek. Ze swej strony dodam do tego: demonstracja siły przeładowywania definicji funkcji w locie, w trakcie tworzenia oprogramowania, bez konieczności restartu środowiska uruchomieniowego oraz możliwość poznawania API Javy z użyciem Clojure REPL.

Tym samym chciałbym podziękować wszystkim uczestnikom za udział w mojej prezentacji Clojure i towarzyszące temu, niezwykle inspirujące dyskusje. Dziękuję również za cierpliwość podczas lektury tego wpisu. Ryzykuję, że zabrzmię banalnie, ale współpraca z Wami to czysta przyjemność dająca mi wiele satysfakcji. Pewnie już zwyczajowo, ale wciąż z serca, wszystkim życzę podobnych doznań.

Prezentacja dostępna jest do pobrania jako JacekLaskowski-WJUG-Wstep-PF-Clojure-19.10.2010.pdf.

Jeśli przychodzi Wam do głowy temat warty omówienia podczas spotkań JUGowych, piszcie. Ustawiam się w roli zdającego relację z postępu moich prac podczas kolejnych spotkań. Wy przywdziewacie szaty zlecających i jednocześnie egzaminujących wyniki. Czyż to nie idealny sposób na naukę dla obu stron?! "Ucząc się uczę", albo "Ucząc uczę się". Nie wierzę, że nie znajdzie się ochotnik, aby skorzystać z oferty.

Kolejne spotkanie za 2 tygodnie. Chętni? W przypadku braku, zakładam, że oddaje mi się pola na rzecz dalszego przedstawiania wad i zalet programowania funkcyjnego z Clojure. Z góry dziękuję i rezerwuję sobie prawo, do skorzystania jedynie w ostateczności.

p.s. Do warsjawy 2010 pozostały 3 dni. Do tej pory zarejestrowało się już ponad 150 osób (dokładnie 151 - stan na godzinę 11:00)! Skala zainteresowania sobotnią konferencją przeszła najśmielsze oczekiwania organizatorów. Niech będzie ona równie wartościowa dla prelegentów, jak moje wczorajsze wystąpienie dla mnie, a uczestników proszę o podobny poziom aktywności. Parafrazując słowa Owsiaka "Oj, będzie się działo!"