Pokazywanie postów oznaczonych etykietą javaee5. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą javaee5. Pokaż wszystkie posty

12 stycznia 2010

Każdemu będzie w końcu dane - wreszcie Java EE 5 w projektach!

19 komentarzy
Nowy rok i nowe projekty, a tak się złożyło, że część z nich nawet rozwojowa - dosłownie i w przenośni. Znalazłem się więc w projekcie, w którym tworzone jest oprogramowanie do synchronizacji danych między bazami danych (tym samym kłaniam się nisko uczestnikom - klimat "Piratów z Karaibów", których oglądałem przez ostatnie 3 dni się udziela :]).

Architektura obejmuje WASv7 z DB2 (centrala) oraz WASCE z DB2 Express (satelitarne, lokalne instalacje). Nareszcie projekt w IBMie, gdzie serwer aplikacyjny wspiera najnowszą specyfikację Java EE 5 (może niekoniecznie najnowszą, bo na dniach wyszła nowiuteńka wersja Java EE 6, ale jej wsparcie nie jest jeszcze na tyle rozpowszechniona, aby nawet próbować się z nią w ramach prac domowych). Przyznaję, że trochę dziwnie mi się pisze oprogramowanie w Java EE 5 z udziałem IBM WebSphere. Jakoś przyzwyczaiłem się do starszych specyfikacji, których unikałem, jak tylko mogłem i większość pracy sprowadzałem do odpowiednich funkcjonalności w RADzie. Udało się i teraz zostało mi to wynagrodzone - wreszcie można oddychać pełną piersią, a jeśli dodać do tego, że teraz wszystkie zabawki IBMa z rodziny WebSphere działają na WASv7 - serwerze aplikacyjnym zgodnym z Java EE 5 i działającym na Java SE 6 - to możecie sobie wyobrazić, jak bardzom z tego rad. Do niedawna jeszcze o Java EE mogłem sobie pomarzyć w cieple domowego kominka, a w pracy...brrr...lepiej nie wspominać, wciąż J2EE. Teraz się odmieniło, bo kiedy się bardzo chce, to się kiedyś ziści. Wiedza, którą zdobywałem w ostatnim roku teraz się przydaje...produkcyjnie. Wreszcie!

Wracając do mojego bieżącego projektu, miałem dzisiaj przygodę z synchronizacją realizowaną przez...stronę JSP. Wszystko było wykonywane z jej poziomu i jej autor zdawał się mieć tego całego programowania w Javie najwyraźniej dosyć (nieprawdaż Paweł?). Szkoda było chłopaka, bo zacny z niego gość, ale brakowało mu wiedzy, ciut więcej i takiej ukierunkowanej na mocne strony Java EE. A skoro już mają Java EE, to nie byłoby dobrze nie skorzystać z dobrodziejstw. Zadanie na rozgrzewkę w sam raz dla mnie - można błysnąć i to przy niewielkim nakładzie pracy. To lubię! ;-)

Przed moimi oczyma jawi się strona JSP, a w niej jeden wielki try/catch z dostępem do bazki, sprawdzeniem tego i owego, aby ostatecznie zbudować odpowiedź XMLową. Dla mnie naturalnym było zaciągnąć @WebService i @Resource do pracy, aby z niecnego JSP zrobić całkiem przyzwoitą klaskę, powtórzę, zwykłą klaskę z kilkoma "wskazaniami" dla serwera, aby traktował ją specjalnie.

Wystarczyło więc, uruchomić NetBeans IDE 6.8.1, zaciągnąć aktualne źródła aplikacji webowej z repozytorium CVS (brrr, że też wciąż tego ustrojstwa się używa) i dodać tę oto klaskę (niektóre elementy usunięte dla poprawienia czytelności):
package pl.tufirma;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.sql.DataSource;

@WebService
public class Synchronizator {

private final String AUTH_SQL = "SELECT ID FROM AUTHORIZE WHERE AUTH = ?";

@Resource(name = "jdbc/mak")
DataSource makDS;

public String synchronizacjaPoczatkowa(@WebParam(name = "key") String klucz) {
return synchronizeFirst(klucz);
}

protected String synchronizeFirst(String key) {
try {
String id_authorize = pobierzIdAuthorize(key);
MessageFormat SQLQUERY = new MessageFormat("WITH ...");

StringBuffer queryParam = new StringBuffer(id_authorize);
String query = SQLQUERY.format(new Object[]{queryParam.toString()});

System.out.println("SQLQUERY: " + query);
Connection conn = makDS.getConnection();
PreparedStatement stmt = conn.prepareStatement(query);
ResultSet rs = stmt.executeQuery();
String XMLResult = "";
if (rs.next()) {
XMLResult = rs.getString(1);
}
return XMLResult;
} catch (SQLException ex) {
Logger.getLogger(Synchronizator.class.getName()).log(Level.SEVERE, null, ex);
throw new IllegalStateException("Problemy z bazka", ex);
}
}

protected String pobierzIdAuthorize(String key) {
try {
Connection conn = makDS.getConnection();
PreparedStatement authStmt = conn.prepareStatement(AUTH_SQL);
authStmt.setString(1, key);
ResultSet authRs = authStmt.executeQuery();
if (!authRs.next()) {
throw new IllegalArgumentException("NIe odnaleziono klucza dla " + key);
}
return authRs.getString(1);
} catch (SQLException ex) {
Logger.getLogger(Synchronizator.class.getName()).log(Level.SEVERE, null, ex);
throw new IllegalArgumentException("NIe odnaleziono klucza dla " + key, ex);
}
}
}
Jak widać wiele jeszcze do zrobienia, ale sam szkielet klasy już jest odpowiednio dopasowany. Propozycje dalszych zmian mile widziane. Mamy wystawioną usługę jako usługę sieciową za pomocą @WebService, a dostęp do bazy danych kontrolowany jest przez serwer aplikacyjny i dostępny klasie przez @Resource. Czyż nie ładniej, chciałoby się zapytać? Teraz pozostaje obsłużyć właściwe tworzenie pliku XML (pewnie JAXB, ale nie będę ukrywał, że aż mnie rwie do Groovy), klient po stronie bazy lokalnej, który czyta odpowiedź od usługi, zapis do lokalnej bazy danych i powinno być całkiem cacy. Terapia szokowa w postaci Groovy i Grails czeka w kolejce (jeszcze im nic nie mówiłem, nawet nie wspominałem, więc prośba o dochowanie tajemnicy, zgoda?).

Jeśli są zainteresowani, aby dowiedzieć się więcej o szczegółach działania tej klasy, wystarczy się odezwać w komentarzu, np. tak: "Wyjaśnień potrzebowałbym więcej...". Chętni? Artykuł czy skrinkast*?

Ach i przy okazji tych doświadczeń z adnotacjami Java EE 5, sprawdziłem jeszcze jedno połączenie, tym razem NetBeans IDE z Eclipse. Sam projekt tworzony był w Eclipse IDE i tak został zapisany w repozytorium. Ja wystartowałem z NetBeans, więc konieczny był import, który sądziłem początkowo, że trochę pozamienia w projekcie. Okazało się, że nie tylko nie pozamieniał, ale moja zmiana była widoczna w Eclipse bez jakichkolwiek specjalnych kroków poza cvs update. Nie było mi dane ukryć mojego zdumienia, że tak łatwo poszło. Miałem przez moment stracha, że może się nie udać, ale, jak to mówią, diabeł ma wielkie oczy.

[*] Z tym "skrinkast" to przegiąłem, co?

22 marca 2008

Komentarz do komentarza w sprawie Spring Framework a Java EE 5

5 komentarzy
Czy powinienem był oczekiwać czegoś innego? Tak już chyba zostanie, że kiedykolwiek dotknę Spring Framework publicznie, to mogę spodziewać się, że wcześniej czy później przyciągnie to i uwagę Waldiego (w innych, mniej javowych kręgach znanego również jako Waldemar Kot). W ostatniej notatce o zniesieniu adnotacji @Transactional w celu pozbycia się zależności od świata zewnętrznego w tworzonej aplikacji - Słów kilka o transakcjach w Spring Framework napisałem:

W tym sensie jego [=Spring Framework] bogate acz "rozproszone" możliwości mogą być zabójcze dla wielu, niekoniecznie początkujących programistów, którzy postawieni przed wyborem swojej platformy dla następnej aplikacji z pewnością wybiorą serwer aplikacyjny Java EE ze względu na jego "gotowość" (oczywiście znajdzie się wielu odważnych, którzy początkowe trudności w zestawieniu serwera aplikacji z użyciem Springa zrekompensują sobie późniejszą elastrycznością architektury). Możnaby powiedzieć, że serwer aplikacyjny Java EE to aplikacja oparta o Spring Framework ze wszystkimi jego usługami już zestawionymi do poprawnej realizacji wymagań stawianych przez specyfikację Java EE.

Nie trzeba było długo czekać, aby uwaga Waldiego została skierowana właśnie ku niej, gdzie odpowiedział:

Biorąc pod uwagę nasze przekomarzania, pewnie się tego Jacek spodziewasz, ale oczywiście IMHO linia podziału przebiega między Spring a EJB (dokładnie częścią EJB czyli Session Bean i Message Driven Bean, czyli bez JPA), a NIE między Spring a Java EE.
Nie widzę też w Springu tego "wiele" na jego poprawne zestawienie (ani też nie widzę tego "bez większego wysiłku umysłowego" w EJB).
A już w żadnej mierze - o czym zresztą jakiś czas temu na grupie WJUG [=Warszawa JUG - mój dopisek] było - nie można przeciwstawiać serwera aplikacyjnego i Spring. Kombinacja serwer aplikacyjny JEE + Spring jest bardzo mocną platformą na której można budować serwerowe aplikacje.
Trzymałbym się też rzeczywistości, która jasno pokazuje, że "model Spring" w sposób absolutny zdominował "model EJB" i do "zabójstw" nie dochodzi ;-). Wręcz przeciwnie - dzisiaj wielu (większość ???) programistów szczególną uwagę przywiązuje do możliwości łatwego testowania swojego kodu - problem, którego akurat EJB3 (znowu dotyczy Session i Message-Driven Beans) wciąż nie rozwiązuje i nic "gotowego" tu nie oferuje.
Aby podtrzymać DOBRĄ praktykę przekomarzania się, to przyznam, że Twojej analogii o app serwerze jako "aplikacji opartej o Spring" nie załapałem ;-).

I tu wymagany jest mój komentarz do komentarza Waldiego, a że zainteresowany jestem zdaniem innych osób postanowiłem "ubrać" dyskusję w szaty wpisu do Notatnika (ciekawym, czy kiedykolwiek doczekam się dnia, gdzie tego typu dyskusje będą prowadzone na prywatnych blogach, podobnie jak to było swego czasu w pewnym nurcie muzyki, gdzie kolejny kawałek był odpowiedzią na inny - nie pamiętam które to kapele ze sobą w ten sposób rywalizowały, ale było ciekawie - to były jakieś hiphopowe, polskie kapele, które wzorowały się na ich zachodnich odpowiednikach).

Jak ja widzę sprawę Spring Framework a Java EE a może powinienem nawet napisać Spring Framework vs Java EE. Do tej pory spotykam się ze zdaniem, że jakkolwiek połączenie Spring Framework i Java EE to bardzo bogate funkcjonalnie podejście, to ostatecznie większość naszych aplikacji "migruje" w kierunku platformy, gdzie głównym i zazwyczaj jedynym graczem w naszych rozwiązaniach jest Spring, w ramach którego uruchomione (uaktywnione) są inne usługi - utrwalanie danych za pomocą Hibernate, bezpieczeństwo przejmuje Acegi (obecnie Spring Security), szkielet webowy to Spring MVC, bądź podobny, który dobrze integruje się ze Springiem i ostatecznie z całej gamy usług Java EE pozostaje...kontener servletów, którym jest zazwyczaj Apache Tomcat. Zgodzę się, że Spring oferuje wiele i jest ciekawą platformą. Zgodzę się również, że nie wszyscy idą w tym kierunku (acz jest to znacząca większość). Nie mogę się zgodzić i pogodzić z powszechnym przekonaniem, że takie architektury powinno się oferować klientom jako ostateczne. Powód? Większość z tego dobrodziejstwa należy "zestawić" samodzielnie. I tutaj upatruję "wyższości" Java EE nad Springiem. To nazwałem w swojej notatce jako "rozproszone" możliwości. W przeciwieństwie do serwera aplikacji Java EE, usługi w Springu należy najpierw włączyć poprzez ich konfigurację w niezwykle skomplikowanym, xmlowym pliku konfiguracyjnym. W Java EE nie zauważyłem tego skomplikowania, co może być tylko moim postrzeganiem, co jest skomplikowane, a co nie. Temat zestawienia usług w świecie serwerów aplikacji Java EE przejmują właśnie ich dostawcy, którzy pozostawiają nam, twórcom aplikacji korporacyjnych, jedynie ich konfigurację. Postrzegając temat przez pryzmat osób nowych w temacie tworzenia aplikacji korporacyjnych, ich wybór zazwyczaj podyktowany jest zwykle bezkrytycznemu postrzeganiu otaczającego ich świata. Obserwując ruch w moim Notatniku zauważam wyjątkowo wysoką aktywność wokół tematów Hibernate, JBoss Seam czy właśnie Spring. Nie potrafię jeszcze tego wytłumaczyć, ale Hibernate bije większość innych tematów na głowę. Zapewne popularność rozwiązań springowych przesłania możliwości serwerów aplikacji Java EE, które powinny być komplementarnym rozwiązaniem, a nie stawiane jako konkurencja. Tak właśnie postrzegam podział, który wytworzył się po ukazaniu książki Roda Johnsona (autora Springa) , Expert One-on-One J2EE Design and Development (Programmer to Programmer) oraz Expert One-on-One J2EE Development without EJB, która zapoczątkowała erę Springa, w której serwery aplikacyjne zostały umiejscawiane w kategorii niepotrzebnego balastu architektonicznego (za wyjątkiem kontenera webowego). Uważam, że wszechobecność Springa wynika z kopiowania (anty?)wzorców. Spring Framework jako kontener IoC (ang. inversion of control) dostarcza ogrom możliwości, ale co mnie niepokoi, to właśnie to kopiowanie i bezkrytyczne naśladowanie. W ten sposób rodzą się właśnie antywzorce, które przez długi czas są rekomendowane jako wzorce, a dopiero po krytycznym im się przyjrzeniu pokazują swoje pazury i "przepoczwarzają" w antywzorce. Niepokojący jest fakt, że Spring jako de facto standard w zakresie kontenerów IoC przyćmił swoim blaskiem inne, potencjalnie bardziej bogatsze projekty. Dobrym przykładem jest kontener IoC wykorzystywany w Apache Maven - Plexus - niewielki, dobrze sprawujący się i dostarczający wyłącznie funkcjonalności wstrzeliwania zależności kontener DI (ang. dependency injection). Ostatnie dyskusje dotyczące Mavena i mechanizmów DI na grupie dyskusyjnej programistów Mavena (trunk & shading czy XBean and DI?) zwróciły moją uwagę na problem wszechobecnego i bezkrytycznie przyjmowanego Springa. Jego stanowsze NIE dla wprowadzenia Springa czy OSGi pod strzechy Mavena daje do myślenia. Pojawienie się Google Guice jest również sygnałem, że w temacie coś jest na rzeczy i wielu oczekuje czegoś alternatywnego. Pewnie, że do możliwości Springa Guice musi jeszcze dorosnąć, ale niektórym monopol Springa na rozwiązania DI najwyraźniej doskwiera.

Wracając do linii podziału między kontenerem EJB, czy pełnego serwera aplikacji vs Spring Framework niepokojący jest fakt, że wykorzystanie serwera Java EE nie pociąga za sobą wykorzystania Spring Framework (przynajmniej w jego części IoC) i odwrotnie (przynajmniej, w sytuacji, gdzie korzystamy również z kontenera servletów). Wciąż zadaję sobie pytanie Dlaczego?. Jednym z potencjalnych wyjaśnień może być (mam nadzieję) przemijająca nieprzyjazność Java EE w jej wersji 1.4, a szczególnie jeśli chodzi o EJB 2.1. Tak, to można napisać nie narażając się komukolwiek - EJB 2.1 to była wpadka, która kosztowała wiele wielu. Pomysł wspaniały, ale realizacja nie ta. Nieprzespane noce ślęcząc nad generowaniem niepotrzebnego kodu, nauka XDoclet, aby ulżyć cierpieniu, aż tu światełko w tunelu w postaci Springa, książka Roda i zaczęła się masowa migracja do jedynej, właściwej platformy Spring Framework. To faktycznie mogło wielu zniechęcić do Java EE. Teraz wierzę i doświadczam na codzień, że sprawy mają się inaczej - Java EE 5 to wciąż te same usługi, ale bardziej rozbudowane i co ważne prostsze w użyciu oraz gotowe do użycia. Przez gotowość do użycia rozumiem fakt, że wystarczy szczątkowa ilość adnotacji czy xmla, wręcz w wielu przypadkach żadna, i już mamy dostęp do bazy danych, aktywne transakcje, bezpieczeństwo, itp. Nie jest to wystarczające? Dodajmy do tego Springa. Dlaczego nie?! Ów "model springowy", o którym pisał Waldi na pewno miał w tym swoją zasługę na ostateczny wygląd specyfikacji Korporacyjnej Javy 5, a w przypadku Java EE 6 będzie miał jeszcze większy. Kiedy ostatnio konfigurowałem Springa uderzyło mnie kopiowanie kroków, jakie musiałbym wykonać konfigurując serwer aplikacji (zestawienie połączenia do bazy danych, konfiguracja transakcji). Napisałem, że serwer aplikacyjny Java EE to aplikacja oparta o Spring Framework ze wszystkimi jego usługami już zestawionymi do poprawnej realizacji wymagań stawianych przez specyfikację Java EE, co podyktowane było spojrzeniem na Springa z perspektywy wyłącznie jego możliwości IoC/DI, który do pełnej gamy usług dostarczanych przez serwer Java EE wymaga dodatkowo konfiguracji, zewnętrznych do Springa, usług. Takie podejście oczywiście pozwala wręcz na konstrukcję serwera aplikacji, czego dowodem jest chociażby wykorzystanie Springa do konstrukcji kontenera EJB 3 w BEA WebLogic Server. Taki ruch jedynie podkreśla możliwości Springa, ale usługi należy w jakiś sposób dostarczyć. Usługi ustandaryzowane przez specyfikację Java EE jak transakcyjność, bezpieczeństwo, utrwalanie danych, wielowątkowość nie są dostępne w Spring Framework za darmo. Pod tym względem liczba zadań przy zestawieniu aplikacji wyłącznie na Springu jest bardziej pracochłonna i może być zabójcza dla wielu, niekoniecznie początkujących programistów. W serwerze aplikacji Java EE mamy je za darmo, co w Springu wiąże się z utworzeniem pliku XML, czy wykorzystaniem innych alternatywnych środków jak adnotacje (co tak czy owak wymaga poświęcenia naszego czasu na stworzenie tego środowiska, które w przypadku serwera Java EE 5 jest gotowe). Dla mnie, owe środowisko serwera aplikacji zgodnego ze specyfikacją Korporacyjnej Javy 5 będzie tym, co ja nazywam Springiem z dodatkowymi usługami związanymi plikiem XML. Można wyobrazić sobie sytuację, w której Spring IoC po dodaniu wymaganych usług przeistoczy się w Spring Application Server (Spring Java EE). Spring jest dobrym kontenerem IoC, dostarcza wiele ciekawych i użytecznych rozwiązań idąc w górę stosu aplikacyjnego, ale nie zgodzę się, że powinien być wyłącznym sensownym rozwiązaniem, gdzie inne dodatki są jedynie dodatkami i to jeszcze traktowanymi jak niepotrzebnie komplikujące rozwiązanie. Mam takie wrażenie, że postrzeganie serwerów aplikacyjnych Java EE 5 przez użytkowników-praktyków Springa jest nieadekwatne do tychże serwerów możliwości upraszczających tworzenie aplikacji korporacyjnych. Mam wrażenie, że wielu postrzega linie podziału między Springiem vs serwer Java EE 5 jako "albo Springa albo serwer", a niewielu sprowadza temat do dyskusji "jak Spring i aplikacje korporacyjne, to i serwer Java EE", bądź "jak Java EE 5, to i Spring". Sądzę, że najprościej możnaby stwierdzić, że wynika to z naszego okrajania możliwości jednego czy drugiego rozwiązania ze względu na ich niedoceniane możliwości, które wymagają czasu na ewaluację i dogłębne poznanie. Czyż nie prościej i łatwiej wziąść coś z półki "gotowe i polecane" niż "bogatsze funkcjonalnie acz wymagające poznania"? Czyż właśnie nie chodzi o tą ilość czasu, jaką mamy na poznawanie niepoznanego?

Na koniec Waldi dodał:

To w sumie też już było kilka razy poruszane, ale moim skromnym zdaniem w fajny sposób pokazałeś, że CZASAMI te zniesławione ostatnimi czasy deployment deskryptory (nawet XMLowe) mogą być lepszym podejściem (biorąc pod uwagę ZAŁOŻENIA) od będących-cool adnotacji. Wybór "adnotacje vs. zewnętrzna konfiguracja" jest kwestią indywidualną danego programisty. Czasem lepiej pasuje jedno, czasem drugie. Akurat mapowanie OR, czy konfiguracja transakcji należą moim zdaniem do tych, gdzie - zwłaszcza w dłuższej perspektywie - zewnętrzna konfiguracja ma przewagę nad adnotacjami. Marzy mi się takie rozszerzenie do IDE, w którym będzie refaktoring zamieniający jednym kliknięciem adnotacje na konfigurację i odwrotnie...

W tym przypadku podzielam zdanie Waldiego, więc komentarz bardzo krótki ;-) Wydaje się, że programiści znużeni są przytłaczającym xmlem jako medium konfiguracyjne, co najczęściej dotyka mnie osobiście właśnie przy Springu i Apache Maven 2. Nazywam to programowaniem w XMLu. W Maven 1 mieliśmy Apache Jelly i początkowo wszyscy byli nim zachwyceni, ale szczęśliwie nie trwało to długo, aby Maven 2 zarzucił ten pomysł na mechanizm wtyczek pisanych w Javie. To wydaje mi się droga ku krainie szczęśliwości - konfiguracja programowalna w języku programowania, np. Javie, albo czymś znacznie mniej restrykcyjnym, skrojonym na miarę wymagań, np. Groovy, albo JRuby. I tutaj możnaby kontynuować temat wskazując na Apache Buildr, gdzie mamy próbę połączenia dwu światów - możliwości Apache Maven 2 (głównie zarządzanie zależnościami) oraz bogactwem języka programowania JRuby zastępując XMLa skryptami. Nota bene, JRuby sam w sobie jest połączeniem dwu rozwiązań - możliwości programowania z wykorzystaniem Ruby na bazie wirtualnej maszyny Javy (JVM) z jednoczesnym korzystaniem z bogactwa bibliotek javowych. Nie mogę doczekać się dnia, kiedy tego typu synergię ujrzę i w Springu, gdzie poza adnotacjami i programowaniem w XMLu będę miał konfigurację programowalną w wybranym języku skryptowym. A może już to mam, a jeszcze tego nie zauważyłem?

19 września 2007

NetBeans IDE 6.0 Beta 1 oraz GlassFish V2 dostępne, ale czy gotowe?

0 komentarzy
Właśnie pojawiła się nowa wersja beta środowiska programistycznego NetBeans IDE 6.0 Beta 1. Rozpoczął się tym samym program NetCAT 6.0 (NetBeans IDE 6.0 Community Acceptance Testing), w którym zdeklarowałem zweryfikować poprawność działania kolejnych kandydatów na finalną wersję NetBeans IDE 6.0 w obszarach j2ee oraz web services (Participants of NetCAT 6.0 program). Jak się później okazało w wersji Beta 1 jest kilka błędów, które dyskwalifikują ją i konieczne jest pobranie wersji następnej, rozwojowej.

Zabawę czas zacząć!

Rozpocznę od stworzenia bardzo prymitywnej aplikacji Java EE 5 z wykorzystaniem jak najmniejszej liczby kroków, a tym bardziej uderzeń w klawiaturę (coś na wzór poprzedniego testu, którego wynikiem był artykuł - Tworzenie aplikacji EJB 3.0 z GlassFish v2, Apache Maven 2 i NetBeans IDE 6.0).

Tym razem zbuduję bezstanowe ziarno sesyjne EJB, które udostępnia wyłącznie interfejs usługi sieciowej (WS) oraz klienta korzystającego z niej (jakiż inny mógłbym wybrać przykład łączący EJB3 (obecne zainteresowanie) z Web Services w ramach NetBeans IDE 6 tak, aby kontynuować poznawanie EJB3 i sprawdzić działanie NetBeans IDE?!)

Przez serwer rozumiem serwer aplikacyjny zgodny ze specyfikacją Korporacyjnej Javy 5 (Java EE 5).
Przez aplikację korporacyjną rozumiem aplikację tworzoną przy wykorzystaniu elementów Korporacyjnej Javy.

Definiuję nowy serwer, który będzie wymagany przy tworzeniu aplikacji korporacyjnej. Jak miało to miejsce poprzednio wybieram GlassFish'a (ech, jak mi się marzy przedstawienie Apache Geronimo 2.0.1 z wtyczką dla NetBeans IDE 6.0, ale to jeszcze musi trochę poczekać). Serwer pobieram w ramach paczki dystrybucyjnej NetBeans IDE 6.0 Beta 1 bądź jako osobny projekt ze strony GlassFish Project - V2 Final Build (aka b58g Promoted Build). Instrukcje tworzenia nowego serwera można znaleźć we wspomnianym wcześniej artykule.


Zaczynam od stworzenia projektu ziarna - MojPierwszyWsEJB - menu Enterprise > EJB Module, wskazuję na serwer GlassFish (jeśli jest jedynym serwerem to będzie automatycznie wybrany) i zatwierdzam formatkę definiowania projektu.

Tworzę nowy pakiet (menu New > Java Package) - pl.jaceklaskowski.ejbws.

W menu kontekstowym nowego pakietu wybieram New > Session Bean... podaję EJB Name jako MojPierwszyWsEJB i zatwierdzam formatkę.

Jakkolwiek zgodnie z komentarzem w klasie ziarna możnaby skorzystać z menu kontekstowego Web Service > Add Operation to faktycznie takie menu nie istnieje. Zgłosiłem błąd [60cat] No Web Service > Add Operation menu yet the comment in EJB points to it.

Wybieramy Add Business Method i definiujemy bezparametrową metodą metodaBiznesowa. Ostatecznie ziarno wygląda następująco:

package pl.jaceklaskowski.ejbws;

import java.util.logging.Logger;
import javax.ejb.Stateless;

@Stateless
public class MojPierwszyWsEJBBean implements MojPierwszyWsEJBLocal {

Logger logger = Logger.getLogger(MojPierwszyWsEJBBean.class.toString());

public void metodaBiznesowa() {
logger.info("Metoda biznesowa metodaBiznesowa wywołana poprawnie");
}
}

gdzie lokalny interfejs biznesowy wygląda tak:

package pl.jaceklaskowski.ejbws;

import javax.ejb.Local;

@Local
public interface MojPierwszyWsEJBLocal {

void metodaBiznesowa();

}

New > Web Service... z domyślną nazwą NewWebService, w pakiecie pl.jaceklaskowski.ejbws (pole Package) i wybieram opcję Delegate to Existing Session Enterprise Bean ze wskazaniem na wcześniej stworzone ziarno. Finish. Niestety, w tym momencie pojawi się NPE, który zgłosiłem jako [60cat] NPE upon finishing New > Web Service in EJB project. Zamykam okno z komunikatem błędu (przycisk Close). Po pewnym czasie wszystko wraca do normy, tj. pojawia się pozycja MojPierwszyWsEJBBean w węźle Enterprise Beans, chociaż nie potrafię odtworzyć ścieżki poleceń, aby do tego momentu dojść. Tak, czy owak, zamknięcie okna z błędem kończy temat do momentu kolejnego rozwinięcia węzła Enterprise Beans, czego nie planuję zrobić ponownie.

package pl.jaceklaskowski.ejbws;

import javax.ejb.EJB;
import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.ejb.Stateless;

@WebService
@Stateless
public class NewWebService {

@EJB
private MojPierwszyWsEJBLocal ejbRef;

@WebMethod(operationName = "metodaBiznesowa")
@Oneway
public void metodaBiznesowa() {
ejbRef.metodaBiznesowa();
}
}

Zanim wywołam usługę sieciową, instaluję paczkę EJB na serwerze przez wywołanie menu Run. Próba wcześniejszego uruchomienia usługi kończy się komunikatem o niedostępności usługi na serwerze.

Wybieram menu Test Web Service z menu kontekstowego węzła MojPierwszyWsEJB/Web Services/NewWebService.

Wciskam przycisk metodaBiznesowa, która spowoduje wywołanie metody metodaBiznesowa ziarna MojPierwszyWsEJB, o czym można się przekonać w dzienniku zdarzeń GlassFish'a:

Invoking wsimport with http://localhost:8080/NewWebServiceService/NewWebService?WSDL
wsimport successful
Metoda biznesowa metodaBiznesowa wywolana poprawnie

Pomijając 2 błędy znalezione w międzyczasie tworzenie usługi sieciowej na bazie ziarna EJB można uznać za zakończone. Ze względu na błędy zmuszony byłem do zainstalowania wersji rozwojowej NetBeans IDE 6.0 z dnia 18.09.2007 (uwaga: odnośnik wskazuje na ostatnią wersję NetBeans IDE 6.0, więc w trakcie czytania wersja może być już nowsza).

W międzyczasie natrafiłem na artykuł zbliżone do tematu opublikowany na stronach netbeans.org - Getting Started with JAX-WS Web Services in NetBeans IDE 6.0. Zresztą jest ich więcej, m.in. na stronie Web Application Learning Trail oraz Java EE Applications Learning Trail w sekcji NetBeans IDE 6.0 Beta Tutorials.

06 września 2007

Tworzenie aplikacji Java EE 5 z NetBeans IDE 6.0 i GlassFish v2

0 komentarzy
Poprzedni artykuł Tworzenie aplikacji EJB 3.0 z GlassFish v2, Apache Maven 2 i NetBeans IDE 6.0 przedstawił proces tworzenia aplikacji EJB 3.0 z kilkoma narzędziami wspierającymi tworzenie oprogramowania zgodnego ze specyfikacją Korporacyjnej Javy (Java EE 5). Artykuł uzmysłowił mi potrzebę skrócenia czasu tworzenia aplikacji korporacyjnej do niezbędnego minimum. Postanowiłem iść dalej i spróbować stworzyć aplikację Java EE korzystając wyłącznie z pomocników (ang. wizards) dostarczanych przez NetBeans IDE 6.0. Jako aplikację do utworzenia wybrałem książkę telefoniczną bazując na przykładzie zaczerpniętym z dokumentacji serwera aplikacyjnego Apache Geronimo - Very simple Entity EJB example. Celem było zminimalizowanie koniecznych modyfikacji wykonywanych manualnie na rzecz wykorzystania możliwości środowiska graficznego NetBeans IDE 6.0 oraz technologiczne uatrakcyjnienie przykładu opisanego na wspomnianej stronie (co powinno zostać odzwierciedlone również na niej samej w kontekście użycia Apache Geronimo).

W takim klimacie przyszło mi napisać nowy artykuł Tworzenie aplikacji Java EE 5 z NetBeans IDE 6.0 i GlassFish v2, w którym krok po kroku przedstawiłem proces tworzenia aplikacji Java EE 5 z minimalnym użyciem klawiatury. Jest to pełna aplikacja korzystająca z JSF, EJB3 oraz JPA. Czekam na sugestię rozszerzenia przykładu. Dodatkowo mile widziane podpowiedzi jeszcze bardziej skrócające czas niezbędny do zbudowania aplikacji Java EE 5 z NetBeans IDE 6.0. Chętnie usłyszę o doświadczeniach z innymi IDE.

Pora na zestawienie podobnego 10-minutowego przykładu z Eclipse IDE 3.3 albo jakimś rozszerzeniem Eclipse'a, np. RedHat Developer Studio. Przykład z pewnością uruchomię na Apache Geronimo v2 z wtyczką Geronimo Eclipse Plugin.

25 stycznia 2007

Java EE 5: Resources, Naming, and Injection

0 komentarzy
Zanim podejdę do lektury kolejnej specyfikacji postanowiłem sprawdzić jedną rzecz, która męczyła mnie od dawna - rodzaje komponentów w Java EE 5, które podlegają obsłudze mechanizmu wstrzeliwania zależności (DI). Pamiętam, że podczas przygotowań do, bądź w trakcie prezentacji EJB3 na spotkaniu Warszawa JUG, zauważyłem, że strony JSP nie korzystają z DI (mimo, że JSP to ostatecznie servlet). Właśnie teraz, po zakończeniu EJB3 Simplified, a przed rozpoczęciem kolejnej części stwierdziłem, że jest to najlepszy moment, w którym powinienem rozwiać wszelkie wątpliwości z tym związane. I...zabrałem się za lekturę rozdziału 5 specyfikacji Java Platform, Enterprise Edition (Java EE) Specification, v5 (co za zbieg okoliczności z tymi 5-tkami) - Chapter 5: Resources, Naming, and Injection.

Rozdział 5 zawiera dokładnie to, czego potrzebowałem, aby w pełni odpowiedzieć na pytanie: Kogo dotyka dobrodziejstwo DI? Z EJB3 Simplified wiem, że dotyczy to każdego typu komponentu EJB, ale co poza tym? Odpowiedzi udziela rozdział 5 specyfikacji Java EE 5. W nim opisano sposób deklarowania i rozwiązywania zależności od zasobów środowiska i parametrów konfiguracyjnych. Jest to zlepek informacji pochodzących z różnych specyfikacji pomocniczych:
  • Java Metadata (JSR-175 aka adnotacje), która jest częścią Java SE 5 (patrz pakiet: java.lang.annotation)
  • Java Naming and Directory Interface (JNDI) - podobnie jak adnotacje, jest częścią Java SE od wersji 1.3 (patrz pakiet: javax.naming)
  • Common Annotations 1.0 (JSR-250) opisująca adnotacje wspólne dla technologii Java (nie tylko Java EE)
  • Enterprise JavaBeans 3.0 (JSR-220), w której skład wchodzi również specyfikacja Java Persistence API
Na uwagę zasługuje powód zmian i wprowadzenia tylu usprawnień pod postacią adnotacji i połączenia ich z deskryptorem instalacji w specyfikacji Java EE 5. Mamy dwa główne powody wprowadzenia rozwiązań będących przedmiotem rozważań grup standaryzujących skupionych wokół w/w specyfikacji. Po pierwsze, zakłada się, że osoba konstruująca aplikację (ang. application assembler) oraz instalator (ang. application deployer) mają możliwość konfiguracji aplikacji bez konieczności posiadania kodu źródłowego (mimo ich zanużenia - za pomocą adnotacji - w kodzie źródłowym). W Java EE 5 elementy konfiguracyjne jak wartości parametrów, połączenia do zasobów zewnętrznych, odwzorowanie logicznych nazw użytkowników itp. są możliwe w dekryptorze instalacji (w zasadzie wiele się tutaj nie zmieniło w porównaniu z poprzednią wersją specyfikacji Java EE 1.4). Drugi powód to zniesienie obowiązku poznawania szczegółów mechanizmu zarządzania zasobami (będącymi zależnościami) w środowisku uruchomieniowym. Uproszczeniu uległa konfiguracja nazw logicznych zasobów zależnych na ich faktyczne zasoby w środowisku, co nie jest obarczone koniecznością poznawania ich fizycznych nazw i organizacji w środowisku. Zdecydowanie na plus!

W przeciwieństwie do EJB3 Simplified, rozdziały specyfikacji JavaEE są obszerne i zazwyczaj składają się z wielu podrozdziałów. Rozdział 5 - Resources, Naming, and Injection składa się z 54 stron i 13 sekcji, co z pewnością wymaga trochę czasu, aby to przerobić i zrozumieć. Mnie zabrało aż 2 dni i próba zreferowania tematu zawsze kończyła się wycięciem kilku informacji, które z pragmatycznego punktu widzenia nie są istotne (a jeśli są, to i tak przychodzi wtedy pora na zapoznanie się ze specyfikacją bądź dokumentacją produktu - raczej w odwrotnej kolejności).

Dużym udogodnieniem jest uwspólnienie wymagań konfiguracyjnych dla różnych typów komponentów, czyli poznanie adnotacji dla komponentów jednego typu (np. EJB) jest równoznaczne z poznaniem adnotacji dla pozostałych (np. servletów) oraz samego sposób ich użycia.

Wstrzelenie zasobów zależnych sprowadza się do odszukania ich w kontekście nazw JNDI (ang. JNDI naming context), tj. użycie adnotacji jest w tym przypadku jedynie skrótem programistycznym i jest równoznaczne z odszukaniem zasobu w JNDI.

Metody biznesowe komponentu korzystają z elementów/wpisów w środowisku (poza małymi wyjątkami jak metody przechwytujące czy zwrotne). Mogą je pozyskiwać poprzez operacje JNDI bądź skorzystać z metod wyszukujących na obiekcie kontekstu specyficznego dla komponentu (które de facto opakowują bezpośrednie korzystanie z metod JNDI - są ich uproszczeniami, które znoszą obowiązek poznawania szczegółów konfiguracyjnych i metod JNDI). Poza tymi sposobami (które uważam za stosunkowo niskopoziomowe) istnieje mechanizm wstrzeliwania zależności, które umożliwia przekazanie (wstrzelenie) zależności do pola instancji bądź metod modyfikujących (ang. setter) - zauważyłem użycie określenia pole instancji oraz właściwość instancji, gdzie to drugie jest polem instancji z metodą modyfikującą i/lub odczytującą. Dostawca komponentu deklaruje w deskryptorze instalacji lub za pomocą adnotacji wszystkie zasoby środowiska, od których zależy działanie aplikacji. Kontener zarządza kontekstem nazw JNDI i umożliwia ich administrację. Osoba instalująca aplikację ma możliwość inicjowania wartości elementów środowiska, które wskazują na wymagane przez aplikację zasoby środowiska.

Współdzielenie zasobów środowiska

Komponenty deklarują zależności, które dostarczone są przez kontener (serwer aplikacyjny) w przestrzeni nazw JNDI komponentu. Instancje wybranego komponentu w ramach pojedyńczego kontenera współdzielą te same składowe środowiska. Nie ma możliwości modyfikowania środowiska podczas działania aplikacji - innymi słowy przestrzeń nazw jest wyłącznie do odczytu.

Każdorazowe wyszukanie pozycji w przestrzeni nazw java: zwraca nową instancję danego typu z kilkoma drobnymi wyjątkami, gdzie kontener wie, że się nie zmienią (stan obiektu jest niezmienny, singletony, wybrane obiekty współdzielone). Tym samym każdorazowe wstrzelenie zależności poprzez adnotacje jako równoważne wyszukaniu w kontekście komponentu nowej instancji, bądź współdzielonej zgodnie z zasadami wymienionymi powyżej (uwaga na jednostki utrwalania - ang. persistence unit - przy wartości tworzenia schematu drop-create).

Kilka istotnych uwag odnośnie miejsca użycia adnotacji:
  • Pole lub metoda instancji może być dowolnej widoczności (public, private, protected czy domyślnej)
  • Poza klientami aplikacyjnymi (ang. application client) pole i metoda nie mogą być static
  • W przypadku klientów aplikacyjnych pole i metoda musza być static
  • Udekorowane pole nie może być final
  • Domyślna nazwa zasobu wyszukiwanego w kontekście podczas wstrzeliwania zależności to sklejenie nazwy pola wraz z pełną nazwą klasy, np. java:comp/env/pl.jaceklaskowski.exams.ExamSchedulerBean/examScheduler, gdzie java:comp/env wyznacza prywatną cześć przestrzeni nazw dla komponentu podlegającemu DI, pl.jaceklaskowski.exams.ExamSchedulerBean jest nazwą klasy, w której następuje DI (w tym przypadku jest to komponent EJB) oraz examScheduler jest nazwą pola instancji
  • Adnotacja umożliwia również bezpośrednie podanie nazwy zasobu (atrybut name), pod którą można go odszukać w kontekście, która jest względna do przestrzeni java:comp/env. Podobny mechanizm działa dla właściwości (np. udekorowanie setExamScheduler jest równoznaczne z udekorowaniem pola examScheduler).
Dowolny zasób może być wstrzelony do pola lub metody w danej klasie. Nie można zażądać wstrzelenia zasobu o danej nazwie jednocześnie do pola i metody, które wskazują na tę samą zmienną instancji. Dozwolone jest jednak podanie różnych nazw dla metody i pola. Podając inną niż domyślną nazwę pojedyńczy zasób może zostać wstrzelony do wielu pól i metod wielu klas.

Typy komponentów mogących korzystać z DI (to był właśnie powód lektury rozdziału 5!):
  • servlety, filtry, metody obsługujące zdarzenia (ang. event handlers)
  • JSP - klasy znaczników, metody obsługujące zdarzenia związane z bibliotekami znaczników (ang. tag library event listeners)
  • JSF - komponenty zarządzane o zasięgu innym niż none (ang. scoped managed beans)
  • JAX-WS - końcówki serwisów (ang. service endpoints), klasy komponentów
  • EJB - komponenty i metody przechwytujące (ang. interceptors)
  • Klient aplikacyjny (ang. application client) - metoda main oraz metoda zwrotna uwierzytelniająca JAAS
Wszystkie wspierają adnotacje @PostConstruct oraz @PreDestroy, za wyjątkiem klienta aplikacyjnego dla metody main. Wstrzeliwanie zależności odbywa się po stworzeniu instancji typu (poziom JVM), a przed wywołaniem metody biznesowej (poziom serwera aplikacyjnego). Jeśli istnieje @PostConstruct to jest ona wywoływana po DI. Brak zasobu, dla którego istnieje deklaracja zależności (adnotacja) powoduje niedostępność usługi/komponentu.

Adnotacje mogą być związane z samą klasą. W takim przypadku należy podać nazwę zależnego zasobu. Nie powoduje to faktycznego wstrzelenia zależności, a jedynie deklarację pozycji w kontekście komponentu. Niestety, nie odkryłem jeszcze sytuacji, w której chciałbym skorzystać z tej możliwości - wydaje mi się, że jest to po prostu ukłon w stronę administratora, że korzystamy z takiego zasobu wprost, poprzez operacje JNDI, aby wiedział, co należy dostarczyć w środowisku, tj. serwerze aplikacyjnym, aby komponent działał poprawnie (a może jest to układ do samego siebie, w końcu skoro przekazujemy komponent do wykorzystania, to chcemy, aby błedy typu brak zasobów nie wpływał na stan emocjonalny klienta ;-))

Udekorowanie klas może odbywać się na dowolnym poziomie hierarchi klas komponentu. Nie ma znaczenia, że klasa, z której dziedziczy komponent nie jest komponentem podlegającym DI. DI podlega zasadom widzialności pól i metod w Javie, co oznacza, że wszystko, co widoczne w klasie podlegającej DI może zostać udekorowane (mimo, że fizycznie nie występuje w samej klasie mogącej zażądać DI). Klasa pochodna ma prawo nadpisać adnotacje, tj. zmienić typ wstrzeliwanego zasobu, czy nawet zadeklarować brak DI.

Deklaracja składowej środowiska (zasób bądź zmienna) odbywa się albo za pomocą adnotacji, albo wpisów do deskryptora instalacji. Istotna zmiana w Java EE 5 polega na możliwości zaniechania deskryptora na rzecz domyślnych wartości zależności bądź ich deklaracji i konfiguracji za pomocą adnotacji (ale to juz było wiadomo z EJB3 Simplified). Ta sama składowa może być zadeklarowana poprzez adnotację i deskryptora instalacji (w kolejności ich ważności, czyli wartość z deskryptora jest ważniejsza). Jest to sposób na nadpisanie wartości przez osobę składającą aplikację z komponentów czy administratora (bez konieczności posiadania kodu źródłowego, gdzie zadeklarowano, lub nie, zależności poprzez adnotacje). Nie powinno się korzystać z DI w deskryptorze instalacji do pól lub metod, które nie zostały do tego przeznaczone (czyli możliwa jest, ale nie zalecana, sytuacja, gdzie administrator zmodyfikuje deskryptor instalacji - to mu wolno - i wstrzeli zasób do pola/metody, która nie została przez programistę udekorowana - Ale jazda! Szanujmy administratorów! ;-)).

Reguły rozwiązywania wartości elementu środowiska zadeklarowanego za pomocą adnotacji i nadpisanego przez deskryptor instalacji:
  1. Wartość odszukiwana jest w JNDI na podstawie nazwy domyślnej lub podanej explicite
  2. Typ określony w deskryptorze instalacji musi odpowiadać typowi pola bądź właściwości (tj. parametrowi wejściowemu metody modyfikującej)
  3. Opis w deskryptorze nadpisuje description z adnotacji
  4. Miejsce wstrzelenia (jeśli podane) musi wskazywać na udekorowane pole lub metodę modyfikującą
  5. res-sharing-scope (jeśli podane) nadpisuje shareable z adnotacji (nie zaleca się nadpisywania jej, gdyż może zaburzyć działanie komponentu)
  6. res-auth (jeśli podane) nadpisuje authenticationType z adnotacji (nie zaleca się nadpisywania jej, gdyż może zaburzyć działanie komponentu)
Nadpisywanie @EJB oraz @WebServiceRef jest opisywane w specyfikacji EJB i Web Services (dojdę i do nich niebawem...)

Specyfikacja zawiera obowiązki poszczególnych ról występujących podczas tworzenia aplikacji - dostawcy komponentu, osoby składającej aplikację, administratora i dostawcy serwera aplikacyjnego. W ten sposób opisano wszystkie rodzaje pozycji kontekstu i ich konfigurację względem ról.

Proste pozycje środowiska (ang. simple environment entries)

Odpowiadają pozycjom, których wartość jest typem opakowującym typ prosty w Javie wraz z java.lang.String (Character, Byte, etc.)

Pole lub metoda może być udekorowana przez @Resource. Kontener "rozpakuje" typ opakowujący na jego odpowiednik prosty (ang. Java unboxing). authenticationType i shareable nie mogą być podane (nie mają zastosowania).

// konfiguracja wartości pola dostępna administratorowi
@Resource int iloscPoprawnychProb;
Zawsze istnieje możliwość wyszukania pozycji środowiska w java:comp/env.

Dostawca komponentu deklaruje wpisy środowiska za pomocą adnotacji bądź deskryptora instalacji (env-entry). Zasięg widoczności wpisu jest wyłącznie do komponentu, który go zawiera. Ta sama nazwa wpisu może pojawić się wielokrotnie dla różnych komponentów.

Poza deklaracją elementu środowiska poprzez adnotację (w ten sposób deklarujemy, które pole/właściwość podlega DI) mamy możliwość zadeklarować wstrzelenie wartości elementu środowiska bez konieczności korzystania z adnotacji za pomocą znacznika injection-target (w obszarze znacznika env-entry) - uwaga na programowanie w XML znane i (nie)lubiane z Jelly - administratorzy mają kolejną zabawkę, aby instalacja aplikacji trwała latami.

Istnieje możliwość deklarowania wartości domyślnej w kodzie komponentu.

Referencje do komponentów EJB

Administrator wiąże zależności komponentów od komponentu EJB z jego interfejsem domowym lub instancją. Wiązania następują poprzez logiczne nazwy - referencje EJB.

Istnieje również możliwość wiązania referencji EJB z jednego komponentu do EJB w pliku ejb-jar w deskryptorze instalacji bądź poprzez adnotację.

Adnotacja @EJB przypisywana jest do pola albo metody i jedynie dla dowiązania do komponentu sesyjnego (niby wiadome, ale i tak było to dla mnie duużym zaskoczeniem).

Referencja może być do lokalnego/zdalnego interfejsu domowego (EJB 2.1 i poprzednie) albo do interfejsu biznesowego (EJB 3.0). Jeśli korzysta się z referencji do interfejsu biznesowego (EJB3) wstrzelona zostanie już instancja EJB.

Istnieje możliwość precyzyjnego podania wartości adnotacji (z częściowym wykorzystaniem wartości domyślnych - patrz: konfiguracja przez nadpisywanie).

Mimo, że referencje do EJB są elementami środowiska to env-entry nie ma zastosowania. Korzysta się z adnotacji (kod źródłowy) albo znaczników ejb-ref lub ejb-local-ref (deskryptor instalacji).

Opcjonalny znacznik ejb-link precyzuje położenie zależnego komponentu EJB w aplikacji przemysłowej (ear). Można wykorzystać go do przypisywania nazwy logicznej komponentom o tych samych nazwach.

Referencje do fabryki połączeń z zarządcami zasobów (ang. resource manager connection factory)

Faryka połączeń z zarządcami zasobów jest obiektem tworzącym połączenia do zarządcy zasobów (np. javax.sql.DataSource jest fabryką dla java.sql.Connection).

Pole lub metoda może być udekorowana @Resource. Elementy authenticationType i shareable służą do uszczegółowienia konfiguracji dostępu do zasobów.

@Resource javax.sql.DataSource employeeAppDB;
Specyfikacja zaleca, aby fabryki połączeń danego typu były związane z podgałęziami java:comp/env, tj.
  • java:comp/env/jdbc dla fabryk połączeń JDBC (javax.sql.DataSource)
  • java:comp/env/jms dla fabryk połączeń JMS z systemami przesyłania komunikatów (javax.jms.QueueConnectionFactory, javax.jms.TopicConnectionFactory, javax.jms.ConnectionFactory)
  • java:comp/env/mail dla połączeń JavaMail (javax.mail.Session)
  • java:comp/env/url dla połączeń poprzez URLConnection (java.net.URL)
Deklaracja elementów środowiska dla fabryk odbywa się w deskryptorze instalacji za pomocą resource-ref.

Referencje kanałów komunikacji (ang. message destination references)

Tutaj nie ma wiele zmian porównując z referencjami fabryk połączeń. Korzystamy z @Resource bez authenticationType oraz shareable (nie mają zastosowania).

Za pomocą adnotacji @Resource, nie ma możliwości zdefiniowania, czy związany zasób służy do odbioru czy wysyłania komunikatów. Służy do tego deskryptor instalacji z pomocą znacznika message-destination-ref.

@Resource javax.jms.Queue stockQueue;

Referencje UserTransaction

Niektóre komponenty mają możliwość zarządzania tranzakcją (rozpoczęcie, zatwierdzenie i wycofanie). Do dowiązania do obiektu UserTransaction służy java:comp/UserTransaction albo adnotacja @Resource dla typu userTransaction.

Wstrzelenie lub udostępnienie zasobu w kontekście jest kontrolowane przez serwer aplikacyjny i mimo zadeklarowania referencje mogą nie istnieć (ale nie doszedłem, które są takimi wrażliwymi typami komponentów).

@Resource UserTransaction tx;

Referencje do TransactionSynchronizationRegistry

Interfejs TransactionSynchronizationRegistry może być wykorzystywany przez komponenty systemowe jak zarządcy utrwalania stanu (ang. persistence managers) dla EJB lub komponentów aplikacji internetowych.

Możliwe dekorowanie @Resource albo wyszukanie java:comp/TransactionSynchronizationRegistry w JNDI.

Wstrzelenie lub udostępnienie zasobu w kontekście jest kontrolowane przez serwer aplikacyjny i mimo zadeklarowania referencje mogą nie istnieć (ale nie doszedłem, które są takimi wrażliwymi typami komponentów).

Referencje do szyn ORB

Wstrzelenie za pomocą @Resource lub odszukanie java:comp/ORB w JNDI.

Serwer aplikacyjny musi dostarczyć obiekt do każdego typu komponentu poza appletami.

@Resource ORB orb;

Referencje do jednostek zapisu (ang. persistence unit references)

Udostępnia logiczną nazwę dla fabryki utrwalania stanu komponentów encyjnych.

Jednostki zapisu definiowane są w persistence.xml zgodnie z zasadami opisanymi w specyfikacji Java Persistence API (część specyfikacji Enterprise JavaBeans 3.0).

Pole lub metoda może zostać udekorowana adnotacją @PersistenceUnit. Opcjonalnie można podać nazwę jednostki w JNDI za pomocą elementu name. Element unitName wskazuje na nazwę jednostki jak zdefiniowano w persistence.xml.

@PersistenceUnit
EntityManagerFactory emf;

@PersistenceUnit(unitName="InventoryManagement")
EntityManagerFactory inventoryEMF;
Specyfikacja zaleca, aby wszystkie jednostki utrwalania były dostępne w poddrzewie java:comp/env/persistence.

Deklaracja zależności w deskryptorze instalacji odbywa się poprzez persistence-unit-ref.

Identyczne nazwy jednostek (wykorzystywanych przez różne komponenty) można przypisać do nazw logicznych w deskryptorze instalacji z wykorzystaniem '#' w znaczniku persistence-unit-name.

<persistence-unit-name>
../lib/inventory.jar#InventoryManagement
</persistence-unit-name>

Referencje do kontekstów utrwalania (ang. persistence context references)

Udostępnia logiczną nazwę dla kontekstu utrwalania stanu komponentów encyjnych.

Jednostki zapisu definiowane są w persistence.xml zgodnie z zasadami opisanymi w specyfikacji Java Persistence API (część specyfikacji Enterprise JavaBeans 3.0).

Pole lub metoda może zostać udekorowana adnotacją @PersistenceContext. Opcjonalnie można podać nazwę jednostki w JNDI za pomocą elementu name. Element unitName wskazuje na nazwę jednostki jak zdefiniowano w persistence.xml. Opcjonalny element type wskazuje na rodzaj kontekstu:
  • tranzakcyjny (ang. transaction-scoped) - domyślny
  • rozszeżony (ang. extended)

@PersistenceContext
EntityManager em;
albo

@Resource SessionContext ctx;
...
EntityManager em = (EntityManager) ctx.lookup("persistence/InventoryAppMgr");
Deklaracja w deskryptorze instalacji odbywa się poprzez persistence-context-ref. Istnieje również możliwość zadeklarowania miejsca wstrzelenia zależności poprzez deskryptor instalacji.

23 stycznia 2007

Powrót do Polski, wirtualny JUG, Studencki Festiwal Informatyczny w Krakowie i głosowanie o polskie tłumaczenie annotation

1 komentarzy
Po 2 dniach spędzonych w Wiedniu (Austria) z przyjmnością otworzyłem moją skrzynkę pocztową, w której znalazłem kilka ciekawych wiadomości. Jedną z nich na pewno była inicjatywa założenia wirtualnego JUG, o której pisze na swoim blogu pietruha. Pomysł bardzo mi się spodobał i chciałbym zestawić taką imprezkę w ramach Warszawa JUG (nawet nazwy podobne, jakby stworzone dla siebie ;-)). Zabieram się jutro z samego rana za rozesłanie wiadomości do ludzi od Noc Linuksożerców oraz wierzę, że znajdzie się kilka osób na jdn.pl i Warszawa JUG, którzy pomogą w realizacji pomysłu. Wielkie pomysły rodzą się w wielkich umysłach i pomysł wirtualnego JUGa zdecydowanie zasługuje na miano genialnego. Brawo pietruha!

Druga wiadomość była równie elektryzująca (w pozytywnym tego słowa znaczeniu). Zresztą jej treść sama wyjaśnia mój stan (ufam, że autor zaproszenia nie zechce zdjąć tej części wiadomości z mojego notatnika).

Piszę w imieniu komitetu organizacyjnego Studenckiego Festiwalu Informatycznego w Krakowie, który jest niekomercyjną inicjatywą Naukowych Kół Studenckich czterech największych uczelni tego miasta.

Chciałem spytać, czy zechciałby Pan może uświetnić grono prelegentów naszego festiwalu?

Nie trzeba więcej, aby noc po powrocie do domu była wywrócona do góry nogami. Nie należę do osób lekkiego serca (ang. faint-hearted), ale możliwość uczestniczenia w roli prelegenta na festiwalu jest wyjątkowym wyróżnieniem, które pozytywnie mną wstrząsnęła. Zawsze marzyłem o zaktywizowaniu polskiej społeczności użytkowników technologii Java za pomocą różnego rodzaju spotkań, konferencji, paneli dyskusyjnych, etc., ale nie sądziłem, że będę mógł swoje marzenie realizować z pomocą polskich uczelni. Zaczęło się od warszawskiego MiMUW, następnie zaproszono mnie na Politechnikę Poznańską, a teraz mógłbym uczestniczyć w inicjatywie czterech największych uczelni krakowskich - Akademii Ekonomicznej, Akademii Górniczo-Hutniczej, Politechniki Krakowskiej oraz Uniwersytetu Jagiellońskiego. Czyżby Św. Mikołaj zapomniał o mnie i dopiero teraz wysyła mi prezenty? ;-)

Ostatnia wiadomość, o której chciałem napisać, to napywające do mnie uwagi odnośnie tłumaczeń, jakie stosuje w moim notatniku (aka blogu). Jednym z bardziej kontrowersyjnych słów jest annotation. Moje tłumaczenie - annotacja - wzbudziło wiele uwag o poprawę na adnotacja, z czym nie mogę się zgodzić. Nie pretenduję do miana polskiego tłumacza, więc o wyrażenie opinii poprosiłem społeczność Java na grupie pl.comp.lang.java. Podsumowanie głosowania za 7 dni. Słowo annotation będzie jednym z częściej stosowanym w 2007, więc ujednolicenie jego tłumaczenia znacznie poprawi mój techniczny jezyk. Głosowanie odbywa się w wątku Głosowanie: polskie tłumaczenie słowa annotation.

A tak poza tym, podczas pobytu w Austrii, zabrałem się za lekturę EJB3 Core, ale szybko zanurzyłem się w rozdziale 5. specyfikacji Java EE 5 - Chapter 5: Resources, Naming, and Injection. Zmusiła mnie do tego niewiedza o tym, kto może, a kto nie korzystać z dobrodziejstw wstrzeliwania zależności. Wrażenia dopiero jutro...ekh...już dzisiaj, ale później. Pora spać! (tylko jak tu spać po tym wszystkim?!?!).

28 grudnia 2006

Tworzenie aplikacji Java EE 5 z Eclipse IDE i GlassFish

8 komentarzy
Rozczytując się w specyfikacji JSR 220: Enterprise JavaBeans 3.0, a szczególnie w jej wersji uproszczonej (EJB 3.0 Simplified) postanowiłem sprawdzić, co do zaoferowania ma Eclipse IDE. Do tej pory do tworzenia oprogramowania korzystając z Java EE 5 jako zintegrowane środowisko programistyczne (ang. IDE - integrated development environment) zawsze wybierałem NetBeans IDE 5.5 ze względu na jego zaawansowanie we wsparciu dla tej specyfikacji (bądź służbowo IBM Rational Application Developer V7.0). Skoro wymagania Java EE 5 znacznie zmalały, tj. komponenty EJB mogą być (i zazwyczaj są) dystrybuowane jako pliki jar bez dodatkowych elementów (np. /META-INF/ejb-jar.xml) zmieniają się nasze wymagania dla zintegrowanych środowisk programistycznych. Nadeszła pora, aby sprawdzić, co można stworzyć w Java EE 5 korzystając z Eclipse IDE 3.3 i GlassFish v2.

Nie było lekko. Najwięcej czasu zajęło mi zestawienie działającego środowiska - Eclipse i wtyczki. Okazało się w międzyczasie, że nawet najnowsza wersja GlassFish'a ma swoje niedogodności, więc po 2 dniach ciężkich bojów udało mi się w końcu nie tylko zestawić środowisko, ale również opisać je w moim kolejnym artykule - Tworzenie aplikacji Java EE 5 z Eclipse IDE i GlassFish.

Chętnych zapraszam do lektury (i zgłaszania niedociągnięć, jeśli takie się pojawią).

Wracam tym samym do lektury specyfikacji EJB3 Simplified. Udało mi się, w międzyczasie, przeczytać kolejne 3 rozdziały o komponentach sesyjnych i sterowanych komunikatami, jednakże walka z Eclipse nie pozwoliła mi opisać moich wrażeń. W zasadzie nie ma nic nowego, o czym nie pisałbym poprzednio, więc wiele informacji powtórzyłoby się. Teraz, kiedy ujarzmiłem Eclipse czuję, że i najwyższa pora zakończyć lekturę specyfikacji w jej uproszczonej postaci. Najwyższa pora zabrać się za prawdziwy hard-core - EJB Core Contracts and Requirements! ;-)

29 listopada 2006

Tworzenie aplikacji Java EE 5 z Apache Maven 2 i Glassfish

13 komentarzy
Nie było lekko, ale się udało! Skończyłem artykuł, o który zostałem poproszony jakiś czas temu, a którego tematyka była mi dosyć bliska - skorzystanie z możliwości Apache Maven 2 przy tworzeniu aplikacji Java EE 5. Aplikacja należy do niezwykle nieskomplikowanych, ale sądzę, że tym samym cel został osiągnięty. Demonstracja M2 w roli narzędzia wspomagającego tworzenie aplikacji z JSF 1.2 i EJB 3.0 z uruchomieniem jej na serwerze Glassfish jest do przeczytania w kolejnym artykule na moim Wiki - Tworzenie aplikacji Java EE 5 z Apache Maven 2 i Glassfish.

W nadchodzący wtorek - 5.12 o 18:00 - jest planowane spotkanie grupy Warszawskiej Grupy Użytkowników Java (Warszawa JUG), więc będzie okazja przedyskutować szczegóły. Może nawet uda mi się dokończyć artykuł o facelets. Z pewnością będzie ciekawie móc zaprezentować temat na żywo. Miłej lektury i do zobaczenia!

10 listopada 2006

Pierwsze kroki z Java EE z Glassfish i NetBeans IDE

1 komentarzy
Czyż to nie najwyższa pora zająć się Java EE 5 na poważnie? W zasadzie gdzieś tam trochę człowiek dotyka pewnych elementów tego wydania, ale brak w tym jakiegoś porządku. Postanowiłem ponownie przyjrzeć się technologii Java EE z perspektywy projektu Glassfish, który jest wolnodostępną, referencyjną implementacją specyfikacji.

Zabawę rozpoczynam od pobrania wersji instalacyjnej Glassfish V2 B19. Instalacja jest niezwykle prosta i polega na pobraniu odpowiedniej wersji i uruchomieniu instalera, który jest wykonywalnym plikiem jar (ang. executable jar). Dokładnie jak opisano na https://glassfish.dev.java.net/downloads/v2-b19.html, czyli

 java -Xmx256m -jar glassfish-installer-v2-b19.jar

Cała instalacja zabiera nie więcej niż 2-3 minuty (rozpakowanie paczki i uruchomienie anta). Wykonanie polecenia asadmin start-domain "podnosi" serwer i możemy zaczynać (dla pełnego obrazu dodam, że zatrzymanie serwera to wykonanie polecenia asadmin stop-domain). Komunikat na konsoli informuje o konsoli administracyjnej pod adresem http://localhost:4848 (dobrze, że Firefox zapamiętał hasło, bo nie dałbym rady dostać się do niej). W menu Application nie ma jeszcze żadnej aplikacji, więc koniecznie należałoby rozejrzeć się na stronie projektu w poszukiwaniu przykładowych aplikacji. Ale to już w kolejnych dniach...

Kolejny krok to właśnie uruchomienie przykładowych aplikacji, których spodziewam się, że w projekcie będzie kilka. Pisanie nowych będzie odbywać się w NetBeans IDE 5.5, który mówi się, że jest wielce pomocny przy tworzeniu rozwiązań z Java EE 5 (na codzień używam Eclipse/RAD i minęło już trochę czasu od momentu, kiedy kilkakrotnie w tygodniu otwierałem projekt w NetBeans, więc początek może być bolesny ;-)).

Jeśli udało Ci się stworzyć aplikację korzystając z Java EE napisz, co najbardziej podobało Ci się w nowej specyfikacji, a co najmniej i co sprawiło trudności. Chętnie wysłucham rad bardziej doświadczonych użytkowników Java EE.

Za miesiąc spotkanie Warszawa-JUG i chciałbym móc zaprezentować temat Java EE mając więcej doświadczeń. Wiem, że jest wielu, którzy korzystają z JBoss AS 4.0.5 (z EJB 3.0), czy JBoss Seam i to byłyby z pewnością chwytliwe tematy, ale sądzę, że możliwość porównania dwóch różnych środowisk - Glassfish vs JBoss - może być jeszcze ciekawsze. Powinienem tym samym z łatwością sprowokować ciekawą dyskusję na ten temat.

29 sierpnia 2006

Java EE 5 - wpływ projektów wolnodostępnych na uproszczenie specyfikacji

10 komentarzy
Najnowsza wersja specyfikacji Java Platform Enterprise Edition (w skrócie Java EE czy JEE) to wersja 5. Każda ze specyfikacji wprowadzała użytkownika języka Java w coraz to bardziej zaawansowane arkana sztuki tworzenia aplikacji przemysłowych. Niestety szło to w parze z koniecznością poznania wielu zawiłości specyfikacji składowych (przede wszystkim Enterprise JavaBeans (EJB)). Stanowiło to nie lada wyzwanie nawet dla zaawansowanych programistów.

Jednym z podstawowych problemów nie tylko dla świeżych adeptów poprzednich wersji Java EE (nazywanych poprzednio Java 2 Enterprise Edition - J2EE) było utrzymywanie plików pomocniczych wymaganych przez poszczególne specyfikacje, m.in. deskryptory instalacji i dodatkowe klasy pomocnicze. Ich istnienie było krytykowane, ponieważ nie dostarczały wartości dodanej, a osoby korzystające z usług serwerów aplikacyjnych J2EE musiały borykać się z utrzymywaniem dodatkowych plików, powiązanych jedynie w środowisku uruchomieniowym. Była to bezpardonowa walka nie tylko dla osób dopiero wkraczających na teren J2EE (zauważ na skrót, który wskazuje na wersje specyfikacji wcześniejszych od Java EE 5, np. J2EE 1.4). Szczęśliwie pojawiło się panaceum. Środkiem zaradczym stały się projekty wolnodostępne, np. XDoclet, których cykl wytwórczy był krótszy i wdrożenia udogodnień następowały na bieżąco. XDoclet pozwalał na opisanie kodu źródłowego aplikacji i utworzenie plików pomocniczych automatycznie podczas budowania aplikacji. Opisywanie kodu źródłowego następowało za pomocą znaczników JavaDoc, które precyzowały stosowanie naszych klas. Pozwalało to na znaczne uproszczenie tworzenia aplikacji J2EE kosztem wprowadzenia do cyklu wytwarzania narzędzi pomocniczych. Koszt nie był wielki, a z pewnością zdecydowanie mniejszy niż realizowanie zadania na własną rękę. XDoclet stał się de facto standardem - narzędziem wykorzystywanym podczas tworzenia aplikacji J2EE (świadomie używam skrótu poprzedniej specyfikacji) w każdym zespole, który niwelował potrzebę utrzymywania niezliczonej ilości plików pomocniczych. Ci, którzy nie stosowali XDoclet najczęściej znajdowali inne rozwiązania semi-J2EE. Tak, czy owak stosowanie J2EE sprowadziło się głównie do budowania aplikacji z użyciem Java Servlets i JavaServer Pages (choć i dla nich znaleziono również alternatywne rozwiązania). Szczęśliwie, zalety stosowania narzędzi wspierających tworzenie aplikacji, jak XDoclet, dostrzeżono nie tylko w zespołach rozwijających specyfikację Java 2 Enterprise Edition, ale również i samego języka Java. W najnowszej produkcyjnej odsłonie języka Java SE 5 wprowadzono mechanizm anotacji (ang. annotations) zwanego również meta-danymi. Tym samym anotacje stały się częścią języka Java, co powodowało, że stał się on powszechnie stosowanym rozwiązaniem opisu kodu źródłowego na podstawie, którego można tworzyć inne artefakty projektowe, np. deskryptory instalacji. Ważny podkreślenia jest fakt udostępnienia tego mechanizmu nie tylko dla osób związanych z platformą Java EE, ale przede wszystkim Java SE (Java Standard Edition 5), czyli w samym języku Java (!) Zaletę stosowania anotacji każdy z nas, programujących w Javie, dostrzegł już wcześniej korzystając ze znaczników JavaDoc do opisywania kodu źródłowego. W ten sposób tworzono dodatkowy artefakt projektowy jakim jest dokumentacja publicznego interfejsu (API) projektu. Za pomocą JavaDoc, niewielkim kosztem można stworzyć dokumentację, której układ i znaczenie znane są każdemu użytkownikowi aplikacji Java. Dla wielu, problemy związane z dokumentacją już nie istnieją, albo sprowadzają się jedynie do utrzymywania JavaDoc (co i tak niestety jeszcze dla wielu stanowi wyzwanie). Grupa standaryzująca specyfikację Java EE 5 wykorzystała dobrodziejstwa płynące z wdrożenia anotacji do opisywania klas tak, aby na ich podstawie utworzyć pozostałe części składowe aplikacji JEE. Życie twórcy aplikacji przemysłowych w Javie stało się zauważalnie prostsze. Na uwagę zasługuje fakt, że stosowanie anotacji stało się tak popularne, że już nie ma osób, które nie korzystają, albo nie planują z nich skorzystać. W naturalny sposób programiści języka Java nabyli użytecznej umiejętności utrzymywania dodatkowych, zewnętrznych plikach aplikacji w ryzach implementacyjnych bez konieczności nauki dodatkowej (i zazwyczaj niepotrzebnej) wiedzy o niskopoziomowych zasadach działania specyfikacji J2EE (ponownie uwaga na akronim). W zasadzie można było stwierdzić, że stosowanie J2EE "zanieczyszczało" nam nasz projekt i dlatego stosowanie projektów wolnodostępnych jako antidotum na bolączki wdrożenia zasad J2EE zdobywało uznanie. Powoli znikały "czyste" aplikacje J2EE i pojawiały się rozwiązania alternatywne, łatwiejsze w implementacji i utrzymaniu. Serwer aplikacyjny J2EE stał się jedynie zbędnym dodatkiem do środowiska uruchomieniowego udostępniającym wiele z usług, których użycie sprowadzało się do wykorzystania kontenera serwletów (jako łącznika ze światem zewnętrznym) i zarządcy transakcji. Reszta istniała bez większego wykorzystania.

"Wpływowych" projektów wolnodostępnych rewolucjonizującymi tworzenie aplikacji przemysłowych z wykorzystaniem języka Java było wiele. Na uwagę jednakże zasługują dwa: Hibernate oraz Spring Framework. Nie były doskonałe, ale ich wdrożenie nie nastręczało trudności i stosunkowo szybko reagowały na zmieniające się wymagania użytkowników (w przeciwieństwie do serwerów aplikacyjnych J2EE nie wspominając już samej specyfikacji J2EE). Oba uzupełniają się i tworzą kompletną platformę do tworzenia aplikacji przemysłowych poza ramami J2EE. Oba projekty były odpowiedzią na rosnącą komplikację i trudność w pomyślnym zastosowaniu specyfikacji J2EE (ponowie uwaga na skrót). I na szczęście oba wpłynęły na ostateczny wizerunek specyfikacji Java EE 5. Pierwszy z nich Hibernate był podwaliną dla powstania uproszczonej specyfikacji Enterprise JavaBeans (EJB) w wersji 3.0 w obszarze nazywanym Java Persistence, natomiast drugi Spring Framework upowszechnił stosowanie wzorca Wstrzeliwanie Zależności (ang. DI = Dependency Injection bądź IoC = Inversion Of Control). Oba korzystały z udogodnień wprowadzanych "u innych", aż wypracowano niepisany standard korzystania z rozwiązań specyfikacji JavaBeans (nie mylić ze specyfikacją Enterprise JavaBeans!) dostępnych bezpośrednio w języku Java do tworzenia aplikacji. I to bez konieczności wdrażania serwerów aplikacyjnych J2EE, które były trudne w administracji a ilość informacji do przyswojenia "wykańczała" niejeden zespół projektowy. Pojawił się termin POJO.

POJO (ang. Plain Old Java Object), czyli stary, dobry obiekt Javy jest klasą Javy ze zbiorem metod do ustawiania i pobierania właściwości obiektu (tzw. settery i gettery). Brak wymagania na dziedziczenie klas, czy implementację interfejsów szkieletu programistycznego (ang. framework) był strzałem w dziesiątkę. Krzywa uczenia znacznie się spłaszczyła, a zalet stosowania POJO nie trzeba było nikomu przedstawiać. Zacznijmy od najważniejszej - brak wplatania własnych klas w hierarchię klas wykorzystywanego szkieletu, np. tak jak to było na platformie J2EE. Brak konieczności realizacji interfejsów i klas pomocniczych uniezależnia aplikację od docelowego środowiska uruchomieniowego. Korzystanie z POJO pozwala na tworzenie aplikacji w zespołach, których jedynym tematem dyskusji jest realizacja wymagań biznesowych a nie wymagań tej czy innej platformy. Temat wdrożenia aplikacji na daną platformę uruchomieniową pozostawiany jest architektom i administratorom. Zespół programistów koncentruje się wyłącznie na aspektach biznesowych projektu a nie implementacyjnych docelowej platformy. Mimo tak oczywistych zalet istnieje jeszcze jedna, często tak oczywista, że się o niej po prostu zapomina. Każdy programista Java potrafi stworzyć POJO. Nie ma potrzeby wdrażać zespołów do stosowania POJO (chyba że, aby zastosować szkolenie jako terapię wstrząsową po wielomiesięcznych projektach J2EE). Technologia JavaBeans istniała od zawsze w Javie, przede wszystkim w arsenale programistów aplikacji graficznych, ale teraz powraca do łask twórców aplikacji przemysłowych. Istnienie rozwiązań opartych o POJO wymaga jednakże specjalizowanego środowiska, którym nie był serwer aplikacyjny J2EE (ponownie uwaga na skrót). Wymagano kontenerów IoC/DI, które wstrzeliwały zadeklarowane zależności. Można powiedzieć, że podobnie było w przypadku serwerów J2EE, gdzie deklarowało się zależność w deskryptorze instalacji, z tą jednak różnicą, że w kontenerze IoC wystarczy jedynie dostarczyć publiczny setter bądź odpowiedni konstruktor i otrzymuje się gotową do użycia zależność (bez jej wyszukiwania jak to miało miejsce w J2EE, np. wyszukiwanie komponentów EJB w JNDI). Wraz z wdrożeniem kontenera IoC i zastosowania POJO w projekcie, kod korzystający ze specyficznych rozwiązań środowiska zewnętrznego maleje. Operujemy wyłącznie na publicznym interfejsie, co dodatkowo go uelastycznia. Wynika to ze sposobu działania kontenera IoC - zadeklarowana zależność za pomocą anotacji (preferowany sposób), czy pliku konfiguracyjnego musi być dostępna zanim aplikacja zostanie w pełni uruchomiona. Druga zaleta to brak konieczności wyszukiwania zależności. To nie aplikacja ich szuka, ale kontener, który podaje je (wstrzeliwuje) podczas inicjalizacji aplikacji. Stąd bierze się określenie wzorca programowania - Odwórcenie kontroli znanego również jako Wstrzeliwanie zależności. Z nim związana jest zasada nazwana Hollywood Principle, które odzwierciedla istotę jego działania (jak i istnienia samego Hollywood): Don't call us we'll call you, co oznacza Nie dzwoń do nas, to my zadzwonimy do Ciebie. W kontenerze IoC nasza aplikacja deklaruje zależności i ich oczekuje. Wstrzeliwanie zależności odbywa się za pomocą konstruktora (podczas tworzenia obiektu jeden z parametrów jest zależnością), albo za pomocą metody-settera (po stworzeniu obiektu wywoływany jest setter zanim nastąpi wywołanie innych metod biznesowych). Zalety stosowania zasady Hollywood (m.in. w Spring Framework) dostrzeżono w grupie standaryzującej platformę Java EE 5 i wdrożono ją m.in. w specyfikacji JavaServer Faces (nowość w specyfikacji Java EE, gdzie - obok Java Servlets i JavaServer Pages - jest kolejnym szkielet do budowania aplikacji internetowych, aczkolwiek specyfikacja wykracza poza zakres środowiska aplikacji internetowych), czy Enterprise JavaBeans (komponenty biznesowe reprezentujące procesy biznesowe, w tym i trwałe dane aplikacji przy współpracy innych usług serwera aplikacyjnego JEE, m.in. usługi bezpieczeństwa, czy monitorowania transakcji).

Kolejną innowacją w środowisku Java EE 5, która wspaniala spisywaly się na rynku aplikacji pisanych w języku Java na długo zanim sfinalizowano specyfikację JEE było uproszczenie zarządzania trwałymi danymi. Prym w tej dziedzinie wiódł projekt Hibernate (rozwiązanie należące do rodziny JBoss Enterprise Middleware Suite (JEMS)). Prostota dostępu i modyfikacji danymi trwałymi przechowywanymi w relacyjnych bazach danych za pomocą Hibernate była wprost porażająca w porównaniu z wykorzystaniem niezwykle skomplikowanego rozwiązania Enterprise JavaBeans 2.1, a szczególnie jej części dotyczącej dostępu do danych - Container-Managed Persistence (CMP) entity beans. Komponenty CMP są komponentami biznesowymi, które odpowiadają za obiektową reprezentację relacyjnych danych. Zastosowanie J2EE (uwaga na skrót) wymagało serwera aplikacyjnego, gdzie otrzymywano skomplikowany mechanizm dostępu do relacyjnych danych podczas, gdy Hibernate nie narzucał takich obostrzeń i mógł być stosowany i w aplikacjach desktopowych i przemysłowych, czyli wszędzie. Jedynym zauważalnym problemem było poznanie produktu Hibernate (poza , które nie było trywialne, ale alternatywą było stosowanie jeszcze bardziej nietrywialnych komponentów CMP (rozpatrując jedynie Hibernate i J2EE) i to wyłącznie w pewnych zastosowaniach - wyłącznie w rozwiązaniach przemysłowych. W aplikacjach desktopowych realizację dostępu do bazy danych dostarczał standardowy mechanizm JDBC, który jednak był zbyt niskopoziomowy w stosunku do możliwości Hibernate. Te i inne dobrodziejstwa Hibernate spowodowały odejście programistów Java od stosowania kolejnego ustandaryzowanego rozwiązania J2EE. Hibernate, podobnie jak Spring Framework, korzysta z POJO, aby "przenosić" dane obiektowe z i do relacyjnej bazy danych. Oba rozwiązania współpracują ze sobą, co stanowiło poważną alternatywę dla platformy J2EE. Z wprowadzeniem specyfikacji JEE (uwaga - zmiana akronimu) wielu programistów zapewne ponownie rozpatrzy zastosowanie Spring Framework + Hibernate versus platforma Java EE 5 szczególnie, że Hibernate realizuje specyfikację Java Persistence i może występować w roli dostawcy usługi. Byłoby niestosownym nie wspomnieć o możliwości uruchomienia implementacji Java Persistence poza środowiskiem Java EE, więc nasze aplikacje staną się jeszcze bardziej modularne i jedynie jednym z wielu implementacji (a nie jedyną) stanie się Hibernate. Spodziewam się przechylenia szali zainteresowania ze stosowania Hibernate na rzecz ustandaryzowanych rozwiązań realizujących specyfikację Java Persistence, którą pokreślam jedną z wielu jest Hibernate.

Nie sądzę, aby pojawienie się serwerów zgodnych ze specyfikacją Java EE 5 spowodowało znaczny spadek zainteresowania rozwiązaniem Spring Framework + Hibernate, czy podobnych. Sądzę jednak, że najnowsza odsłona platformy Java EE 5 stanowi interesującą alternatywę dla tego zestawienia. Wykorzystanie w JEE konstrukcji dostępnych bezpośrednio w języku Java do budowania aplikacji przemysłowych znacznie zmniejszy wymagania początkowe dla poznania specyfikacji Java EE 5 i znacząco zwiększy zainteresowanie platformą programistów innych rozwiązań, a nawet języków programowania. Taki stan rzeczy musi przełożyć się na jeszcze większą konkurencyjność projektów wolnodostępnych i ich komercyjnych odpowiedników. Nadszedł czas na zapoznanie się z Java EE 5 w praktyce.