- Rozpoczynamy instalując JBoss Seam 1.1.0 GA i budując przykładową aplikację, która znajduje się w katalogu examples/glassfish. Zbudowanie aplikacji to wykonanie polecenia ant.
C:\apps\jboss-seam-1.1.0.GA\examples\glassfish>ant
Buildfile: build.xml
compile:
[mkdir] Created dir: C:\apps\jboss-seam-1.1.0.GA\examples\glassfish\build\classes
[javac] Compiling 23 source files to C:\apps\jboss-seam-1.1.0.GA\examples\glassfish\build\classes
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
ejb3jar:
[jar] Building jar: C:\apps\jboss-seam-1.1.0.GA\examples\glassfish\build\jboss-seam-glassfish.jar
war:
[war] Building war: C:\apps\jboss-seam-1.1.0.GA\examples\glassfish\build\jboss-seam-glassfish.war
ear:
[ear] Building ear: C:\apps\jboss-seam-1.1.0.GA\examples\glassfish\build\jboss-seam-glassfish.ear
main:
BUILD SUCCESSFUL
Total time: 4 seconds - Uruchamiamy GlassFish i bazę danych dostarczaną razem z nim.
asadmin start-database
asadmin start-domain domain1 - Przystępujemy do instalacji aplikacji wykonując polecenie
asadmin deploy --host localhost --port 4848 jboss-seam-glassfish.ear
- Uruchomienie aplikacji to otwarcie strony http://localhost:8080/jboss-seam-glassfish.
29 grudnia 2006
JBoss Seam z GlassFish - cóż za bezproblemowe uruchomienie!
28 grudnia 2006
Tworzenie aplikacji Java EE 5 z Eclipse IDE i GlassFish
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! ;-)
26 grudnia 2006
Dokończenie rozdziału 3 specyfikacji EJB3 - 3.4 Interceptors
Termin interceptor pojawia się po raz pierwszy w specyfikacji EJB właśnie w wydaniu 3. Nie jest to jednak pojęcie nowe w świecie programowania. Idea interceptorów została zapożyczona z podejścia programistycznego opartego o aspekty z Aspect-Oriented Programming (AOP). Nie chciałbym rozpisywać się o aspektach, które same w sobie wymagałyby osobnej pozycji w moim dzienniku, ale zrozumienie aspektów to zrozumienie interceptorów, więc kilka słów znacznie pomoże w temacie. Po więcej informacji zapraszam do lektury The AspectJ 5 Development Kit Developer's Notebook.
Aspekt jest pewną funkcjonalnością, która niekoniecznie związana jest z działaniem biznesowym aplikacji. Modelowanie aplikacji oparte o aspekty wprowadza dodatkowy element modularyzacji dostarczając zestaw rozszerzeń (coś na kształt wtyczek) do podstawowej wersji aplikacji. Najczęstszymi przykładami aspektów są funkcjonalności rozbudowujące aplikację (a raczej jej funkcje biznesowe) o funkcje audytowe (ang. logging), bezpieczeństwo, czy obsługę transakcji. Jakkolwiek dwa ostatnie są dostarczane przez serwer aplikacyjny to pierwszy z nich - funkcje audytu - nie istnieje (lub innymi słowy, nie jest częścią specyfikacji Java EE, a jedynie serwera aplikacyjnego, stąd specyficzne dla niego i potraktowane przeze mnie jako nieistniejące).
Po lekturze rozdziału 3.4 Interceptors interceptory wydają się być dla mnie okrojonymi aspektami, tj. możliwości aspektów w dojrzałych szkieletach programistycznych AOP (np. AspectJ) znacznie przewyższają możliwości interceptorów w EJB3.
Czym zatem jest interceptor w sensie specyfikacji EJB3?
Interceptor jest metodą, która przechwytuje wywołanie metody biznesowej (metody z interfejsu biznesowego) lub zdarzenia zwrotnego związanego z etapem życia komponentu (bardzo podobne do nasłuchiwaczy - ang. listeners). Interceptor może być zdefiniowany na klasie komponentu bądź we własnej, dedykowanej klasie interceptora związanej z komponentem. Klasa interceptora to klasa zawierająca interceptory. Zabronione jest, aby klasa interceptora była jednocześnie komponentem EJB. Pojęcie interceptorów związane jest wyłącznie z komponentami sesyjnymi i sterowanymi komunikatami, i nie występuje dla komponentów encyjnych. Istnieje możliwość zdefiniowania interceptora metod biznesowych do wszystkich metod biznesowych komponentu bądź dla dowolnego ich podzbioru.
Klasa interceptora związana jest z klasą komponentu EJB za pomocą annotacji @Interceptors lub w deskryptorze instalacji - ejb-jar.xml. Pojawia się pojęcie domyślnych interceptorów, czyli interceptorów, które związane są ze wszystkimi komponentami sesyjnymi i sterowanych komunikatami zdefiniowanymi w deskryptorze instalacji wraz z definicją samych interceptorów. Brzmi bardzo zagmatwanie i oznaczyłem do dalszego sprawdzenia.
Nie ma ograniczenia dla liczby interceptorów zdefiniowanych dla pojedyńczej klasy komponentu EJB. Kolejność wykonywania interceptorów wyznaczana jest przez kolejność ich deklaracji w klasie komponentu i deskryptorze instalacji (jak ostatecznie tworzona jest kolejność pozostaje do sprawdzenia, choć wydaje się, że najpierw te zadeklarowane przez annotacje, a później przez deskryptor instalacji - choć może...ech..zostawiam to na później). Kolejność wykonywania jest o tyle istotna, że mimo, że interceptory są bezstanowe, to mają one dostęp do zasobów środowiska serwera, do których dostęp ma komponent EJB, więc i drzewa JNDI, w którym możnaby umieszczać informacje (ot, taki niezalecany efekt poboczny - ang. side-effect - wykonania bezstanowego interceptora). Poza tym istnieje również InvocationContext, o którym za moment, a który może służyć do komunikacji między interceptorami.
Klasa interceptora musi posiadać publiczny bezargumentowy konstruktor (dla przypomnienia: kompilator dostarcza go, jeśli nie istnieje żaden inny konstruktor w klasie, więc sprawa bardzo się upraszcza, jesli tylko sami nie będziemy chcieli jej skomplikować ;-)).
Następnie sekcja 3.4 przechodzi do omówienia zasad związanych z interceptorami (jakby tych już wspomnianych było mało). Mowa jest o kontekstach transakcyjnym i bezpieczeństwa, które są identyczne z tymi aktualnie związanymi z wywoływaną metodą biznesową, dla której one są wywoływane, wyjątkach identycznych z tymi zadeklarowanymi w metodach biznesowych, możliwością wywołania innych usług dostępnych dla komponentu EJB, wsparciu dla wstrzeliwania zależności i ostatecznie kończy się na ograniczeniach interceptorów, które są identyczne z ograniczeniami komponentów EJB. Innymi słowy można traktować interceptory jako metody biznesowe komponentu EJB, dla którego zostały zdefiniowane, z tym, że wywoływane są wcześniej, dodatkowo do wywołania metody biznesowej komponentu.
Dalej rozdział przechodzi do prezentacji 2 rodzajów interceptorów:
- interceptor zdarzenia zwrotnego związanego z etapem życia komponentu (w skrócie interceptor zwrotny) (ang. lifecycle callback interceptor)
- interceptor metody biznesowej (ang. business method interceptor)
void <NazwaMetody>()
, a dla dedykowanej klasy interceptora jest:
void <NazwaMetody>(InvocationContext)
Metody mogą być dowolnej widoczności (public, protected, private, domyślny). Niedopuszczalne jest deklaracja interceptora zwrotnego jako final lub static (przypomniam, że interceptor to metoda instancji w Javie).
Te same annotacje opisujące interceptor zwrotny (dalej zwane zwrotnymi) są stosowane w klasie komponentu EJB i klasie interceptora (za pomocą annotacji @PostConstruct, @PreDestroy, @PostActivate, @PrePassivate). Ta sama metoda może być udekorowana różnymi annotacjami zwrotnymi.
Zabronione jest wielokrotne użycie tej samej annotacji zwrotnej w danej klasie komponentu.
Drugi z interceptorów - interceptor metody biznesowej - jest definiowany przez annotację @AroundInvoke lub element around-invoke w deskryptorze instalacji dla metod biznesowych (należących do interfejsu biznesowego) komponentów sesyjnego i sterowanymi komunikatami. Jedynie pojedyńcza metoda udekorowana @AroundInvoke może istnieć w klasie komponentu lub w danej klasie interceptora. Zabronione jest, aby metoda udekorowana przez @AroundInvoke była metodą biznesową.
Wywołanie metody biznesowej wyzwala (jest przechwycone przez) metody klasy komponentu udekorowane przez AroundInvoke jak i klasy interceptorów. Wywołanie metody @AroundInvoke musi pociągać za sobą wywołanie metody InvocationContext.proceed() albo związana metoda biznesowa nie zostanie wywołana jak i kolejne metody @AroundInvoke.
Metody @AroundInvoke mają następującą sygnaturę:
public Object <NazwaMetody>(InvocationContext) throws Exception
Na zakończenie sekcji 3.4 dotyczącej interceptorów opisano klasę javax.interceptor.InvocationContext, który udostępnia kontekst wykonania dla interceptorów (i który wspomniany był kilkakrotnie wcześniej). Identyczna instancja InvocationContext jest przekazywana do każdego interceptora dla danej metody biznesowej lub zdarzenia związanego z etapem życia komponentu i pozwala na przekazywanie informacji między interceptorami.
Najważniejsza z metod w klasie InvocationContext to
public Object proceed() throws Exception
, która powoduje wywołanie kolejnego interceptora bądź, kiedy wywołana przez ostatni z interceptorów, metody biznesowej.
Kolejny rozdział specyfikacji EJB3 za mną - Chapter 3: Enterprise Bean Class and Business Interface
Co wniosła do mojej wiedzy lektura rozdziału 3. Enterprise Bean Class and Business Interface specyfikacji EJB 3.0 Simplified API?
Rozdział 3 omawia te elementy specyfikacji EJB3, które są wspólne dla komponentów sesyjnych (ang. SB - session beans) i sterowanych komunikatami (ang. MDB - message-driven beans). Pojawia się również notka, która stwierdza, bardzo istotną z punktu widzenia osób tworzących rozwiązania oparte o poprzednie wersje specyfikacji EJB 2.1 i poprzednich, że komponenty encyjne nie są już w zasadzie komponentami EJB jak to miało miejsce poprzednio i stąd też osobny dokument na ich temat - Java Persistence API oraz brak omówienia w tym rozdziale.
Część informacji była już omówiona bardzo pobieżnie w poprzednich rozdziałach, stąd niektóre informacje wydają się być znajome (nawet dla nie-praktyków EJB3, którzy jednak śledzili poprzednie moje relacje).
Tworzenie modułu EJB rozpoczyna się od stworzenia interfejsu biznesowego, np.:
package pl.jaceklaskowski.exam.scheduler;
import java.util.List;
import pl.jaceklaskowski.exam.beans.Exam;
public interface ExamScheduler {
List<Exam> getExams();
}
, a następnie realizacji jego przez klasę komponentu EJB (ang. enterprise bean class),np.
package pl.jaceklaskowski.exam.scheduler;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import pl.jaceklaskowski.exam.beans.Exam;
@Stateless
public class ExamSchedulerBean implements ExamScheduler {
private final List<Exam> exams = new ArrayList<Exam>();
public List<Exam> getExams() {
return exams;
}
}
W przeciwieństwie do poprzednich wersji specyfikacji EJB, rolę aktywującą funkcjonalność modułu EJB stanowią przede wszystkim annotacje jako dodatkowy mechanizm konfiguracji poza osobno utrzymywanym, zewnętrznym deskryptorem instalacji - ejb-jar.xml. Annotacje, jako mechanizm dostarczany przez Java SE, służy do opisu modułu, jego wymagań i zależności od środowiska uruchomieniowego bezpośrednio w klasie komponentu EJB. Jedyną wymaganą annotacją klasy komponentu EJB jest deklaracja typu (jeśli takowa informacja nie została zawarta w deskryptorze instalacji).
Wyróżniamy następujące annotacje typów komponentu:
- @Stateless - bezstanowy komponent sesyjny
- @Stateful - stanowy komponent sesyjny
- @MessageDriven - komponent sterowny komunikatami
Specyfikacja EJB3 określa, że interfejs biznesowy komponentu EJB to dowolny interfejs w Javie poza:
- java.io.Serializable
- java.io.Externalizable
- dowolnym interfejsem z pakietu javax.ejb
które nie biorą udziału w wyznaczaniu interfejsów lokalnych i/lub zdalnych.
Nie ma konieczności implementacji interfejsów javax.ejb.EJBObject czy javax.ejb.EJBLocalObject, jak to miało miejsce w poprzedniej wersji specyfikacji (choć taka możliwość istnieje ze względu na wsteczną zgodność). I komponenty sesyjne i sterowane komunikatami wymagają co najmniej jednego interfejsu biznesowego (gdzie interfejs komponentu sterowanego komunikatami to zazwyczaj wskazanie na rodzaj obsługiwanej usługi, np. javax.jms.MessageListener dla JMS).
Ciekawym stwierdzeniem jest, że klasa główna komponentu nie musi implementować własnego interfejsu biznesowego. Jak dalej napisano, można tak udekorować klasę (bądź skorzystać z konfiguracji poprzez deskryptor instalacji), że interfejs biznesowy będzie realizowany przez inną klasę i będzie on nadal jej interfejsem biznesowym. Trochę to pogmatwane i nie jestem w stanie sobie tego wyobrazić, więc spodziewam się wyjaśnienia w kolejnych rozdziałach.
Skoro klasa komponentu EJB musi posiadać co najmniej jeden interfejs biznesowy (lokalny lub zdalny), to:
- pojedyńczy interfejs realizowany przez nią zakłada się, że jest interfejsem biznesowym lokalnym chyba, że zadeklarowano inaczej poprzez annotację @Remote na klasie lub interfejsie (lub alternatywnie przez deskryptor instalacji - ejb-jar.xml). Domyślnie zakłada się, że występuje annotacja @Local.
- Posiadanie więcej niż jednego interfejsu lokalnego czy zdalnego wymaga ich oznaczenia za pomocą annotacji @Local lub @Remote na klasie komponentu lub interfejsie bądź poprzez deskryptor instalacji.
- Zabronione jest oznaczanie interfejsu biznesowego jednocześnie jako lokalnego i zdalnego, w tym również sytuacja niespójnej deklaracji @Local czy @Remote na klasie komponentu i interfejsie, tj. jeśli annotacja widoczności występuje na interfejsie biznesowym, to jeśli występuje ona również na klasie komponentu to ich wartości muszą być identyczne.
- Zabronione jest deklarowanie interfejsu biznesowego, który rozszerza javax.ejb.EJBObject lub javax.ejb.EJBLocalObject.
Poniższy przykład ilustruje kilka z wymienionych wyżej wymagań.
package pl.jaceklaskowski.exam.manager;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import pl.jaceklaskowski.exam.beans.Exam;
import pl.jaceklaskowski.exam.beans.Note;
@Stateless
@Local(ExamScheduler.class)
@Remote(ExamVerifier.class)
public class ExamControllerBean implements ExamScheduler, ExamVerifier {
private final List<Exam> exams = new ArrayList<Exam>();
public List<Exam> getExams() {
return exams;
}
public Note verify(Exam exam, Set<String> answers) {
return exam.verify(answers);
}
}
Kolejne uproszczenie specyfikacji EJB3 dotyczy wyjątków. Metody interfejsu biznesowego mogą deklarować (poprzez słowo kluczowe throws) dowolne wyjątki aplikacyjne za wyjątkiem java.rmi.RemoteException, który jest opakowywany przez javax.ejb.EJBException przez serwer aplikacyjny, w przypadku problemów niskopoziomowych.
Specyfikacja przechodzi do omówienia interceptorów. Temat zajmuje aż 3 strony specyfikacji, co w porównaniu z poprzednimi tematami w tym rozdziale stanowi solidną dawkę informacji do przyswojenia. Postanowiłem pozostawić sobie przyjemność opisania go w kolejnej relacji po próbie zrozumienia tematu na przykładach.
Rozdział kończy się bardzo krótką wzmianką dotyczącą interfejsów domowych, które...znikają na dobre. Grały one kluczową rolę w poprzedniej wersji specyfikacji EJB 2.1 i poprzednich podczas, gdy teraz mamy do dyspozycji mechanizm wstrzeliwania zależności (realizowanego poprzez annotacje) w przypadku komponentów sesyjnych, a komponenty encyjne tworzy się za pomocą mechanizmu powoływania instancji klasy w Javie, tj. słowa kluczowego new.
Dla przypomnienia, komponenty sterowane komunikatami (MDB), ze względu na swoją specyfikę działania, nie miały interfejsu domowego już w poprzednich wersjach specyfikacji.
24 grudnia 2006
Wigilia i kolejny rozdział specyfikacji EJB3 - Chapter 2: Overview of the EJB 3.0 Simplified API
Do tych już wspomnianych w rozdziale 1. (które opisałem wczoraj) dodać można:
- Tworzenie modułów EJB nie wymaga tworzenia dodatkowych, specyficznych dla serwera aplikacyjnego, klas przed właściwą ich instalacją na serwerze. Innymi słowy: nie ma konieczności uruchamiania narzędzia dostarczanego przez serwer aplikacyjny generującego klasy pomocnicze dla modułów EJB. Klasy konieczne do uruchomienia modułów EJB tworzone są dynamicznie podczas uruchamiania przez serwer.
- Nie ma konieczności rozszerzania klas należących do EJB API czy dostarczania klas wymaganych przez specyfikację EJB, np. rozszerzanie (nie wprost) javax.ejb.EnterpriseBean.
Poniżej znajduje się przykład kompletnego bezstanowego komponentu sesyjnego implementującego biznesowy interfejs lokalny pl.jaceklaskowski.ejb.ExamScheduler.package pl.jaceklaskowski.ejb;
gdzie pl.jaceklaskowski.ejb.ExamScheduler to:
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import pl.jaceklaskowski.ejb.interceptor.ParameterLogger;
@Stateless
public class ExamSchedulerBean implements ExamScheduler {
public List<Exam> getExams() {
List<Exam> exams = new ArrayList<Exam>();
exams.add(new Exam("Programowanie obiektowe"));
return exams;
}
}package pl.jaceklaskowski.ejb;
Instalacja komponentu ExamSchedulerBean to stworzenie pliku jar zawierającego obie klasy i umieszczenie go na serwerze aplikacyjnym. W poprzednich wersjach specyfikacji EJB 2.1 i wcześniejszych, między nimi występował jeszcze krok tworzenia klas specyficznych dla serwera aplikacyjnego. Krok był zależny od zastosowanego serwera, więc próba uruchomienia komponentu EJB wymagała wykonania go narzędziami dostarczanymi przez serwer (i wymagało zdecydowanie więcej wiedzy na temat środowiska poza znajomością samej specyfikacji EJB).
import java.util.List;
public interface ExamScheduler {
List<Exam> getExams();
} - Konfiguracja komponentów EJB opiera się na ustandaryzowanych wartościach domyślnych, które można modyfikować poprzez udekorowanie kodu komponentów przez annotacje, bądź alternatywnie za pomocą pliku ejb-jar.xml. Wprowadzono nowy termin związany z konfiguracją komponentów EJB, tj. konfiguracja przez nadpisywanie (ang. configuration by exception), która określa podejście do konfiguracji EJB, gdzie podane są wyłącznie parametry konfiguracyjne nadpisujące wartości domyślne.
Ważną kwestią jest wyznaczenie ostatecznej wartości parametru EJB. Mamy do dyspozycji (w kolejności ich rosnącej ważności):- możliwość pozostania przy konfiguracji domyślnej
- nadpisania jej annotacjami
- skorzystanie z deskryptora konfiguracji - ejb-jar.xml.
Jest to przydatne w trakcie tworzenia aplikacji, gdzie można nadpisywać parametry za pomocą pliku ejb-jar.xml, a podczas produkcyjnej instalacji zaniechać jego dołączania i pozostania przy wartościach annotacji czy domyślnych. - Tworzenie komponentów EJB sprowadziło się do stworzenia metod ważnych dla programisty, a nie serwera aplikacyjnego, tj. nie ma konieczności dostarczania metod typu ejbCreate tylko i wyłącznie dla spełnienia wymagań serwera. Jeśli metody nie istnieją, kontener EJB dostarczy własne implementacje w trakcie działania.
- Dowiązanie do zdalnego interfejsu biznesowego (ang. remote business interface) nie wymaga odszukania interfejsu domowego komponentu EJB, a następnie utworzenia instancji. W EJB3 uproszczono mechanizm dowiązania do pobrania interfejsu zdalnego bezpośrednio.
- Dowiązania do innych komponentów i zasobów środowiska odbywa się poprzez annotacje (lub deskryptor instalacji). Wystarczy zadeklarować zależność za pomocą annotacji zmiennej prywatnej, która będzie reprezentować zależność, np. fabrykę instancji typu EntityManager (EntityManagerFactory), a kontener EJB poprzez mechanizm wstrzeliwania zależności (ang. dependency injection) zainicjuje zmienną do odpowiedniej wartości. Wyłącznie w pełni skonstruowana (zainicjowana) aplikacja z dostępnymi wszystkimi zależnościami będzie uruchomiona. W przypadku błędów inicjalizacji samych komponentów EJB, bądź powiązań między nimi, bądź ostatecznie części aplikacji deklarującej zależność z komponentami EJB serwer aplikacyjny nie uruchomi aplikacji.
Załóżmy aplikację przemysłową (ang. enterprise application), która składa się z aplikacji internetowej (która z kolei składa się z servletu) oraz modułu EJB (który składa się z bezstanowego komponentu sesyjnego ExamSchedulerBean zaprezentowanego powyżej). Specyfikacja EJB3 uprościła sposób dostępu (dowiązania) servletu do komponentu EJB w następujący sposób:package pl.jaceklaskowski.servlet;
import java.io.IOException;
import java.util.List;
import javax.ejb.EJB;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pl.jaceklaskowski.ejb.Exam;
import pl.jaceklaskowski.ejb.ExamScheduler;
public class ExecuteEjbServlet extends HttpServlet {
@EJB
private ExamScheduler examScheduler;
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<Exam> exams = examScheduler.getExams();
request.setAttribute("exams", exams);
RequestDispatcher rd = getServletContext().getRequestDispatcher("/index.jsp");
rd.forward(request, response);
}
}
Na uwagę zasługuje udekorowanie prywatnej zmiennej instancji examScheduler annotacją @EJB, która za pomocą wykorzystanego interfejsu ExamScheduler wskazuje serwerowi aplikacyjnemu, który komponent EJB jest potrzebny. - Wprowadzenie interceptorów (ang. interceptors), które wprowadzają możliwości aspektów (ang. aspects) z Aspect-Oriented Programming (AOP) do świata komponentów EJB, gdzie można zadeklarować wykonanie metody interceptora wraz z wykonaniem metody komponentu EJB.
Poniżej znajduje się klasa z metodą oznaczoną annotacją @AroundInvoke, za pomocą której wskazuje się metody biorące udział w mechaniźmie interceptorów.package pl.jaceklaskowski.ejb.interceptor;
Wywołanie metody powyższej klasy w komponencie EJB wiąże się z udekorowaniem klasy bądź metody klasy annotacją @Interceptors z obowiązkowym parametrem wskazującym na klasę interceptora.
import java.lang.reflect.Method;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
public class ParameterLogger {
@AroundInvoke
public Object printArgs(InvocationContext ic) throws Exception {
Object target = ic.getTarget();
Method m = ic.getMethod();
Object[] params = ic.getParameters();
System.out.printf("Parametry wywołania metody %s.%s %n", target.getClass().getName(), m.getName());
if (params != null) {
for (Object param: params) {
System.out.printf("- %s %n", param);
}
} else {
System.out.println("Brak parametrów wejściowych");
}
return ic.proceed();
}
}package pl.jaceklaskowski.ejb;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import pl.jaceklaskowski.ejb.interceptor.ParameterLogger;
@Stateless
@Interceptors(ParameterLogger.class)
public class ExamSchedulerBean implements ExamScheduler {
public List<Exam> getExams() {
List<Exam> exams = new ArrayList<Exam>();
exams.add(new Exam("Programowanie obiektowe"));
return exams;
}
} - Udostępnienie komponentu EJB jako Usługi Sieciowej (ang. Web Service) wiąże się jedynie z udekorowaniem metod instancji klasy przez annotację @WebMethod.
package pl.jaceklaskowski.ejb;
import java.util.List;
import javax.jws.WebMethod;
public interface ExamScheduler {
@WebMethod
List<Exam> getExams();
} - Łatwość migracji do nowej wersji specyfikacji EJB3.
Podobnie jak to ma miejsce z innymi rozszerzeniami do Java SE czy Java EE zazwyczaj gwarantuje się ich wsteczną zgodność (dobrym przykładem jest mechanizmu Java Generics i jego wykorzystanie w Java Collections API). Aplikacja korzystająca z komponentów EJB 2.1 i wcześniejszych ma możliwość korzystania z rozwiązań EJB3 i na odwrót.
23 grudnia 2006
Usystematyzowanie nauki EJB 3.0 - Chapter 1: Introduction
Dokument EJB 3.0 Simplified API składa się z 12 rozdziałów, przy czym 12. rozdział jest dodatkiem o historii dokumentu. Znajomość zmian jakie następowały w dokumencie odzwierciedla bolączki z jakimi przyszło zmagać się twórcom specyfikacji, więc jego znajomość jest równie cenna, jak pozostałych. Natomiast, 11. rozdział jest wyłącznie zestawieniem odnośników do dalszych lektur, więc ten nam odpada. Pozostaje 11 rozdziałów do przeczytania.
Cały dokument to 60 stron pisany w dość przystępnej formie. Mam nadzieję, że moje relacje nie sprowadzą się do kopiowania części dokumentu, co jest nielegalne bez zgody autora (i jeśli zdarzy mi się to popełnić, zaraz proszę o przesłanie informacji).
Rozpoczynam od rozdziału Chapter 1: Introduction.
Celem EJB 3.0 jest:
- uproszczenie tworzenia komponentów EJB, m.in. poprzez uproszczenie EJB API, co zwiększa atrakcyjność specyfikacji
- zgodność z EJB 2.1, co umożliwia migrację do nowego środowiska bez konieczności przepisywania aplikacji
- możliwość jednoczesnego korzystania z EJB 2.1 i EJB 3.0
- wykorzystanie dobrodziejstw nowości Java SE 5 - annotacji, co pozwala na określanie znaczenia klasy/interfejsu w aplikacji bez konieczności utrzymywania zewnętrznych plików, których często trudno było utrzymać aktualne (bez stosowania rozwiązań pomocniczych jak XDoclet - kolejny otwarty projekt, który miał wpływ na specyfikację EJB3)
- zmniejszenie ilości klas/interfejsów do niezbędnego minimum, czyli powrót do korzeni języka Java, do specyfikacji JavaBeans, która była dostępna od jej pierwszych dni (ech, rzeczy proste zwykle pozostają niezauważane)
- usunięcie konieczności rozszerzania klas czy implementacji interfejsów, co przywiązywało nasze komponenty EJB 3.0 ze środowiskiem serwera aplikacyjego. Obecnie zwykła klasa realizująca specyfikację JavaBeans - POJO (ang. plain old java object) gra główne skrzypce.
- uproszczenie konstruowania powiązań między częściami aplikacji za pomocą annotacji, bez konieczności definiowania ich w plikach pomocniczych, np. ejb-jar.xml, web.xml, czy innych.
- wprowadzenie ustawień domyślnych, które można nadpisywać annotacjami, czy (opcjonalnie) deklaracjami w pliku ejb-jar.xml. W poprzedniej wersji specyfikacji wiele domyślnych ustawień było specyficznych dla serwera aplikacyjnego, co powodowało, że wykorzystana wartość domyślna mogła przyjmować różne wartości dla różnych serwerów.
- stworzenie JPA (Java Persistence API) dzięki, któremu zdefiniowano ujednoliconą warstwę zarządzania obiektami trwałymi, gdzie dostarcza się sterowników JPA (np. Hibernate) realizujących kontrakt (podobnie jak sterowniki JDBC w stosunku do JDBC).
- uproszczenie mechanizmu notyfikacji o sytuacjach wyjątkowych w aplikacji
Jednym słowem twórcy specyfikacji nauczyli się oddychać tym samym powietrzem, co projektanci i programiści ze świata rozwiązań otwartych, np. Spring Framework, czy Hibernate i zapożyczyli wiele z rozwiązań. Wpływy tych projektów widać, aż nadto (i stąd moje przekonanie, że Spring Framework+Hibernate nie wprowadza do naszych rozwiązań przemysłowych - tych opartych o standard Java EE 5 - niczego, czego nie byłoby już dostępnego w serwerze aplikacji). Nadeszła ponownie era Java EE.
19 grudnia 2006
Nareczcie egzamin z Java EE 5 i to darmowy! Tylko do 2 stycznia 2007
Dla mnie 2 stycznia jest nierealny, ale gdyby komuś zechciało się podejść do egzaminu SCBCD 5 proszę o natychmiastowy kontakt ;-)
Wracam do lektury specyfikacji EJB3 i ewaluacji IBM WebSphere Application Server Version 6.1 Feature Pack for EJB 3.
18 grudnia 2006
Sun Certified Java Programmer (SCJP) 5.0 zdany!
Dzisiaj o 11:00 stawiłem się w ABCData na VIII piętrze, gdzie dotarłem walcząc ze schodami po tym jak zdecydowałem się iść, a nie jechać windą. Kiedy dotarłem nie mogłem złapać tchu i to nie z powodu egzaminu (!) Zanim do normy wróciły wszystkie funkcje życiowe, pani wskazała mi na moje stanowisko. Po wstępnej ankiecie, w której miałem ocenić własną znajomość języka Java, przyszła pora na właściwy egzamin. Po około 2 godzinach zobaczyłem przy swoim nazwisku Pass, a następnie dostałem do ręki wydruk z wynikiem.
Przy minimum egzaminacyjnym na poziomie 59% zdobyłem 80%, co pozwoliło mi na pomyślne zdanie egzaminu. I nie ukrywam, że mimo wydawałoby się dużego zaangażowania w różne projekty i technologie Java, nie było lekko. Oj nie było! Czuję dużą ulgę, że mam to już za sobą - 72 pytań w 175 minut wykańcza samo w sobie, a życie analizatora składniowego języka Java nie jest łatwe ;-) O to właśnie chodzi na egzaminie - stać się analizatorem składniowym (!) Przy naszym wykorzystaniu zintegrowanych środowisk (IDE) coraz bardziej na nich polegamy zapominając o konstrukcjach języka (inicjalizacja tabel, średniki, przecinki), różnicach w działaniu podstawowych operatorów (np. & czy |) nie wspominając, że nauka nowości języka w wersji 5 nie należy do łatwych (szczególnie Java Generics, czy Enumy). Zdumiewające dla mnie było nauczenie się działania operatorów % oraz / i znaków ich wyników (dla dociekliwych: % daje w wyniku ujemną liczbę wyłącznie jeśli pierwszy operand jest ujemny, a przy drugim jeśli przynajmniej jeden z operandów).
Z czego się uczyłem? Głównie SCJP Sun Certified Programmer for Java 5 Study Guide (Exam 310-055) by Kathy Sierra and Bert Bates, McGraw-Hill/Osborne © 2006 oraz Whizlabs SCJP 5.0 Preparation Kit. Oczywiście ciągle towarzyszyły mi Java 2 Platform Standard Edition 5.0 API Specification i The Java Language Specification, Third Edition. Tak uzbrojony pozostawało mieć wystarczająco wiele czasu, aby zgłębić niuanse i meandry języka i uzyskać...no cóż...jedynie 80%. Duuużo cierpliwości i wystarczająco dużo snu są wielce pożądane (w ostatnią sobotę nie mogłem się opanować i zabrałem się za ewaluację IBM WAS 6.1 z dodatkiem EJB 3.0 - dobrze, że nie wiedziałem o BEA WLS 10 ;-)).
Każdemu osobiście polecam podejście do egzaminu, bo wiele się nauczyłem i zrozumiałem. Ile to razy nie mogłem uwierzyć w to, co czytam (szczególnie z wątkami oraz kolekcjami, z których ostatecznie i tak wypadłem kiepsko). Promocja typów również była ciekawa oraz kwalifikatory dostępu. Wiele informacji przyswajałem wykonując testy w symulatorze z Whizlabs, bo alternatywnie mogłem wkuwać z książki, a nie bardzo szło mi poznawanie detali Javy bez komputera.
Możnaby zapytać, czy egzamin jest potrzebny? Ja odpowiem: tak. Człowiek uczy się ponownie uczyć rzeczy, które wydaje mu się, że rozumie. I nie widać, aby była różnica, czy dopiero się zaczyna pracę z Javą, czy jest się weteranem. Oba profile mają swoje wady i zalety - pierwszy ma świadomość konieczności nauki nowości w Javie 5, podczas gdy drugiemu może się wydawać, że wystarczy jedynie przeczytać tu i tam i podejść. Obaj muszą przewertować javadoc i specyfikację od deski do deski i duuuużo testować. Przynajmniej takie są moje odczucia. Ja nie należę do cierpliwych i po upływie 2 godzin miałem dosyć. Zaznaczyłem 12 odpowiedzi jako "do sprawdzenia", ale kiedy przyszło mi je sprawdzać po prostu nie chciało mi się, byłem wypruty. Coś tam sprawdziłem, ale bojąc się błędnie wprowadzonych odpowiedzi na sam koniec ostatecznie zarzuciłem temat.
Oficjalny certyfikat w drodze. Zastanawiam się nad kolejnym egzaminem - może SCWCD albo SCBCD, ale z pewnością w ich najnowszej odsłonie dla Java EE 5 (nie mam zamiaru przechodzić męki z EJB 2.1 ponownie).
16 grudnia 2006
IBM WebSphere Application Server Version 6.1 Feature Pack for EJB 3
Właśnie wczoraj przeczytałem informację o kolejnym komercyjnym dostawcy (poza Sunem i Oracle) z serwerem aplikacyjnym wspierającym EJB 3.0. Jest to dodatek-rozszerzenie do IBM WebSphere Application Server 6.1. I tutaj już wiadomo, o kim mowa - IBM. Nie ukrywam, że wiele mojego dziennego czasu upływa z produktami IBM i bardzo się ucieszyłem, kiedy po publikacji narzędzia IBM Rational Application Developer (RAD) v7, który oparty jest o Eclipse 3.2.1 (bądź jako rozszerzenie do własnej wersji), pojawia się teraz wsparcie dla EJB 3.0 w serwerze aplikacyjnym. Więcej informacji można znaleźć na stronie IBM WebSphere Application Server Version 6.1 Feature Pack for EJB 3. W nadchodzący poniedziałek podchodzę do egzaminu z Sun Java Certified Programmer 5 (SCJP 5), więc będę wewnętrznie walczył z samym sobą, aby nie spróbować uruchomić tego cacka ;-)
Jakby tego było mało jakimś dziwnym trafem znalazłem się na stronie Eclipse Dali JPA Tools, gdzie dowiedziałem się o rozszerzeniu Eclipse o narzędzia do Java Persistence API. Słyszałem wcześniej o Dali, ale aż do dzisiaj nie sądziłem, że ma to cokolwiek wspólnego z Java EE. W zasadzie to trudno mi sobie przypomnieć, co odpowiedziałbym, kiedy byłbym zapytany o Eclipse Dali. Teraz na pewno nie odpuszczę i korzystając z funkcjonalności Eclipse extension locations pobawię się Dali.
Dodam jeszcze, że projekt Apache OpenEJB 3 również małymi krokami zmierza ku wsparciu EJB 3.0, przez co wierzę, że i Apache Geronimo niedługo zacznie oferować dla niej wsparcie. Niedługo dla mnie oznacza pierwszą połowę nadchodzącego roku (Q107), ale czas pokaże jak będzie. W końcu jest to projekt otwarty, więc wszystko zależy od dostępności czasu osób zaangażowanych w projekt. Jeśli chciał(a)byś pomóc, zapraszam jako programista w obu projektach.
07 grudnia 2006
Relacja z II spotkania Warszawa JUG
Samo prowadzenie spotkania było dla mnie nielada novum (i nie do końca udało utrzymać mi się tempo i jego styl). Nowość spotkania polegała na całkowitym braku slajdów. Wszystkie informacje przekazywane były ustnie w ramach wyjaśnienia kroków jakie wykonywałem tworząc aplikację na żywo, całkowicie unplugged. I jak to w zwyczaju bywa przy tego typu prezentacjach, nie obyło się bez wpadek. Ale właśnie one powodują, że spotkanie nabiera rumieńców. Przykład uruchamiałem kilkakrotnie przez spotkaniem, jak i podczas tworzenia artykułu, który był przyczynkiem do niego (Tworzenie aplikacji Java EE 5 z Apache Maven 2 i Glassfish). Wszystko grało. Wystarczyło kopiować uważnie z artykułu i wszystko powinno grać. Ja jednak zaabsorbowany wyłuskiwaniem prostoty tworzenia aplikacji Java EE jak to mam w zwyczaju rozgadałem się, wręcz odjechałem podeskcytowany tematem i nie przekopiowałem dwóch plików. Ostatniecznie, kiedy przyszło do jej uruchomienia i na moją uwagę, że nie ma prawa się nieuruchomić, ku mojemu zdumieniu pojawił się...wyjątek. Nie mogłem uwierzyć własnym oczom. Szczęśliwie klimat wokół pierwszego uruchomienia był bardzo przyjazny, więc obyło się bez gwizdów, pomidorów, czy innych dodatków. Dzięki temu mogłem zaprezentować sposób rozwiązywania problemów podczas tworzenia aplikacji, co sprowadziło się do poprawienia web.xml i faces-config.xml.
Spotkanie trwało 2 godziny i wszyscy wytrwali do samego końca. Było wiele pytań o możliwość zastosowania tej wiedzy w praktyce, na co odpowiedziałem, że nasza wiedza wykracza poza możliwości dostępnego oprogramowania. Nie całkowicie, ale w dużej części. W końcu udało nam się być przygotowanym na nowości w świecie tworzenia aplikacji przemysłowych w Javie. Była wzmianka o kontenerach IoC i annotacjach w Javie, pojawiło się pytanie o JBoss Seam i Tomcat 6, jak i wzmianka o licencji Glassfish, która wygląda na niesprzyjającą uruchamianiu aplikacji komercyjnych na nim. Ogólnie bardzo mi się podobało i zamierzam dalej kontynuować temat.
Kolejne spotkanie Warszawa JUG planowane jest na 9 stycznia 2007. Do zobaczenia!
p.s. Spotkanie było ponownie nagrywane, ale odsłuchawszy poprzedniego nie sądzę, ażebym zdobył się na odwagę i opublikował materiał. Tak wiele błędów prezenterskich, że szkoda psuć sobie opinię wsród tych, którzy sądzą, że spotkania są ciekawą inicjatywą, ale nie mieli okazji jeszcze jej poczuć ;-)
01 grudnia 2006
II spotkanie Warszawskiej Grupy Użytkowników Technologii Java (Warszawa-JUG)
Warszawska Grupa Użytkowników Technologii Java (Warszawa-JUG) zaprasza na II spotkanie, które odbędzie się we wtorek 05.12.2006 o godzinie 18:00 w sali 5820 na Wydziale MiMUW przy ul. Banacha 2 w Warszawie.
Temat prezentacji: Tworzenie aplikacji Java EE 5 z wykorzystaniem Apache Maven 2
Wiele się zmieniło w specyfikacji Java EE 5 od ostatniej jej wersji. Twórcy specyfikacji, czerpiąc z wielu uproszczeń oferowanych w projektach otwartych, m.in. Spring Framework czy Hibernate, stworzyli bardzo elegancką specyfikację opartą o mechanizmy wstrzeliwania zależności (dependency injection - DI - bądź Inversion of Control - IoC), czy nowość w Javie SE 5 - annotacji. Tworzenie aplikacji Java EE 5 znacząco zostało uproszczone. Można śmiało powiedzieć, że nie ma znaczącej różnicy w sposobie tworzeniach aplikacji desktopowej, a uruchamianej na serwerze aplikacyjnym. Przekonamy się o tym tworząc aplikację Java EE 5 opartą o JavaServer Faces 1.2 i Enterprise JavaBeans 3.0, której wspomaganie projektowe zlecone zostanie Apache Maven 2.
Prezentacja prowadzona będzie przez Jacka Laskowskiego, który jest członkiem grup rozwojowych projektów Apache Geronimo i Apache OpenEJB. Tematyka spotkania została spisana i opublikowana do publicznej krytyki na jego własnym Wiki.
Planowany czas prezentacji to 1 godzina z kolejnymi 30 minutami na dyskusję.
Zapraszam w imieniu Warszawa-JUG!
29 listopada 2006
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!
19 listopada 2006
Eclipse Extension Location - zarządzanie wtyczkami
Więcej na Zarządzanie wtyczkami w Eclipse - Extension Location. Ciekaw jestem ilu miało świadomość istnienia tego mechanizmu.
18 listopada 2006
Eclipse 3.3 M3 i ciekawostka w zarządzaniu przestrzeniami roboczymi
Funkcjonalność, o której piszę znajduje się w menu File->Switch Workspace. Wybierając przestrzeń Eclipse zapisuje jej położenie w pliku $ECLIPSE_HOME\configuration\.settings\org.eclipse.ui.ide.prefs. Tak jest przynajmniej od wersji 3.2.
A skąd aż tyle szumu wokół tego? Jak napisałem, kiedyś mnie to zastanowiło, ale było na tyle nieistotne, że nie poświęciłem temu więcej czasu. Tym razem jest inaczej. Zacząłem pracować z Eclipse 3.3M3 i obok menu Other..., po wybraniu Switch Workspace pojawiła się pozycja C:\. Gdybym mógł zdefiniować sobie listę najciekawszych przestrzeni roboczych byłoby przyjemniej. I zacząłem szukać.
Najpierw natrafiłem na rozwiązanie starego problemu. A po chwili natrafiłem na Eclipse 3.3 M3 - New and Noteworthy, co w zasadzie powinno być pierwszym miejscem, w którym powinienem szukać odpowiedzi. A tam pozycja dotycząca Improved workspace switching. Dokładnie to czego mógłbym oczekiwać od tego typu narzędzia. Brrr, chyba zbyt mocno zaczynam przywiązywać się do Eclipse.
Jest pewna uwaga do działania tej funkcjonalności. Eclipse nie rozumiał katalogów z symbolem '@' w nazwie. Używam tego symbolu dla nadania ważności katalogowi, jednakże Eclipse traktował ten znak specjalnie w nazwie katalogu i stąd na liście przestrzeni znajdowała się niezrozumiała dla mnie wcześniej pozycja C:\, która de facto odpowiadała katalogowi C:\@eclipse-workspace\projekt.
13 listopada 2006
Hibernate jako dostawca JPA w samodzielnej aplikacji
Podsumujmy dotychczasowe wyniki pracy z JPA. Stworzyłem aplikację z pomocą NetBeans IDE 5.5, który umożliwił mi skorzystanie z implementacji JPA w wydaniu Oracle TopLink. Nie modyfikując nic w aplikacji (poza konfiguracją JPA) uruchomiłem ją z Apache OpenJPA. A dzisiaj nadeszła pora na Hibernate. Mimo tych niezwykle krótkotrwałych wypadów w świat JPA, już daje zauważyć się pewne różnice. Daje zauważyć się doświadczenie projektu Hibernate i jego prostota użycia. Ale, skoro są to jedynie szczegóły implementacyjne, kto by się tym zajmował. Implementacje JPA (Oracle TopLink, Apache OpenJPA, Hibernate) staną się (stały się?) podobnym rozwiązaniem jak sterowniki JDBC.
Dzisiejsze doświadczenia zaowocowały kolejnym przepisem - Hibernate jako dostawca JPA w samodzielnej aplikacji.
Najwyższa pora zająć się czymś z Java EE 5 na dłużej. Czas na zabawę z implementacjami JSF 1.2 i ich integracja z JPA. Może JBoss Seam? Nie! Na razie wystarczy Glassfish i samo zapoznanie się z nowościami JSF 1.2, a mówi się, że jest ich wiele.
12 listopada 2006
Apache OpenJPA jako dostawca JPA w samodzielnej aplikacji
Doświadczenia z Apache OpenJPA spisałem w kolejnym artykule - OpenJPA jako dostawca JPA w samodzielnej aplikacji - na moim Wiki. Zapraszam do lektury i nadsyłania swoich propozycji kolejnych tematów, jeśli wałkowanie Java Persistence API zaczyna nurzyć ;-)
Miłej zabawy z JPA w wydaniu OpenJPA!
Java Persistence API w samodzielnej aplikacji
11 listopada 2006
Pierwsza aplikacja z JSF 1.2 i EJB 3.0
Po instalacji Glassfish (od tej pory zwanego GF) oraz NetBeans IDE (NB) postanowiłem skorzystać z możliwości ich integracji i stworzyć pierwszą aplikację Java EE z ich użyciem. Jakież było moje zdumienie, kiedy po niecałych 5 minutach zobaczyłem działającą aplikację opartą o JSF 1.2 i EJB 3.0, a dokładnie JPA (!) To było dokładnie to czego potrzebowałem - kilka ruchów myszką i uderzeń w klawiaturę i mam aplikację z pełnymi źródłami do analizy. Zrozumienie aplikacji nie zabiera więcej niż kolejne 10-15 minut (oczywiście zakładając znajomość takich pojęć jak JSF w ogólności, kontenery IoC i Java Annotations). Z niecierpliwością oczekuję projektu, w którym przyjdzie mi stosować cudeńka Java EE i SE 5. Tworzenie aplikacji Java EE nie mogło być prostsze!
Opis przykładowej aplikacji po angielsku to:
Demonstrates the use of Java Persistence APIs based on the new Java Persistence specification in conjunction with JavaServer Faces that creates a simple authentication scheme using JavaServer Faces PhaseListeners and a simple Entity bean representing a user.
Dla zainteresowanych samodzielnym przejściem mojej "ścieżki zdrowia" przedstawiam kolejne kroki. Założeniem jest, aby GF i NB były zainstalowane.
- Uruchamiamy NB
- Definiujemy GF w menu Servers w zakładce Runtime w NB.
- Otwarcie NB wiąże się z jednoczesnym uruchomieniem okna Welcome z różnymi pozycjami związanymi z NB, gdzie w dolnym lewym rogu znajduje się Sample Projects, a tam pozycja Enterprise.
- Wybranie Enterprise to uruchomienie pomocnika (ang. wizard) , gdzie wybieramy JsfJpa (prawy panel - Projects) i wciskamy przycisk Next.
- Podajemy położenie projektu i wciskamy przycisk Finish.
- Tak utworzyliśmy nasz projekt JsfJpa (zakładka Projects) z wykorzystaniem JSF i JPA.
- Zaznaczamy projekt JsfJpa i z menu pod prawym klawiszem myszy wybieramy menu Run Project.
- Uruchamia się automatycznie Java DB oraz GF i przeglądarka z adresem http://localhost:8080/jsf-jpa-war/. To kończy naszą dzisiejszą pracę.
10 listopada 2006
Pierwsze kroki z Java EE z Glassfish i NetBeans IDE
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.
07 listopada 2006
1. inauguracyjne spotkanie Warszawa-JUG za nami
Temat prezentacji to Apache Geronimo w ogólności oraz jego integracja z Eclipse. Mimo, że chciałem zaprezentować Apache Geronimo w akcji to przez pierwszą godzinę gadałem jak nakręcony. Sam nie mogłem uwierzyć, że czas zleciał tak szybko. Postanowiłem przyspieszyć i zaprezentować wtyczkę Eclipse do pracy z Geronimo, uruchomiłem więc bardzo prostą aplikację internetową, zaprezentowałem konsolę Geronimo i kolejne 20 minut poszło w zapomnienie.
W międzyczasie wspomniałem o funkcjonalności Eclipse o nazwie Extension Locations, które pozwala na rozbudowę Eclipse o wtyczki bez modyfikacji katalogu głównego (w ten sposób uaktualnienie wtyczek, czy samego Eclipse jest trywialnie proste). Okazało się, że temat zyskał tyleż fanów, co sam temat główny i kolejne 20 minut przebiegło na jej omówieniu.
Kolejne, tym razem ostatnie, 20 minut poświęciliśmy na sesję pytań i odpowiedzi. Zakończyliśmy o godzinie 20:00.
Na moje pytanie kto nie zdecyduje się na przyjście kolejnym razem nikt się nie odezwał, co pozwala przypuszczać, że inicjatywa się podoba i będzie tym samym kontynuowana. Kolejne spotkanie za miesiąc!
Acha, zapomniałbym - spotkanie było nagrywane, więc oczekujcie publikacji nagrania niebawem. Będzie się z czego pośmiać, bo kilkakrotnie sala wybuchła śmiechem po moich próbach konstruowania inteligentnych odpowiedzi. A są one nierzadko okraszone zupełnie nietrafionymi w miejsce i porę moimi przemyśleniami. Warto chociażby z tego powodu zapoznać się z materiałem ;-)
IBM Rational Software Architect V7.0 Open Beta dostępna
Wersja RSA V7 oparta jest o najnowsze dziecko projektu Eclipse.org - Eclipse 3.2.1 i w zasadzie ten trend powinien się utrzymać, tzn. podczas instalacji RSA możemy wybrać opcję doinstalowania wtyczek (ang. plugins) i rozszeżeń (ang. features) do własnej zainstalowanej wersji Eclipse. Oznacza to, że pod warunkiem braku niekompatybilnych zmian w samej architekturze wtyczek w Eclipse, RSA powinien działać również z kolejnymi wersjami (np. Eclipse 3.3).
Po instalacji zabrałem się za stworzenie przykładowej aplikacji J2EE. Uruchomienie jej na IBM WebSphere Application Server (WAS) v6.1 nie stanowiło żadnego problemu (przypominam, że moje doświadczenie w tym zakresie mogłoby przez wielu być nazwane porażająco niskim, więc można sobie wyobrazić jak prosty musi być ten krok). Szybkość reakcji narzędzi jest imponująca (nawet podczas działania WASa), więc główny mankament RSA (a właściwie RAD V6) został wyeliminowany.
Na uwagę zasługuje również fakt, że wersja beta produktu RSA V7 to jednocześnie pełna nowa wersja RAD V7. Podczas instalacji możemy wybrać te funkcjonalności, które nas interesują, co pozwala na wykluczenie tych rozszeżeń RADa, które nie są w zakresie naszych zainteresowań, dodatkowo odchudzając narzędzie (zostawiając jedynie narzędzia wokół UML), ale nie idzie się oprzeć pokusie zainstalowania wszystkiego. Prostota instalacji zniewala ;-) A na prawdę warto. Ilość narzędzi i komfort pracy z RSA jest imponująca. Zresztą, co tu wiele pisać - jest to po prostu Eclipse 3.2.1, więc chociażby to wprowadza wiele dobrego. Reszta jest równie warta poświęcenia czasu szczególnie, że mamy do czynienia z wersją darmową (przynajmniej na czas trwania dostępności wersji beta).
Nie miałem niestety wiele czasu na zabawę z możliwościami RSA w zakresie UML, więc niewiele mogę napisać. Z niecierpliwością jednakże oczekuję chwili, kiedy będę mógł wrócić do niego i popróbować swoich sił. Reszta, co tu dużo ukrywać pójdzie najprawdopodobniej w odstawkę (cóż, może następnym razem bliżej się im przyjrzę - na pewno nie tym razem).
Chętnych do dyskusji na temat możliwości narzędzia zapraszam na strony produktu - https://www14.software.ibm.com/iwm/web/cc/earlyprograms/rational/desktop70O/, gdzie można pobrać wersję beta oraz uczestniczyć w rozmowach o produkcie na jego forum. Sam zamierzam zarzucić inne produkty UML na jego rzecz i przyjrzeć się (czytaj: przetestować na własnej skórze) możliwości narzędzi UML w RSA. Jeśli masz jakiekolwiek uwagi o jego funkcjonowaniu, chętnie ich wysłucham i być może tym samym zapobiegnę doznaniu nieprzyjemnego uczucia niespełnienia moich oczekiwań... ;-)
03 listopada 2006
I spotkanie Warszawskiej Grupy Użytkowników Technologii Java (Warszawa-JUG)
Witajcie!
Warszawska Grupa Użytkowników Technologii Java (Warszawa-JUG) zaprasza na inauguracyjne spotkanie, które odbędzie się we wtorek 07.11.2006 o godzinie 18:00 w sali 5820 Wydziału MiMUW przy ul. Banacha 2 w Warszawie.
Temat prezentacji: Apache Geronimo
Wielu z nas śledzących rynek rozwiązań Java EE spotkała się już zapewne z projektem Apache Geronimo. Celem projektu jest stworzenie serwera aplikacyjnego zgodnego ze specyfikacją Java EE 5, po tym jak cel główny - zgodność z J2EE 1.4 - został spełniony w wersji 1.0. Kolejna wersja 1.2 ma już być częściową implementacją specyfikacji Java EE 5 i jej wydanie planowane jest na ten rok. Prezentacja będzie miała na celu zademonstrowanie możliwości serwera, sposób jego działania, konfigurację i jego elementy składowe. Na prezentacji spróbuję dodatkowo odpowiedzieć na najczęściej zadawane pytania odnośnie serwera oraz przedstawię elementy, które niejednemu nasuną kontrowersyjną tezę o niebywałym podobieństwu między nim a...Spring Framework (!)
W projekcie rozwijana jest również wtyczka do Eclipse IDE, która pozwala na tworzenie aplikacji Java EE w Eclipse i uruchamianie jej na serwerze, o której będzie również mowa na prezentacji. Z jej pomocą, stworzymy demonstracyjną aplikację, którą następnie uruchomimy na serwerze.
Prezentacja prowadzona będzie przez Jacka Laskowskiego, który jest członkiem zespołu koordynującego i programistą w projekcie Apache Geronimo.
Planowany czas prezentacji to 1 godzina z kolejnymi 30 minutami na dyskusję.
Zapraszam w imieniu Warszawa-JUG!
29 października 2006
Moje poszukiwania (darmowych) narzędzi UML
Jest kilka kryteriów jakim poddaję te narzędzia:
- wsparcie dla diagramów przepływu
- wymagania środowiska (najlepiej jeśli jest to rozszerzenie dla Eclipse IDE 3.2+)
- prostota użycia (ma być intuicyjne i intuicyjność nie ma być czymś co nabędę po przeczytaniu sterty dokumentacji)
- cena (a właściwie jej brak)
- prostota instalacji (preferuję wersje bez instalatora, których proces instalacji składa się z jednego kroku - rozpakowania do wybranego katalogu)
- sposób aktualizacji do nowszej wersji
- wsparcie dla UML 2.0 (chociaż nie mam bladego pojęcia dlaczego mi na tym tak zależy, więc nie takie ważne :-))
Zabrałem się za poszukiwanie innego. Wpisałem w Google - Eclipse UML - i...dostałem odnośnik do Omondo EclipseUML (http://www.omondo.com). Słyszałem o nim już wcześniej, więc przejrzawszy stronę domową i dowiedziawszy się, że jest to wersja rozszerzająca Eclipse postanowiłem sprawdzić to cudeńko. Nie zastanawiając się długo pobrałem darmową wersję 3.2.20061006 i zainstalowałem ją w osobnym Extension Location w Eclipse. Rozpocząłem ewaluację. Pierwsze wrażenia całkiem pozytywne, szczególnie po tych nieprzyjemnych z ArgoUML. Darmowy, wspiera Eclipse 3.2.1, można zainstalować w osobnym katalogu bez ryzyka zniszczenia Eclipse i w końcu ma wsparcie dla wywołań metod własnych obiektu, który jest jednocześnie wywołującym i odbierającym włącznie z możliwością rozrysowania podwywołań. Wszystkie ładnie się układało, aż do momentu, kiedy po dodaniu kolejnej klasy i metody diagram zaczął robić się zbyt wysoki, tzn. każde dodanie nowej metody (a było ich nie więcej niż 10!) powodowało, że diagram rozszerzał się w pionie do niezarządzalnych rozmiarów. Dodatkowo linie reprezentujące czas życia obiektów nie były dopasowywane do nowych rozmiarów, więc przyszło mi "bawić się" z rozciąganiem i układaniem obiektów zamiast skupić się na ich wprowadzaniu, gdzie resztę powinno obsłużyć samo narzędzie (pamiętałem, że w którymś z narzędzi widziałem kiedyś możliwość upiększenia rozmieszczenia obiektów na diagramie). Po kilku godzinach zniechęcony, stwierdziłem, że na rynku musi być ciekawsza oferta.
Przypomniałem sobie, że bodajże 5 lat temu byłem na szkoleniu o Bluestone Application Server (nota bene, ciekaw jestem, komu w Polsce przyszło z nim pracować - ciekawe, niszowe rozwiązanie, które po zakupie przez HP i transformacji do HP Application Server - HPAS - zostało ostatecznie zasypane i rozwój całkowicie zamilkł. Ciekawostką jest fakt, że ludzie z działu rozwoju zasilili działy rozwoju Oracle Application Server oraz JBoss Application Server)...Ale o czym to ja? Acha, ewaluacja. Przypomniałem sobie o MagicDraw (http://www.magicdraw.com). Okazało się nawet, że miałem go juz zainstalowanego na swoim komputerze (prawdopodobnie po tym, kiedy otrzymałem wiadomość do skrzynki o tym jaki jest wspaniały i darmowy i takie tam, skuszony zainstalowałem po to, aby...mieć). Na stronie domowej doczytałem o najświeższej wersji 11.6 i że uaktualnienia instaluje się za pomocą mechanizmu wbudowanego w narzędzie (co sprowadza się jedynie na sprawdzeniu, czy one istnieją i potwierdzenie ich instalacji). Kilka punktów dla niego. Na razie wciąż ewaluuję, więc niewiele napiszę o nim tym razem, ale sam sposób instalacji jest bardzo obiecujący. Przejrzałem kilka filmów instruktorzowych o tworzeniu diagramów (w tym i diagramu sekwencji) i nie ukrywam, że oczekuję samych dobroci ;-)
W międzyczasie uaktualniania MagicDraw przypomniałem sobie o innym narzędziu - mojej referencji dla NetBeans RCP - Visual Paradigm for UML (http://www.visual-paradigm.com/product/vpuml). Ostatnia wersja 5.3 ma możliwość instalacji jako produkt samodzielny, bądź jako wtyczka do różnych IDE, w tym i Eclipse IDE. Niestety musiałbym zainstalować narzędzie w domyślnym katalogu Eclipse, bez możliwości skorzystania z Extension Location, więc zaniechałem tego sposobu i pobrałem wersję samodzielną. Nadal oczekiwałem na dokończenie instalacji uaktualnienia MagicDraw, kiedy po pobraniu i instalacji (co przypominam sprowadza się do rozpakowania odpwiedniej paczki instalacyjnej) uruchomiłem w końcu narzędzie i...moim oczom ukazało się zapierające dech w piersiach narzędzie (to są odpowiednie słowa, aby wyrazić mój zachwyt tym co zobaczyłem). Panel startowy wbił mnie w krzesło - kompletnie zdębiałem - mnogość opcji tworzenia różnorodnych diagramów i różnorodność kolorów, w jakich zostało to zaprezentowane. Prawie kompletnie zapomniałem o instalowaniu MagicDraw ;-) Mimo wyłącznie pozytywnych opinii o MagicDraw, postanowiłem kontynuować moją ewaluację od Visual Paradigm for UML. W końcu przyjazność użytkowniowi (co składa się na intuicyjność) ma duże znaczenie dla mnie.
Dla zainteresowanych i tych wytrwałych w lekturze moich doświadczeń ewaluacyjnych (kolejność przypadkowa) napiszę, że na rynku około października ma pojawić się najnowsza wersja IBM Rational Software Architect 7.0 (o nazwie kodowej Caspian). Dlaczego dodałem informację o komercyjnym produkcie? Jak mówi się za kulisami, ma być dostępna wersja darmowa dla społeczności (ang. community edition) i oparta o Eclipse 3.2. W końcy prace nad IBM RSA są kontynuowane pod nadzorem osób, które miały duży wpływ na ostateczny kształ UMLa, więc oczekiwania w stosunku do tego produktu muszą być odpowiednio wysokie również. Z niecierpliwością oczekuję momentu, w którym będę mógł podzielić się moimi doświadczeniami z produktem. Nie ma co pisać o wersji pre-BETA teraz, lepiej poczekać na pełną odsłonę, nieprawdaż?
Wracam do ewaluacji. Visual Paradigm i MagicDraw czekają już gotowe!
17 października 2006
Tabele w JavaServer Faces - znacznik h:dataTable
Przeniosłem więc swoją działalność na Wiki - http://www.laskowski.net.pl/wiki. Nadal nie jestem pewien, czy na tym poprzestanę, ale z pewnością blog powróci do łask jako miejsce krótkich edycji.
Najnowszy artykuł z serii artykułów o JSF w nowym miejscu to Tabele w JavaServer Faces - znacznik h:dataTable.
13 września 2006
Zgłębianie tajników działania środowiska JavaServer Faces (JSF)
JSF działa w ramach kontenera servletów. Innymi słowy JSF jest aplikacją internetową ze wszystkimi jej konsekwencjami i niewątliwie znajomość technologii Java Servlets znacznie ułatwia zrozumienie działania mechanizmów JSF. Podstawową konsekwencją wykorzystania kontenera servletów jako fundamentu jest sposób uruchamiania aplikacji opartej o JSF. Punktem początkowym obsługującym zlecenia aplikacji JSF jest odpowiednie mapowanie javax.faces.webapp.FacesServlet w deskryptorze rozmieszczenia aplikacji internetowej (ang. deployment descriptor - /WEB-INF/web.xml). Najczęściej wykorzystywanym mapowaniem jest mapowanie per ścieżka (/faces/*) albo per rozszeżenie (*.faces i/lub *.jsf). Wyzwolenie servletu FacesServlet to tak na prawdę uruchomienie środowiska JSF. FacesServlet jest punktem wejścia do JSF - spoiwem łączącym dwie technologie Java Servlets i JavaServer Faces. Jak każdy servlet tak i FacesServlet wczytuje swoją konfigurację z deskryptora instalacji. Jest kilka elementów fundamentalnych dla działania FacesServlet (a tym samym i JSF). Są nimi:
- fabryka obiektów FacesContext, które dostarczają informacji o aktualnie przetwarzanym zleceniu i odpowiedzi.
- fabryka obiektów Lifecycle, które odpowiedzialne są za przetwarzanie zleceń według ustalonych etapów.
Parametrów konfiguracyjnych może być znacznie więcej i zależą od implementacji specyfikacji JSF. Konfiguracja obu fabryk obsługiwana jest przez implementację, z której korzystamy i zazwyczaj nie potrzeba się o nią martwić. Najczęściej wymieniane implementacje (środowiska uruchomieniowe) specyfikacji JSF to implementacja referencyjna JSF (ang. JSF Reference Implementation) oraz Apache MyFaces.
Każde zlecenie obsługiwane przez FacesServlet może uczestniczyć w 6 etapach, podczas których wykonywane są odpowiednie czynności związane z przetwarzanym zleceniem. Ważne jest, aby pamiętać, że przejście wszystkich etapów nie jest obowiązkowe i co istotne może być kontrolowane przez samego autora aplikacji JSF. Dodatkowo środowisko JSF może dostarczać własne etapy poza tymi wymienionymi w specyfikacji. Nie można zmienić kolejności wykonywania etapów. Dodać należy również, że lista etapów jest uporządkowana i ominięcie pojedyńczego implikuje zaniechanie wykonania następnych poza ostatnim.
Etapy w życiu zlecenia obsługiwanego przez JSF to:
- Restore View
- Apply Request Values
- Process Validations
- Update Model Values
- Invoke Application
- Render Response
Praca FacesServlet zaczyna się (i jednocześnie kończy) po odebraniu zlecenia i przekazaniu do obiektu implementującego interfejs javax.faces.lifecycle.Lifecycle. Referencyjna implementacja JSF udostępnia go jako obiekt typu com.sun.faces.lifecycle.LifecycleImpl. Po utworzeniu obiektu FacesContext (przy pomocy fabryki FacesContext) przekazuje się go kolejno do metod Lifecycle.execute(FacesContext) i Lifecycle.render(FacesContext). Zakończenie pracy serwletu kończy przetwarzanie zlecenia przez JSF.
Z każdym etapem można związać słuchacza (ang. listener), który jest uruchamiany przy wejściu do i wyjściu z wybranego etapu. Słuchacz implementuje interfejs javax.faces.event.PhaseListener. Domyślnie, konfiguracja słuchacza odbywa się w pliku konfiguracyjnym JSF - faces-config.xml przy pomocy znacznika faces-config/lifecycle/phase-listener (wartością znacznika jest nazwa klasy).
Wywołanie etapu poprzedza sprawdzenie, czy wywołano metodę FacesContext.renderResponse() na obiekcie typu FacesContext związanym z przetwarzanym zleceniem. Wywołanie metody FacesContext.renderResponse() jest sygnałem dla JSF, że zakończenie aktualnie przetwarzanego etapu powinno przekazać kontrolę zlecenia do ostatniego etapu - Render Response - omijając jakiekolwiek etapy pośrednie.
Poza sprawdzeniem stanu związanego z wywołaniem FacesContext.renderResponse(), następuje sprawdzenie, czy wywołano metodę FacesContext.responseComplete() na bieżącym obiekcie typu FacesContext. Informuje ona JSF, że należy zakończyć przetwarzanie zlecenia omijając jakiekolwiek etapy pośrednie. Jest to moment, w którym odpowiedź HTTP została już wysłana do klienta i zakończenie etapu to całkowite zakończenie przetwarzania zlecenia. Możliwym przykładem mogłoby być przekierowanie żądania (ang. HTTP redirect), albo wysłanie strumienia binarnego, np. obrazka.
Każdorazowo przed uruchomieniem etapu następuje wzbudzenie słuchaczy (jeśli takowe zostały zarejestrowane w faces-config.xml). Jeśli słuchacz wykona dowolną z w/w metod (FacesContext.responseComplete() albo FacesContext.renderResponse() w innym etapie niż Render Response) następuje zaniechanie wykonania etapu i zakończenie obsługi żądania, albo przejście do etapu Render Response. Wywołanie słuchaczy odbywa się poprzez wywołanie metod javax.faces.event.PhaseListener.beforePhase(PhaseEvent) bądź javax.faces.event.PhaseListener.afterPhase(PhaseEvent), odpowiednio przed i po etapie. Słuchacz rejestruje swoje zainteresowanie obsługą wejścia do i wyjścia z etapu implementując odpowiednią metodę, a same etapy poprzez metodę javax.faces.event.PhaseListener.getPhaseId().
Jak opisano wyżej, obie metody FacesContext.renderResponse() oraz FacesContext.responseComplete() mogą być wywołane przez elementy stworzone przez programistę w ramach aplikacji JSF (np. słuchacze) i w ten sposób wpływać na przebieg obsługi żądania.
29 sierpnia 2006
Java EE 5 - wpływ projektów wolnodostępnych na uproszczenie specyfikacji
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.