wtorek, 12 maja 2009

Hibernate i Spring DM Server

Spring Dm Server w wersji 1.0 odpaliłem już prawie rok temu. Udało mi się odpalić aplikację web, która pod spodem korzysta z Hibernate. Nie ukrywam, że nie poszło to gładko, ale w końcu się udało. Niestety rok po tym, chciałem pobawić się jeszcze raz, tym razem pod STS 2.0, cała wiedza wyparowała i musiałem jeszcze raz się przebijac i oglądać wyjątki w stylu java.lang.NoClassDefFoundError. W końcu zdecydowałem się to spisać, aby w przyszłości zaoszczędzic sobie ponownej straty czasu.
Aplikacja składa się z następujących projektów:
  • web - Spring DM web bundle
  • domain - obiekty domeny wykorzystywane przez moduł web oraz moduł api, korzysta z hsqlbd oraz commons dbcp
  • api - definiuje interfejs- kontrakt między warstwą web a warstwą dao
  • dao - implementuję interfejs zdefiniowany przez moduł api, dostarcza implementacji usługi OSGI

  1. No PAR deployment- aplikacja składa się z luźno wrzucanych bundli.
    • konfiguracja ORM określona za pomocą annotacji JPA (AnnotationSessionFactoryBean):
      • dao
        Manifest-Version: 1.0
        Bundle-Version: 1.0.0
        Bundle-Name: HibernateTest_dao Bundle
        Bundle-ManifestVersion: 2
        Bundle-SymbolicName: foo.bar.HibernateTest_dao
        Import-Package: foo.bar.dao.api,
        foo.bar.domain,
        javax.sql;version="[0.0.0,0.0.0]"
        Import-Bundle: com.springsource.org.apache.commons.dbcp,
        com.springsource.org.hsqldb,
        com.springsource.org.hibernate;version="[3.2.6.ga,3.2.6.ga]"
        Import-Library: org.springframework.spring.instrumented
        jak się można było spodziewać, importujemy bundle Hibernate

      • domain
        Manifest-Version: 1.0
        Bundle-Version: 1.0.0
        Bundle-Name: HibernateTest_domain Bundle
        Bundle-ManifestVersion: 2
        Bundle-SymbolicName: foo.bar.HibernateTest_domain
        Export-Package: foo.bar.domain;version="1.0.0"
        Import-Bundle: com.springsource.javax.persistence;version="[1.0.0,1.0.0]",
        com.springsource.org.hibernate;version="[3.2.6.ga,3.2.6.ga]"

        pomimo, że nie używamy annotacji Hibernate (a jedynie JPA) bundle Hibernate musi zostac zaimportowany - w przeciwnym przypadku przy starcie bundle dao dostaniemy wyjątek: java.lang.NoClassDefFoundError: org/hibernate/proxy/HibernateProxy

    • konfiguracja ORM określona w plikach konfiguracyjnych xml (LocalSessionFactoryBean):
      • dao
        Manifest-Version: 1.0
        Bundle-Version: 1.0.0
        Bundle-Name: HibernateTest_dao Bundle
        Bundle-ManifestVersion: 2
        Bundle-SymbolicName: foo.bar.HibernateTest_dao
        Import-Package: foo.bar.dao.api,
        foo.bar.domain,
        javax.sql;version="[0.0.0,0.0.0]"
        Import-Bundle: com.springsource.org.apache.commons.dbcp,
        com.springsource.org.hsqldb,
        com.springsource.org.hibernate;version="[3.2.6.ga,3.2.6.ga]"
        Import-Library: org.springframework.spring.instrumented
        bez zmian
      • domain
        Manifest-Version: 1.0
        Bundle-Version: 1.0.0
        Bundle-Name: HibernateTest_domain Bundle
        Bundle-ManifestVersion: 2
        Bundle-SymbolicName: foo.bar.HibernateTest_domain
        Export-Package: foo.bar.domain;version="1.0.0"
        tym razem bundle domain nie potrzebuje żadnego importu: ani JPA ani Hibernate

    Aby moc korzystać z HQL to dla No-PAR deployment wymagane jest zaimportowanie Hibernate dla bundle web.
    Manifest-Version: 1.0
    Web-DispatcherServletUrlPatterns: *.html
    Module-Type: Web
    Bundle-Version: 1.0.0
    Bundle-Name: HibernateTest_web Bundle
    Bundle-ManifestVersion: 2
    Web-ContextPath: HibernateTest
    Bundle-SymbolicName: foo.bar.HibernateTest_web
    Import-Package: foo.bar.dao.api,
    foo.bar.domain;version="[1.0.0,1.0.0]"
    Import-Bundle: com.springsource.org.apache.taglibs.standard;version="[1.1.2,1.1.2]",
    com.springsource.org.hibernate;version="[3.2.6.ga,3.2.6.ga]"
    Import-Library: org.springframework.spring.instrumented

    W innym przypadku, przy próbie wykonania zapytania HQL zobaczymy: org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken. Hibernate ładuję cześć klas za pomocą Thread context classloadera, czyli w naszym przypadku za pomocą ClassLoadera, który załadował moduł web. Najciekawsze jest to, że zapytania korzystające z Criteria API, operacje get/load działają bez tego importu. Jest on jedna wymagany do odpalania zapytań w HQL.

  2. PAR deployment - nasze bundle zostają zapakowane w archiwum PAR
    • konfiguracja ORM określona za pomocą annotacji JPA (AnnotationSessionFactoryBean):
      • dao
        Manifest-Version: 1.0
        Bundle-Version: 1.0.0
        Bundle-Name: HibernateTest_dao Bundle
        Bundle-ManifestVersion: 2
        Bundle-SymbolicName: foo.bar.HibernateTest_dao
        Import-Package: foo.bar.dao.api,
        foo.bar.domain,
        javax.sql;version="[0.0.0,0.0.0]"
        Import-Bundle: com.springsource.org.apache.commons.dbcp,
        com.springsource.org.hsqldb,
        com.springsource.org.hibernate;version="[3.2.6.ga,3.2.6.ga]";import-scope:=application
        Import-Library: org.springframework.spring.instrumented
        tym razem importujemy bundle Hibernate z dodatkowym atrybutem import-scope:=application, który jest pewnym rozszerzeniem Spring DM Server

      • domain
        Manifest-Version: 1.0
        Bundle-Version: 1.0.0
        Bundle-Name: HibernateTest_domain Bundle
        Bundle-ManifestVersion: 2
        Bundle-SymbolicName: foo.bar.HibernateTest_domain
        Export-Package: foo.bar.domain;version="1.0.0"
        Import-Bundle: com.springsource.javax.persistence;version="[1.0.0,1.0.0]"

        używamy jedynie annotacji JPA, nie musimy importować bundle Hibernate

    • konfiguracja ORM określona w plikach konfiguracyjnych xml (LocalSessionFactoryBean):
      • dao
        Manifest-Version: 1.0
        Bundle-Version: 1.0.0
        Bundle-Name: HibernateTest_dao Bundle
        Bundle-ManifestVersion: 2
        Bundle-SymbolicName: foo.bar.HibernateTest_dao
        Import-Package: foo.bar.dao.api,
        foo.bar.domain,
        javax.sql;version="[0.0.0,0.0.0]"
        Import-Bundle: com.springsource.org.apache.commons.dbcp,
        com.springsource.org.hsqldb,
        com.springsource.org.hibernate;version="[3.2.6.ga,3.2.6.ga]";import-scope:=application
        Import-Library: org.springframework.spring.instrumented
        bez zmian
      • domain

        Manifest-Version: 1.0
        Bundle-Version: 1.0.0
        Bundle-Name: HibernateTest_domain Bundle
        Bundle-ManifestVersion: 2
        Bundle-SymbolicName: foo.bar.HibernateTest_domain
        Export-Package: foo.bar.domain;version="1.0.0"
        skoro tym razem nie używamy JPA to nie potrzebujemy importu bundle JPA

    Tym razem do bundle web nie musimy importować bundle Hibernate aby móc korzystać z HQL

    Manifest-Version: 1.0
    Web-DispatcherServletUrlPatterns: *.html
    Module-Type: Web
    Bundle-Version: 1.0.0
    Bundle-Name: HibernateTest_web Bundle
    Bundle-ManifestVersion: 2
    Web-ContextPath: HibernateTest
    Bundle-SymbolicName: foo.bar.HibernateTest_web
    Import-Package: foo.bar.dao.api,
    foo.bar.domain;version="[1.0.0,1.0.0]"
    Import-Bundle: com.springsource.org.apache.taglibs.standard;version="[1.1.2,1.1.2]"
    Import-Library: org.springframework.spring.instrumented

    Dzięki importowaniu bundle Hibernate z atrybutem import-scope:=application nie ma potrzeby importowania Hibernate ani w bundle web ani w bundle domain. Po podłączeniu się za pomocą telnet do konsoli Equinox możemy wyświetlić nagłówki bundli wchodzące w skład naszego PAR, w ten sposób zobaczymy że, każdy z nich "automagicznie" importuje pakiety Hibernate.

GeeCon dzień 2

Java FX For Developers Not Designers
Poprzedniego wieczora staraliśmy się trochę zintegrować i chyba dlatego prezentacja Adam Biena nie zbyt zapadła mi w pamięć. Z tego co pamiętam to zaczęło się od omówień zmian w JRE: JRE kernel, lepsza komunikacja na linii JavaScript-Applet, możliwość wyspecyfikowania per-applet wymagań co do pamięci, specyfikowanie per-applet wymagań co do wersji JRE. Następnie Adam przeszedł do JavaFX. Było to mniej więcej wszystko to samo co na pozostałych prezentacjach na ten temat. Jedyne co mnie "obudziło" to pisanie testów JUnit w JavaFX. Pojawiło się pytanie czy można to robić w stylu JUnit 4.X, czyli za pomocą annotacji. Odpowiedz było prosta: można użyć JUnit w wersji 4.X, ale nie można korzystać z annotacji, ponieważ JavaFX nie wspiera annotacji!.

RESTful Web Services with Spring 3.0
Znużony trochę prezentacją na temat JavaFX na drugie pół godziny przeniosłem się do sali obok aby posłuchać Arjena Poutsmy. Było to praktycznie to samo co Arjen zaprezentował jakiś czas temu w Warszawie. Arjen oprócz tego, starał się wytłumaczyć czym Spring Framework REST support różni się od implementacji JAX-RS: ten pierwszy dotyczy interfejsu human to machine a ten drugi machine to machine. Fuknkcjonalności w stylu: filtr, który obchodzi ograniczenie przeglądarki do wysyłania jesdynie żądan POST i GET, używanie file extensions w celu określenia żądanej reprezentacji (kolejne obejście przeglądarki) mają ułatwić tworzenie aplikacji zgodnych z paradygmatem REST. Jednak jak to później Arjen w rozmowie uściślił @MVC/@REST ma duże zastosowanie dla web development, a JAX-RS dla RESTful services, czyli ma stanowić konkurencje dla SOAP WebServices. Arjen wspomniał także o RestTemplate czyli o REST po stronie klienta. Na koniec pojawiło się pytanie związane z security w świecie REST. Po stronie serwera nic się nie zmienia i standardowo używać form-based authentication oraz SpringSecurity(jest w stanie sprawdzać prawo do wywołania zasobu także na podstawie użytej metody HTTP), a dla RestTemplate używać basic/digest authentication i przesyłać nasze credentials przy każdym żądaniu.

Glassfish
Dodatkowa, nieplanowana prezentacja przeprowadzona przez Antonio Goncalves na temat GlassFish. Antonio zaprezentował jak zainstalować, skonfigurować i używać GlassFish. Wyglądało to jako typowy step-by-step turtorial - od pobierania instalki poprzez uruchamiania serwera i jego konfiguracje każdy etap został zaprezentowany z uprzednio przygotowanych filmików flashowych- nic nie miało prawo nie działać :). Filmiki zostały stworzone przez Antonio na podstawie kroków opisanych w GlassFish Quick Start Guides.
Serwer można zainstalować w 3 trybach: "development", "cluster", ""enterprise". Nie obyło się bez pokazania 2 alternatywnych interfejsów dostępu do serwera: Admin Console i asadmin oraz narzędzie (stworzone w swingu) do instalowania/aktualizowania komponentów samego serwera Update Center. Bardzo mi się spodobało, że Antionio miał przygotowane slajdy omawiające architekturę samego serwera i na tej podstawie wyjaśniał poszczególne pojęcia: domain, administration server, node agent, cental repository, cluster, server instance. Na końcu jeszcze krótka informacja na temat Glassfish V3 , jako referencyjnej implementacji JEE6, z modularną architekturą opartą na OSGI. Rozmawiając na temat OSGI w kontekście V3 z Antionio, usłyszałem, że jak na razie nie ma żadnych planów aby serwer mógł hostować aplikację użytkownika oparte na OSGI.

What's new in Java EE 6
Antonio Goncalves tym razem opowiadał na temat JEE6. Same wydanie specyfikacji jest dość mocno opóźnione z tym co pierwotnie zakładano, a dodatkowo wokół paru specyfikacji zrobiło się dość dużo szumu i wiele emocji :). W JEE 6 pewne specyfikacje zostały "wycięte" m.in.: JAX-RPC, EJB 2.1 entity beans, JSR 88, JAXR. Wprowadzono w końcu pojęcie profili, czyli JEE ma przestać być jednym wielkim monolitycznym kolosem w stylu one size fits all. Aktualnie w przygotowaniu są 3 profile, przy czym jakie specyfikacje będą należeć do jakiego profilu jeszcze nie jest w 100 % pewne.
JEE6 wprowadza wiele zmian i to, w każdej warstwie JEE:
  • Servlets 3.0 (annotacje, fragments, możliwośc rejestrowania/odrejestrowywania servletów, przetwarzanie asynchroniczne), JSF 2.0, AJAX support, JSP jako technologia niszowa
  • JAX-WS 2.2, JAX-RS(nie wspiera client-side REST)
  • EJB 3.1(optional local intefaces), @Singleton (per application per JVM), @ConcurrencyManagement, EJB Lite, EJB asynchronous methods ( zwracją null lub Future, domyślnie dla nich Propagation.Requires_NEW), możliwość pakowania EJB w WAR, globalne ( przenośne) nazwy JNDI, Timer Services API( prawie jak Cron), Embeddable EJB Container
  • JPA 2.0 (m.in. mapowanie kolekcji komponentów, rozbudowa JPQL, dodatnie Criteria API, nowe mechanizmy lockowania)
  • Web Beans przemianowane na JDCI
Tak przygotowana specyfikacja ma nawet umożliwiać tworzenie aplikacji batchowych:
Batch processing = EJB Lite + Timer + Asynch calls + Embeddable Container


Automation of functional tests
Tomasza Kaczanowskiego w swojej prezentacji przedstawił nam idee automatyzacji testów funkcjonalnych. W przypadku testów funkcjonalnych pojawia się zawsze problem związany z przygotowaniem środowiska uruchomieniowego dla testów, które powinno jak najbardziej przypominać środowisko produkcyjne. Przygotowanie takiego środowiska oraz mechanizmu automatyzacji testów funkcjonalnych nie zawsze jest łatwe/możliwe do osiągnięcia i często trzeba do tego podejśc pragmatycznie. Tomasz na podstawie własnych doświadczeń przedstawił w jaki sposób przeprowadził automatyczne funkcjonalne testowanie 2 odmiennych systemów: klasyczny system JEE z interfejsem web, system oparty na OSGI z interfejsem SOAP WebSerices. Przygotowanie środowiska dla testów funkcjonalnych zostało rozbite na poszczególne fazy:
  • stworzenie bazy danych -przykładowe narzędzia: hibernate3-maven-plugin, SQL-maven-plugin
  • załadowanie danych - użycie DBUnit (podobno DBUnit ma problemy z ładowaniem duzej ilości kodu napisanego w PL/SQL), SQL-maven-plugin
  • wrzucenia aplikacji - cargo-maven-plugin, capistarano ?
  • uruchomienie testów - selenium-maven-plugin, soapui-maven-plugin
Tomasz ostrzegał, że w/w narzędzia bardzo pomogły mu osiągnąc zamierzony efekt, ale na pewno nie są one "silver bullet" i nie koniecznie muszą działac w innych środowiskach.

SOLID design principles
Super zabawna prezentacja przeprowadzona w typowym włoskim stylu. Prezentacja bazuje na
Object Oriented Design principles zdefiniowanych przez wujka Boba czyli Boba Martina.
Bruno Bussola zaczął od omówienia czemu powinno nam zależeć na posiadaniu "good design" oraz jakie są symptomy, że coś jest nie tak z naszym designem:
  • rigidity - wprowadzenie zmiany jest nieprzewidywalne(bardzo trudne/nie możliwe do oszacowania pod względem czasu i kosztu). Nawet mała zmiana powoduje, że musimy zmieniać coraz to kolejne elementy (change marathon)
  • fragility - wprowadzenie zmiany w jednym elemencie powoduje, że zaczyna "się sypać" w innym teoretycznie nie powiązanym fragmencie
  • immobility - poszczególne elementy są ze sobą tak powiązane, że nie ma szans aby "wyjąc" pojedyńczy element i re-użyć go.
  • viscosity - przy wprowadzeniu zmiany o wiele łatwiej jest napisać "hack"niż zrobić to poprawnie - zgodnie z designem
Jak dobrze wiemy dobry design powinien się cechować przede wszystkim 2 rzeczami: low coupling, high cohession. Oczywiście łatwiej o tym mówić niż zrobić, ale wujek Bob przygotował nam zbiór zasad aby osiągnąć zamierzony cel. SOLID jest to akronim przy czym każda z liter jest pierwszą literą kolejnych akronimów:
  • Single Responsibility Principle - klasa powinna odpowiadać za tylko 1 aspekt(posiadać pojedynczą odpowiedzialność), czyli powinien być tylko pojedynczy powód dla którego mielibyśmy wprowadzać zmiany w klasie. Przykładowo, klasa Employ nie powinna jednocześnie posiadać metod związanych z obliczaniem pensji, persystencją i generowaniem raportu na podstawie danych użytkownika, a interfejs Modem nie powinien posiadać metod związanych z obsługa komunikacji(stop/start) i obsługą komunikatów. Dośc łatwo jest znaleźć klasy, które łamią te zasady: są to zazwyczaj te, które pełnią role facady: *Controller, *Manager
  • Open-Closed Principle: powinniśmy móc dodawać nową funkcjonalność do naszego kodu bez dokonywania zmiany w istniejącym kodzie. W Javie stosunkowo łatwo się implementuję tę zasadę za pomocą polimorfizmu. Oczywiście trzeba starać się/umieć przewidzieć jakie funkcjonalności mogą/mają szansę się zmienić...
  • Liskov Substitution Principle - zasada zastępowania, czyli możliwość przekazania zamiast obiektu danej klasy, obiekt podklasy bez zmieniania żadnych oczekiwanych zachowań. Wszystko to bardzo ładnie przedstawia przykład kwadrat i prostokąt. Czy kwadrat jest prostokątem? Z matematycznego punktu widzenia tak, ale niestety takie myślenie nie jest zgodne z tą zasadą. Prostokąt ma szerokość i wysokość, przy czym obie te wartości są niezależne - możemy zmienić jeden z wymiarów bez zmieniania drugiego z nich. Kwadrat ma tylko 1 wymiar - szerokość, ale skoro widzimy go jako prostokąt to możemy zmieniać jego wysokość i szerokość. Zmiana jakiejkolwiek z tych wartości wpływa bezpośrednio na drugą, czyli łamie kontrakt określony przez prostokąt.
  • Interface Segregation Principle - zasada określająca, że powinniśmy używać interfejsów do definiowania zależności pomiędzy 2 elementami kodu. Jeśli klasa wystawia kilka "grup powiązanych metod", w szczególności gdy każda z tych grup jest wykorzystywana przez innego klienta, zależnośći takie powinno się przedstawić w postaci pojedynczego interfejsu dla każdej z "grup metod"(pojedynczy klient zależy od pojedynczego interefejsu, który enkaspuluje powiązane ze soba metody, a nie od interfejsu zawierającego wszystkie możliwe metody)
  • Dependecy Inversion Principle - Moduły wysokopoziomowe nie powinny zależeć od modułów niskopoziomowych. Obie grupy modułów powinny zależeć od abstrakcji. Abstrakcje nie powinny zależeć od szczegółowych rozwiązań. To szczegółowe rozwiązania powinny zależeć od abstrakcji.

Developing RESTful Web services with Jersey
Prezentacja Jakuba Podlesaka na temat JAX-RS, a w szczególności projektu Jersey. Zaczęło się standardowo od tego czym jest REST: resources, uniform service interface, multiple representations, hypermedia exhchange (boot URI paradigm), stateless. Jersey będący RI JAX-RS może zostać uruchomiony w Java Servlets Container, embedded HTTP Server, JAX-WS Provider. Jesrsey (nie wiem czy jest to w specyfikacji JAX-RS) jest w stanie wygenerować nam WADL, dokument opisujący nasze usługi oraz dodatkowo wprowadza @Consume. Annotacja ta pozwala na bindowanie ciała żądania HTTP do obiektu. Z tego co wiem to jest to coś nad czym aktualnie pracuje Arejn Poustsma w ramach Spring @Rest.
Jeresey out-of-box wspiera JAXB, czyli marshalling/unmarshalling w formatach XML oraz JSON jest zapewniony. Content-negotiation jest określany na podstawie nagłówka Accept oraz rozszerzenia zasobu. Aby wysyłać z poziomu przeglądarki żądania HTTP: PUT i DELETE używany był plugin do firefox - Poster.
Pomimo tego, że JAX-RS dotyczy jedynie warstwy serwerowej Jersej posiada także API dla klientów usług REST.

sobota, 9 maja 2009

GeeCon dzień 1

GeeCon okazał się być największą i najlepszą polską konferencją Javowa na jakiej dotychczas byłem.
JavaFX: The Platform for Rich Internet Applications
Keynote Simona Rittera na temat Java FX. Niezbyt interesuję się technologiami związanymi z UI oraz widziałem Java FX w akcji podczas Devoxx i chyba dlatego nie do końca dałem się wciągnąć w prezentacje... Podstawowa informacja to, że Java FX jest językiem skryptowym działającym na JRE , pod spodem korzysta z dobrodziejstwa Javy i służy jako język do tworzenia UI uruchamianych w różnych środowiskach: przeglądarka, desktop, urządzenia mobilne, oraz inne wynalazki w stylu TV set top box, konsole gier i inne takie.
Siłą tej technologii ma być prostota, czyli szybkość i łatwość tworzenia UI, które mają działać w wielu środowiskach, czyli 1 język do tworzenia GUI na wielu platformach - cross screen functionality.
Ze względu na to, że przez jakiś czas pracowałem jako J2me developer bardziej zaintersowało mnie wykorzystanie Fx w świecie telefonów komórkowych. Jestem ciekaw czy jest to technologia, która poradzi sobie z problemem fragmentation w świecie mobile. Jak na razie podobno nie ma urządzenia które wspierałoby JAVA FX out of box, ale Sun ma rozmawiać na ten temat z vendorami. Teoretycznie do uruchamianie aplikacji FX na telefonie potrzebna będzie końcówka z obsługą MIDP 2.0 + parę dodatkowych jarów. FX wprowadza profile API, czyli dodatkowe API związane z renderowaniem UI oraz innymi możliwościami (np. PIM oraz obsługa SMS dla Mobile profile) związanymi z platformą uruchomieniową.
W świecie UI (i co za tym idzie RIA) szczególnie ważne jest tworzenie "wodotrysków" i tu Java FX może się na prawdę wykazać. Obsługa audio, video, animacji, rich text jest na prawdę bardzo łatwa, a dodatkowo są też pluginy, które umożliwiają integracje projektów tworzonych w PhotoShop i innych dziwactwach do wykorzystania ich w Java FX. Jako, że aplikacja oprócz UI potrzebuje też trochę logiki, FX posiada wsparcie do komunikacji przez WebServices - chyba chodzi o klasyczne SOAP WebServices (z tego co słyszałem to także Asynchronous Web Services) oraz Restful WebServices.

Collaboration, data synchronization and offline capabilities for Rich Internet Applications
Bardzo przyjemna prezentacja na temat Flex. Cornelaiu po omówieniu ogólnej architektury skupił się na zaprezentowaniu 2 aspektów: data synchronization oraz offline. Dodatkowo zaprezentował tour de flex czyli zestaw przykładów-aplikacji dzięki którym można zobaczyć co Flex potrafi. Nie chodzi jedynie o UI, ale także o pewne feature, które jest bardzo ciężko zaimplementować korzystając z "klasycznych technologii webowych". Pokazano typowe przykłady, w których to z poziomu paru okien przeglądarki widać te same dane, a zmiany robione przez użytkownika są jednocześnie propagowane do okien pozostałych użytkowników. W przypadku konfliktów czyli, np. 2 userów jednocześnie robi zmianę tego samego wiersza Flex wykrywa taką sytuację i pozwala nam coś takiego obsłużyć. Z tego co się orientuje jeśli model który oglądamy w UI jest zbindowany do Hibernate to Flex potrafi podpiąc się pod mechanizm optimistic locking, a w innym przypadku jest to zaimplementowane poprzez cachowanie danych zanim zostaną dostarczone klientowi. Dodatkowo mechanizm Data Management umożliwia korzystanie z Hibernate po stronie klienta, tzn. obiekty w ActionScript są zbindowane do obiektów hibernatowych i ich modyfikacja, ale także odczyt asocjacji (lazy associations) jest propagowany na serwer. Dodatkowo Flex obsługuje comet przy czym ma możliwość "dostosowania" się do działającej infrastruktury: próbuje otworzyc dedykowany socket do serwera, a jeśli to się nie uda to wykorzystuję "klasyczne mechanizmy": Long Pooling , Http Streaming. Kolejny aspektem była praca offline. Jeśli nasz klient straci łącznośc z serwerem, możemy cały czas działać - oczywiście do momentu kiedy nie staniemy się znów online, nie widzimy zmian na serewreze ,ale możemy wykonywać pewne operacje i zapisywać je w lokalnym storage . W przypadku aplikacji nie jest uruchamiana w przeglądarce (aplikacja dektopowa) Flex umożliwia nam korzystanie z wbudowanego SQL Lite. Dla Flexa uruchamianego w przeglądarce ten storage jest bardziej ubogi. Został zaprezentowany przykład, w którym to napisany przez nas listener obsługuję logike związana z zapisywaniem i "wypychaniem" danych na serwer jeśli odpowiednio przejdziemy z online od offline i offline do online. Podobno wszystkie przykłady które zostaly zaprezentowane są dostępne na blogu

Liberate your enterprise Java applications from the Operating System (or: about the JVM-level virtualization)
Chyba najciekawsza (przynajmniej dla mnie) prezentacja dnia. Waldek zaczął od omówienie czym jest wirtualizacja i jakie są korzyści z jej stosowania(przykładowo: "be green", lepsze wykorzystanie maszyn, HA, management). Następnie przedstawił 2 ogólne rodzaje infrastruktury wirtualizacji: Host(OS-based) oraz Hypervisor(bare-metal) . W pierwszym przypadku, w istniejącym systemie operacyjnym instalujemy oprogramowanie, które umożliwia nam uruchamianie maszyn wirtualnych. Jest to architektura, w której pracuje VmWare Workstation, VmWare Server czy VirtualBox. W przypadku Hypervisor, oprogramowanie umożliwiające uruchamianie maszyn wirtualnych jest instalowane bezpośrednio na hardware, czyli pomijamy system operacyjny. Tak działa Oravle VM, Vmware ESX/ESXi. Architektura bare-metal ma nie tylko być wydajniejsza , ale także izoluje nas od stabilności(tzn. braku stabilności) systemów operacyjnych, na których instalowane jest oprogramowanie infrastruktury wirtualizacji. Następnie Waldek przedstawił JRockitVE. Produkt najprościej można opisać jako JRockitVE = JRockitVM + "thin kind-of OS layer". Dzięki JRockitVE mamy możliwość bezpośredniego uruchamiania aplikacji Javowych na maszynie wirtualnej bez potrzeby instalowania na niej systemu operacyjnego.
JVM do swojej pracy(szczególnie jeśli mamy od czynienia z serwerem aplikacyjnym) potrzebuje jedynie pewnych funkcjonalności systemu operacyjnego, np. obsługa urządzeń, system I/O.
Dlatego Jrockit VE dostarcza pewną cienką warstwę, która ma emulować te braki. Waldek podkreślał, że ta warstwa powstała od zera (podejście bottom-up) a nie w wyniku usuwanie zbędnych fragmentów jakiegoś istniejącego OS i oczywiście nie wspiera pewnych funkcjonalności: gui, sound, jni. Z punktu widzenia Javy EE braki te mają być niezauważalne. Taka dostarczana przez Jrockit VE OS jest jedno-procesowy (nie ma możliwości uruchomienia aplikacji/serwera aplikacyjnego oraz bazy danych w ramach jednej maszyny wirtualnej chyba, że baza będzie sama w sobie uruchamiania w JVM) , jedno-użytkownikowy oraz jest w stanie korzystać z funkcji znajdującego się pod spodem hypervisora (paravirtualization). Dodatkowo do tak uruchomionej maszyny wirtualnej możemy się podłączyć za pomocą SSH, jest system plików, jest też jakiś ograniczony shell.
Uruchamianie aplikacji bezpośrednio JRockit VE pozwala nam pozbyć się OS i związanego z nim narzutu: OS nie musi zajmować storage, nie zajmuje RAM, nie ma przejść pomiędzy privileged i user mode.
Na koniec najfajniejsze były przykłady, w których to Waldek za pomocą dostarczanego z JRockitVE narzędzia tworzył z aplikacji Javowej i pliku konfiguracyjnego obraz maszyny wirtualnej i wrzucał go do VmWare Workstation. Na potrzeby prezentacji nie było to środowisko 1:1 z tym co opisywał wcześniej, ale i tak robiło to duże wrażenie..

Making EJB 3.1 development a breeze with Apache OpenEJB
Pierwotnie zająłem miejsce w sali obok i chciałem posłuchać o Scala, jednak gdy na jednym z początkowych slajdów zobaczyłem jakieś krzaki, tzn. jakieś wyrażenie w języku funkcyjnym to czym prędzej uciekłem do sali obok. Przypomniały mi się od razu wyrażenia λ (lambda), które starałem się jakoś pojąć na studiach i jakoś zawsze szło mi to opornie.
W 2 sali Jacek Laskowski zaprezentował OpenEJB jako kontener EJB 3.1. Byłem już na kilku prezentacjach, które omawiały JEE 6 i nie były to dla mnie zbytnie nowości. Z 2 strony cały czas mnie ciekawi co Jacek miał na myśli gdy mówił o integracji OpenEJB ze SpringFramework...

Practical Groovy
Prezentacja na temat Groovy przeprowadzona przez pracownika JetBrains, czyli wszystkie przykłady tworzone i uruchamiane w IntelliJ IDEA. Prezentacja dość typowa dla tych omawiających Groovy: zaczyna się od pokazania ile trzeba "naklepać" w Javie oraz jak szybko da się to przerobić na Groovy (za pomocą narzędzia i/lub ręcznie) aby finalnie zobaczyć zdecydowanie mniejszą ilość kodu z w pełni zachowaną funkcjonalności. Wszystko to wygląda bardzo ładnie, ale mnie przede wszystkim przeraża brak silnej kontroli typów w Groovy, co zmusza developerów do pisania jeszcze większej liczby testów aby wyłapać takie bugi. Podobno można dodatkowo się w tym aspekcie wesprzeć narzędziami do analizy kodu. Osobiście spodobała mi się idea pisania testów jednostkowych dla kodu w Javie w Groovym. Wyglądało to na prawdę całkiem zwięźle i prosto. Oczywiście nie obyło się od prezentacji pokazującej modyfikowanie kodu w w runtime co dla Javowca jest zawsze dużym zaskoczeniem. Groovy podobno bardzo ładnie nadaje się do tworzenie skryptów Anta, budowania konfiguracji Springowych oraz można go wykorzystywać do tworzenia różnej maści DSL. Dodawanie "w locie" metod do klas, używanie clousures i paru jeszcze innych wynalazków, których nazw nie zapamiętałem na pewno wpłynie pozytywnie na produktywność . Jeszcze tylko nie wiem czy taki kod nie okaże się bardzo "fragile".

Building Flex applications with Java Google App Engine backends
Kolejna prezentacja z Flex w temacie. Zaczęło się niestety od problemów technicznych z projektorem i niestety większość prezentacji była wyświetlana w wściekle różowych kolorach. Z całej prezentacji nie interesował mnie Flex, a Google App Engine. Google dotychczas na swoim App Engine umożliwiało wrzucanie aplikacji napisanych w Python, od niedawna jednak można hostować tam aplikacje Javowe. Z tego co się orientuję to chodzi głównie o aplikacje webowe oparte na Java Servlets(z tego co pamiętam to Servlets 2.4) oraz JSP. Dodatkowo można korzystać z dostępnych usług: storage za dostępem za pomocą JDO/JPA, dostęp do Memcache, Java Mail, Authentication/Authorization (na podstawie google accounts). Google dostarcza Google App Engine Java SDK, który może zostać zainstalowane standalone lub jako plugin do Eclipse.W ten sposób łatwo możemy tworzyć, budować, testować (za pomocą lokalnej instancji Jetty) i uploadowac aplikacje na Google App Engine. Podobno nie ma problemu aby uruchomić w taki sposób aplikacje napisaną w Groovy lub za korzystającą z Spring Framework. Podobno jest także wersja BlazeDS, która ma działać na GAE. Google dostarcza jednocześnie model biznesowy(czytaj pricing) dla swojego produktu, ale podobno całkiem dużo można się pobawić za free. O zabawach z flexem na GAE można znaleźc tu