Opublikowałem właśnie nowy artykuł Embeddable EJB 3.1 z Apache OpenEJB 4, Apache Maven 3 i IntelliJ IDEA 10.5, który kontynuuje cykl przedstawiania nowych cech specyfikacji Enterprise JavaBeans (EJB) 3.1. Chodził za mną od kilku dni i potrzeba mi było zebrać się w sobie, aby w końcu usiąść i napisać go. W końcu jest!
Zapraszam do lektury i komentarzy. Dla zwrócenia uwagi napiszę, że w samym ziarnie MySession popełniłem kilka błędów architektonicznych, w których zakładam pewne zachowanie ziarna bezstanowego mimo, że takowej nie oferuje (bez świadomej i specyficznej konfiguracji kontenera). Ciekawym komu uda się zauważyć moją pomyłkę, albo kilka? Zachęcam do dyskusji.
Pokazywanie postów oznaczonych etykietą openejb3. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą openejb3. Pokaż wszystkie posty
03 września 2011
20 grudnia 2010
EJB 3.1 z OpenEJB 3.1 i NetBeans IDE 7.0
Jest wiele sposobów na naukę nowych technologii i dobór odpowiednich narzędzi może znacząco usprawnić ten proces. W przypadku EJB 3.1 możemy skorzystać z projektu Apache OpenEJB 3.1, podpierając się NetBeans IDE 7.0 jako zintegrowanym środowiskiem programistycznym z asystentami tworzenia ziaren EJB z Apache Maven w tle.
Zastosowanie EJB 3.1 jest zwykle podyktowane względami praktycznymi, kiedy wybór serwera aplikacyjnego Java EE 6 mamy już za sobą i pozostaje wykorzystać jego usługi. Ich kompletność i gotowość do użycia najlepiej doświadczyć, kiedy konieczne jest wykorzystanie transakcji, podłączenia do bazy danych z możliwością przypisania komu i co wolno, udostępnić Web Service z wykorzystaniem REST w ramach aplikacji webowej czy podobne "deklaratywne czynności". Nie ma konieczności zestawiania gotowej konfiguracji usług, a konwencja ponad konfigurację znacznie przyspiesza dostarczanie kompletnych rozwiązań. Przenośność aplikacji jest również istotnym aspektem wyboru stosu technologicznego. Dodając do tego łatwość testowania aplikacji korporacyjnych i Java EE 6 (JEE6) wydaje się być idealną platformą aplikacyjną.
W tym artykule przedstawię uruchomienie bezinterfejsowego, niestanowego ziarna sesyjnego EJB (ang. no-interface stateless session bean) z użyciem projektu Apache OpenEJB 3.1.4, który stworzę w NetBeans IDE 7.0 (wersja rozwojowa z dnia 15.12.2010). Celem jest maksymalne zminimalizowanie czasu koniecznego do uruchomienia środowiska. Kolejną zaletą zastosowania OpenEJB jest możliwość wykonanywania wszystkich operacji projektowych (budowanie i testowanie) poza IDE, dzięki użyciu Apache Maven wspieranym przez NetBeans IDE 7 "z pudełka".
Więcej w artykule EJB 3.1 z OpenEJB 3.1 i NetBeans IDE 7.0.
Zastosowanie EJB 3.1 jest zwykle podyktowane względami praktycznymi, kiedy wybór serwera aplikacyjnego Java EE 6 mamy już za sobą i pozostaje wykorzystać jego usługi. Ich kompletność i gotowość do użycia najlepiej doświadczyć, kiedy konieczne jest wykorzystanie transakcji, podłączenia do bazy danych z możliwością przypisania komu i co wolno, udostępnić Web Service z wykorzystaniem REST w ramach aplikacji webowej czy podobne "deklaratywne czynności". Nie ma konieczności zestawiania gotowej konfiguracji usług, a konwencja ponad konfigurację znacznie przyspiesza dostarczanie kompletnych rozwiązań. Przenośność aplikacji jest również istotnym aspektem wyboru stosu technologicznego. Dodając do tego łatwość testowania aplikacji korporacyjnych i Java EE 6 (JEE6) wydaje się być idealną platformą aplikacyjną.
W tym artykule przedstawię uruchomienie bezinterfejsowego, niestanowego ziarna sesyjnego EJB (ang. no-interface stateless session bean) z użyciem projektu Apache OpenEJB 3.1.4, który stworzę w NetBeans IDE 7.0 (wersja rozwojowa z dnia 15.12.2010). Celem jest maksymalne zminimalizowanie czasu koniecznego do uruchomienia środowiska. Kolejną zaletą zastosowania OpenEJB jest możliwość wykonanywania wszystkich operacji projektowych (budowanie i testowanie) poza IDE, dzięki użyciu Apache Maven wspieranym przez NetBeans IDE 7 "z pudełka".
Więcej w artykule EJB 3.1 z OpenEJB 3.1 i NetBeans IDE 7.0.
12 czerwca 2009
OpenEJB 3.1.x, EJB 3.1, @ApplicationException oraz maven.surefire.debug
Pewnie zastanawiasz się, skąd ta różnorodność tematyczna w temacie, co? Dla mnie też było to niemałym zaskoczeniem, kiedy uzmysłowiłem sobie, ile rozwiązań przewinęło mi się dzisiaj, aby rozwiązać wydawałoby się początkowo banalne zgłoszenie OPENEJB-980 @ApplicationException inheritance. Najpierw sądziłem, że to kwestia prześwietlenia dostępnych klas w poszukiwaniu adnotacji @ApplicationException. I tutaj pierwsze bliższe spotkanie z ASM, który wykorzystywany jest w Apache XBean do prześwietlania klas bez konieczności ładowania ich do pamięci JVM z użyciem Reflection API. Wystarczy uruchomić ASM, który poprzez wykorzystanie wzorca projektowego Visitor pozwala na gromadzenie informacji o przetwarzanej klasie. W ten sposób do pamięci PermGen, gdzie trzymane są wszystkie definicje wczytanych klas, nie trafiają definicje, które nie są w użyciu i nie puchnie ona niepotrzebnie.
Miałem już listę klas, które są oznaczone adnotacją @ApplicationException oraz ich potomków. Przyszła więc pora na obsługę samego wyjątku, który niezgodnie z zasadami mechanizmu adnotacji w Javie powinien być oznaczony przez @java.lang.annotation.Inherited, gdyby miał być faktycznie dziedziczony (zdanie w 3. trybie warunkowym z opuszczeniem "if" możecie znaleźć w komentarzu Davida Blevinsa do zgłoszenia - "Had the annotation intended to be inherited it would have been annotated with @Inherited which causes the annotation to be propagated to all the subclasses as described"). W rzeczywistości jednak taka zmiana trafiła do specyfikacji EJB 3.1, w której, mimo, że adnotacja !ApplicationException nie jest @Inherited może taką być przez element inherited z wartością logiczną (domyślnie jest true, czyli jest propagowany w dół hierarchii dziedziczenia). W swoim komentarzu, Dave zaprezentował krótki przykład, który pokazuje, gdzie jest problem (początkowo miałem problemy z dokładnym zrozumieniem tematu, aż do tej chwili, kiedy pojawił się ten przykład - może i Tobie się przyda, o czym ja).
Zajrzałem do specyfikacji EJB 3.1 PFD (ang. Proposed Final Draft) z 24. lutego 2009, rozdział "14.2.1 Application Exceptions" (str. 378). W EJB 3.1, przypisanie wyjątku kontrolowanego (ang. checked exception) jako wyjątku aplikacyjnego dotyczy również wszystkich wyjatków pochodnych. Wystarczy jednak skorzystać z elementu inherited z wartością false, aby dziedziczenie wyłączyć (alternatywnie można użyć elementu application-exception w deskryptorze XML). Zastanawiam się skąd ta decyzja. Pewnie nadanie @Inherited do adnotacji @ApplicationException złamałoby kontrakt, a dodanie elementu już nie (?)
Na stronie 380 specyfikacji EJB 3.1 PFD pokazany jest przykład z wyjątkiem aplikacyjnym dziedziczonym (ExceptionA) oraz nie (ExceptionC). Kolejne miejsce do nauki przez przykład. Jest krótki, więc zdecydowanie nie ma się nad czym zastanawiać, tylko zapoznać się z nim.
Wprowadziłem odpowiednie zmiany w Apache OpenEJB, więc kolejne wersje będą to honorowały (na razie ignorowana jest wartość "inherited" i wszystko jest tak, jakby było "inherited=true"). Jako gotowy przykład do uruchomienia proponuję zajrzeć do aplikacji demonstracyjnej towarzyszącej zmianie applicationexception. Mając klienta Subversion oraz Apache Maven 2, wystarczy
Pozostaje jeszcze wyjaśnić maven.surefire.debug z tytułu wpisu. Pisząc test jednostkowy do tej zmiany użyłem adnotacji @Test(expected = ValueRequiredException.class), która instruuje JUnit, że w teście oczekuje się zgłoszenia wyjątku ValueRequiredException. Początkowo nie wiedziałem, dlaczego ta zmiana to za mało i każdorazowe uruchomienie Mavena kończyły się BUILD ERROR. Doprowadzało mnie to do szału, aż znalazłem rozwiązanie - wyrzucenie "extends TestCase" z definicji klasy testowej ThrowBusinessExceptionImplTest (!) Jeszcze uaktualniłem JUnit do wersji 4.6 oraz maven-surefire-plugin do 2.4.2 i wszystko zaczęło działać poprawnie. W międzyczasie rozglądałem się za dostępnymi, specjalnymi ustawieniami w Mavenie, które mogłyby mi pomóc (wiedziałem, że to może być coś związanego z Mavenem, albo samym testem, ale nie wiedziałem dokładnie co), aż natrafiłem na stronę Debugging Tests. Zamiast definiować konfigurację śledzenia (debugowania) testu w pom.xml wystarczy skorzystać z parametru maven.surefire.debug. Test jest zatrzymywany i oczekuje na podłączenie klienta JDWP...ekhm...zdalnego debuggera. Można również skorzystać z mvnDebug i parametru forkMode, o czym również nie wiedziałem. Do tej pory, kopiowałem konfigurację uruchomienia z włączonym debug do wtyczki maven-surefire-plugin w pom.xml, a tu proszę, rozwiązanie gotowe i pod ręką.
Ze zgłoszenia OPENEJB-980 pozostaje mi jeszcze obsłużyć element inherited w @ApplicationException i temat będzie całkowicie zamknięty. Uwagi mile widziane i pożądane. Nie jest to zmiana najwyższych lotów, a wpisy Łukasza Lenarta Jak cię widzą, tak cię piszą czy Pawła Szulca Testing and Testable Code Presentation tylko mnie utwierdziły, że jeszcze wiele przede mną w temacie dobrych testów jednostkowych.
Z ciekawostek na koniec - podczas testowania przykładu z pustym repozytorium mavenowym zauważyłem, że Apache Maven 2.1.0 pobiera zależności...równolegle (chyba tylko tak mogę interpretować, co zauważyłem - oznaczone na czerwono poniżej). A może jednak nie? To co miałoby to być?!
Miałem już listę klas, które są oznaczone adnotacją @ApplicationException oraz ich potomków. Przyszła więc pora na obsługę samego wyjątku, który niezgodnie z zasadami mechanizmu adnotacji w Javie powinien być oznaczony przez @java.lang.annotation.Inherited, gdyby miał być faktycznie dziedziczony (zdanie w 3. trybie warunkowym z opuszczeniem "if" możecie znaleźć w komentarzu Davida Blevinsa do zgłoszenia - "Had the annotation intended to be inherited it would have been annotated with @Inherited which causes the annotation to be propagated to all the subclasses as described"). W rzeczywistości jednak taka zmiana trafiła do specyfikacji EJB 3.1, w której, mimo, że adnotacja !ApplicationException nie jest @Inherited może taką być przez element inherited z wartością logiczną (domyślnie jest true, czyli jest propagowany w dół hierarchii dziedziczenia). W swoim komentarzu, Dave zaprezentował krótki przykład, który pokazuje, gdzie jest problem (początkowo miałem problemy z dokładnym zrozumieniem tematu, aż do tej chwili, kiedy pojawił się ten przykład - może i Tobie się przyda, o czym ja).
Zajrzałem do specyfikacji EJB 3.1 PFD (ang. Proposed Final Draft) z 24. lutego 2009, rozdział "14.2.1 Application Exceptions" (str. 378). W EJB 3.1, przypisanie wyjątku kontrolowanego (ang. checked exception) jako wyjątku aplikacyjnego dotyczy również wszystkich wyjatków pochodnych. Wystarczy jednak skorzystać z elementu inherited z wartością false, aby dziedziczenie wyłączyć (alternatywnie można użyć elementu application-exception w deskryptorze XML). Zastanawiam się skąd ta decyzja. Pewnie nadanie @Inherited do adnotacji @ApplicationException złamałoby kontrakt, a dodanie elementu już nie (?)
Na stronie 380 specyfikacji EJB 3.1 PFD pokazany jest przykład z wyjątkiem aplikacyjnym dziedziczonym (ExceptionA) oraz nie (ExceptionC). Kolejne miejsce do nauki przez przykład. Jest krótki, więc zdecydowanie nie ma się nad czym zastanawiać, tylko zapoznać się z nim.
Wprowadziłem odpowiednie zmiany w Apache OpenEJB, więc kolejne wersje będą to honorowały (na razie ignorowana jest wartość "inherited" i wszystko jest tak, jakby było "inherited=true"). Jako gotowy przykład do uruchomienia proponuję zajrzeć do aplikacji demonstracyjnej towarzyszącej zmianie applicationexception. Mając klienta Subversion oraz Apache Maven 2, wystarczy
svn co https://svn.apache.org/repos/asf/openejb/trunk/openejb3/examples/applicationexceptionUWAGA: Zmiany potrzebne do uruchomienia przykładu nie są jeszcze rozpropagowane po repozytoriach mavenowych, więc z pewnością zakończy się BUILD FAILURE. Dodatkowo, początkowe uruchomienie pobiera wiele (chyba zdecydowanie za wiele) zależności ze zdalnych repozytoriów, więc przygotuj się na dłuższą przerwę. Najlepiej po prostu ściągnąć źródła OpenEJB i give it a try.
cd applicationexception
mvn test
Pozostaje jeszcze wyjaśnić maven.surefire.debug z tytułu wpisu. Pisząc test jednostkowy do tej zmiany użyłem adnotacji @Test(expected = ValueRequiredException.class), która instruuje JUnit, że w teście oczekuje się zgłoszenia wyjątku ValueRequiredException. Początkowo nie wiedziałem, dlaczego ta zmiana to za mało i każdorazowe uruchomienie Mavena kończyły się BUILD ERROR. Doprowadzało mnie to do szału, aż znalazłem rozwiązanie - wyrzucenie "extends TestCase" z definicji klasy testowej ThrowBusinessExceptionImplTest (!) Jeszcze uaktualniłem JUnit do wersji 4.6 oraz maven-surefire-plugin do 2.4.2 i wszystko zaczęło działać poprawnie. W międzyczasie rozglądałem się za dostępnymi, specjalnymi ustawieniami w Mavenie, które mogłyby mi pomóc (wiedziałem, że to może być coś związanego z Mavenem, albo samym testem, ale nie wiedziałem dokładnie co), aż natrafiłem na stronę Debugging Tests. Zamiast definiować konfigurację śledzenia (debugowania) testu w pom.xml wystarczy skorzystać z parametru maven.surefire.debug. Test jest zatrzymywany i oczekuje na podłączenie klienta JDWP...ekhm...zdalnego debuggera. Można również skorzystać z mvnDebug i parametru forkMode, o czym również nie wiedziałem. Do tej pory, kopiowałem konfigurację uruchomienia z włączonym debug do wtyczki maven-surefire-plugin w pom.xml, a tu proszę, rozwiązanie gotowe i pod ręką.
Ze zgłoszenia OPENEJB-980 pozostaje mi jeszcze obsłużyć element inherited w @ApplicationException i temat będzie całkowicie zamknięty. Uwagi mile widziane i pożądane. Nie jest to zmiana najwyższych lotów, a wpisy Łukasza Lenarta Jak cię widzą, tak cię piszą czy Pawła Szulca Testing and Testable Code Presentation tylko mnie utwierdziły, że jeszcze wiele przede mną w temacie dobrych testów jednostkowych.
Z ciekawostek na koniec - podczas testowania przykładu z pustym repozytorium mavenowym zauważyłem, że Apache Maven 2.1.0 pobiera zależności...równolegle (chyba tylko tak mogę interpretować, co zauważyłem - oznaczone na czerwono poniżej). A może jednak nie? To co miałoby to być?!
03 listopada 2008
@Resource UserTransaction w EJB 3.0 i poprawka dla OpenEJB
Pojawiła się kolejna wersja Apache OpenEJB 3.1 z obsługą EJB 3.1. Tak, tak, my tu o EJB 3.0, a na horyzoncie już się pojawił EJB 3.1 w OpenEJB 3.1 oraz GlassFish v3 Prelude. Na fali wydania postanowiłem obsłużyć jedno ze zgłoszeń dotyczących kontroli poprawności ziaren EJB w kontekście użycia UserTransaction - OPENEJB-847 Validation: @Resource UserTransaction injection mistakenly used on bean with Container-Managed Transactions. Zgłoszenie OPENEJB-847 dotyczyło sprawdzenia, czy deklaracja dostępu do zasobu UserTransaction ma miejsce jedynie w ziarnie EJB z samodzielnie zarządzanymi transakcjami. Zgodnie ze specyfikacją EJB 3.0, rozdział 16.12 UserTransaction Interface (strona 448) dostęp do UserTransaction jest możliwy wyłącznie dla ziaren sesyjnych (stanowych i bezstanowych) oraz komunikacyjnych (sterowanych komunikatami) z zarządzaniem transakcjami przez nie same (ang. BMTD - bean-managed transaction demarcation).
W najczęściej spotykanych przypadkach, transakcyjność ziaren EJB zarządzana jest przez kontener i w takim przypadku nie mamy prawa skorzystać z interfejsu UserTransaction wprost, czy to przez adnotację @Resource UserTransaction, czy deklarując go w deskryptorze wdrożenia (META-INF/ejb-jar.xml). Po prostu, kontrola zasięgu transakcji odbywa się deklaratywnie na poziomie metody lub całej klasy za pomocą adnotacji TransactionAttribute (domyślnie REQUIRED) z TransactionManagement ustawionym na CONTAINER (wartość domyślna).
Pod wpływem niekończących się dyskusji o bardziej przyjaznej IntelliJ IDEA do tworzenia aplikacji javowych (chociażby Fwd: JetBrains Giveaway Program Update), do napisania poprawki dla OpenEJB postanowiłem właśnie z niej skorzystać i przekonać się o tym na własnej skórze. Pamiętam czasy wersji 3 i później Ariadnę (nazwa kodowa dla wersji 4.0), i faktycznie coś w niej było. Później jeszcze kilkakrotnie przymierzałem się do niej, ale nie starczyło zacięcia. Tym razem zawziąłem się. Rozpocząłem od uruchomienia IntelliJ IDEA 8.0M1 i zaimportowałem projekt dzięki wsparciu dla projektów mavenowych. Po ostatniej lekturze artykułu "Poznaj JUnita" (Refleksje po "Poznaj JUnit 4" z Internet MAKER 5/08) tylko czekałem chwili, aby zmierzyć się z tematem tworzenia oprogramowania począwszy od testów jednostkowych. Trochę trwało, zanim faktycznie dałem się przekonać, że właśnie od testu powinienem zacząć i ruszyłem z miejsca, gdyż samo zestawienie całego "środowiska" do wykonania poprawki nie należało do najtrywialniejszych zadań (przede wszystkim utworzenie reprezentacji obiektowej konfiguracji ziarna EJB operając się na klasach JAXB). Szczęśliwie dzisiaj nie trwało to na tyle długo, abym się zniechęcił i po chwili miałem swoją wymarzoną, działającą poprawkę (!) Nadeszła upragniona pora, aby ją sprawdzić poza testem jednostkowym. Skorzystałem z pomocy NetBeans IDE 6.5 RC2 (który właśnie niedawno został wydany - do ostatniego wydania pozostało już kilka tygodni) i stworzyłem przykładowe ziarno bezstanowe z adnotacją @Resource.
Ale jak to?! False?! Czyż @Resource UserTransaction nie jest dedykowane wyłącznie dla ziaren sesyjnych i MDB z samodzielnym zarządzaniem transakcji?! Taką miałem wiedzę, kiedy tworzyłem moją poprawkę dla OpenEJB i tego spodziewałem się w GlassFish (!) W tym momencie, przypomniałem sobie, jak podczas mojego ostatniego wystąpienia z tematem EJB 3.0 podczas NetBeans Day 2008 w Gdańsku, właśnie wykorzystanie transakcji zakończyło się porażką, gdyż...wykonałem przynajmniej jedną metodę na przekazanym egzemplarzu UserTransaction (cóż za zbieg okoliczności - najpierw NetBeans Day, później artykuł o JUnit, a teraz okazja do zastosowania wiedzy praktycznie w OpenEJB). Zmieniłem kod ziarna na następujący
Przyszła więcej pora na testy w środowisku OpenEJB. Najpierw sprawdzenie, jakie będzie działanie przykładowego ziarna w ramach Apache Geronimo 2.1.2, który jest serwerem aplikacyjnym Java EE 5 z kontenerem EJB opartym na OpenEJB. I tu bez niespodzianek - działa i to zgodnie z oczekiwaniami - UserTransaction jest puste. Odetchnąłem z ulgą. Teraz było już z górki - upragnione zatwierdzenie zmian (commit). Zainteresowanych szczegółami implementacji zapraszam do lektury Subversion Commits dla tego zgłoszenia. Nie ma tego wiele, więc pełne rozpoznanie tematu powinno zająć niespełna kwadrans.
p.s. Zauważyłem wiele podobieństw między NetBeans IDE 6.5 a IntelliJ IDEA 8.0M1, gdzie okienko tworzenia nowych elementów klasy, w NetBeans - Ctrl+Insert istnieje w IDEA jako...Alt+Insert oraz sout+TAB jako szablon dla System.out.println("")...również. Gdzieś już trafiłem na podobną refleksję (nie był to Radek Holewa?!). Już te dają mi do myślenia, a pewnie jest więcej.
W najczęściej spotykanych przypadkach, transakcyjność ziaren EJB zarządzana jest przez kontener i w takim przypadku nie mamy prawa skorzystać z interfejsu UserTransaction wprost, czy to przez adnotację @Resource UserTransaction, czy deklarując go w deskryptorze wdrożenia (META-INF/ejb-jar.xml). Po prostu, kontrola zasięgu transakcji odbywa się deklaratywnie na poziomie metody lub całej klasy za pomocą adnotacji TransactionAttribute (domyślnie REQUIRED) z TransactionManagement ustawionym na CONTAINER (wartość domyślna).
Pod wpływem niekończących się dyskusji o bardziej przyjaznej IntelliJ IDEA do tworzenia aplikacji javowych (chociażby Fwd: JetBrains Giveaway Program Update), do napisania poprawki dla OpenEJB postanowiłem właśnie z niej skorzystać i przekonać się o tym na własnej skórze. Pamiętam czasy wersji 3 i później Ariadnę (nazwa kodowa dla wersji 4.0), i faktycznie coś w niej było. Później jeszcze kilkakrotnie przymierzałem się do niej, ale nie starczyło zacięcia. Tym razem zawziąłem się. Rozpocząłem od uruchomienia IntelliJ IDEA 8.0M1 i zaimportowałem projekt dzięki wsparciu dla projektów mavenowych. Po ostatniej lekturze artykułu "Poznaj JUnita" (Refleksje po "Poznaj JUnit 4" z Internet MAKER 5/08) tylko czekałem chwili, aby zmierzyć się z tematem tworzenia oprogramowania począwszy od testów jednostkowych. Trochę trwało, zanim faktycznie dałem się przekonać, że właśnie od testu powinienem zacząć i ruszyłem z miejsca, gdyż samo zestawienie całego "środowiska" do wykonania poprawki nie należało do najtrywialniejszych zadań (przede wszystkim utworzenie reprezentacji obiektowej konfiguracji ziarna EJB operając się na klasach JAXB). Szczęśliwie dzisiaj nie trwało to na tyle długo, abym się zniechęcił i po chwili miałem swoją wymarzoną, działającą poprawkę (!) Nadeszła upragniona pora, aby ją sprawdzić poza testem jednostkowym. Skorzystałem z pomocy NetBeans IDE 6.5 RC2 (który właśnie niedawno został wydany - do ostatniego wydania pozostało już kilka tygodni) i stworzyłem przykładowe ziarno bezstanowe z adnotacją @Resource.
package nopackage;Jakież było moje zdumienie, kiedy podczas jego uruchomienia na GlassFish V2 otrzymałem komunikat:
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.transaction.UserTransaction;
@Stateless
public class CheckUserTransactionRefsTestBean implements CheckUserTransactionRefsTestLocal {
@Resource
UserTransaction tx;
public String businessMethod() {
String result;
try {
result = "tx is null? " + (tx == null);
} catch (Exception ex) {
result = ex.getMessage();
}
return result;
}
}
Ale jak to?! False?! Czyż @Resource UserTransaction nie jest dedykowane wyłącznie dla ziaren sesyjnych i MDB z samodzielnym zarządzaniem transakcji?! Taką miałem wiedzę, kiedy tworzyłem moją poprawkę dla OpenEJB i tego spodziewałem się w GlassFish (!) W tym momencie, przypomniałem sobie, jak podczas mojego ostatniego wystąpienia z tematem EJB 3.0 podczas NetBeans Day 2008 w Gdańsku, właśnie wykorzystanie transakcji zakończyło się porażką, gdyż...wykonałem przynajmniej jedną metodę na przekazanym egzemplarzu UserTransaction (cóż za zbieg okoliczności - najpierw NetBeans Day, później artykuł o JUnit, a teraz okazja do zastosowania wiedzy praktycznie w OpenEJB). Zmieniłem kod ziarna na następującyresult = "tx is null? " + (tx == null) + " ze statusem " + tx.getStatus();i...jest wyjątek!
Przyszła więcej pora na testy w środowisku OpenEJB. Najpierw sprawdzenie, jakie będzie działanie przykładowego ziarna w ramach Apache Geronimo 2.1.2, który jest serwerem aplikacyjnym Java EE 5 z kontenerem EJB opartym na OpenEJB. I tu bez niespodzianek - działa i to zgodnie z oczekiwaniami - UserTransaction jest puste. Odetchnąłem z ulgą. Teraz było już z górki - upragnione zatwierdzenie zmian (commit). Zainteresowanych szczegółami implementacji zapraszam do lektury Subversion Commits dla tego zgłoszenia. Nie ma tego wiele, więc pełne rozpoznanie tematu powinno zająć niespełna kwadrans.p.s. Zauważyłem wiele podobieństw między NetBeans IDE 6.5 a IntelliJ IDEA 8.0M1, gdzie okienko tworzenia nowych elementów klasy, w NetBeans - Ctrl+Insert istnieje w IDEA jako...Alt+Insert oraz sout+TAB jako szablon dla System.out.println("")...również. Gdzieś już trafiłem na podobną refleksję (nie był to Radek Holewa?!). Już te dają mi do myślenia, a pewnie jest więcej.
23 kwietnia 2008
JUnit4, OpenEJB3, Maven2, Cobertura i refactoring w Eclipse - wdrożenie wiedzy praktycznie
Dzisiejszy dzień to próba zastosowania narzędzi, które znałem od wieków, ale ze stosowaniem było (delikatnie ujmując) kiepsko - refactoring (ma to swoją nazwę w j. polskim?) oraz tworzenie testów jednostkowych w JUnit 4 z użyciem adnotacji, statycznymi importami oraz uruchomieniem ich poprzez Apache Maven 2. Wszystko za sprawą nachodzącej specyfikacji EJB 3.1, która za jakiś czas stanie się oficjalną, a ja nie zamierzam czekać na implementację od Suna, tylko dostarczyć ją w ramach projektu Apache OpenEJB. Niedawno udało nam się wypuścić wersję OpenEJB 3.0 z pełnym wsparciem dla EJB 3.0 i możliwością uruchamiania ziaren EJB bez specjalnego i skomplikowanego zestawiania środowiska, a jedynie zmianie CLASSPATH i odpowiednim skonstruowaniu kontekstu JNDI w aplikacji. Więcej najprawdopodobniej niebawem, kiedy uporządkuję kilka bieżących zadań wokół Wicket, OSGi, NetBeans i kilku innych projektów, a niecierpliwych kieruję na strony projektu - Apache OpenEJB. W związku z moim powrotem do korzeni i zwiększenia mojego udziału w rozwoju OpenEJB - rozpocząłem wgłębianie się w jego kod źródłowy właśnie za pomocą testów jednostkowych pisanych w JUnit 4. Niby teoretycznie proste, ale w praktyce nierzadko powoduje niemałą zagadkę logiczną i stworzenie środowiska odpowiedniego dla wykonania testu może przyprawić o ból głowy. Wtedy właśnie wychodzi styl programowania i zasada Najpierw test (strona kliencka), a później sama klasa testowana (sama aplikacja). Pod pojęciem strony klienckiej mam na myśli wymagany interfejs programistyczny, którego użycie planuje się w aplikacji.
Rozpocząłem moją przygodę od uruchomienia mvn clean cobertura:cobertura w ramach projektu mavenowego (wspomniałem, że był to moduł OpenEJB - openejb-ejbd, ale tak na prawdę nie ma to większego znaczenia).

Widać na nim, że jedynie klasa BasicClusterableRequestHandler jest pokryta w 100% przez testy, a pozostałe prezentują się marnie. Pokrycie w 100% nie powinno być celem samym w sobie, ale dla mnie najważniejsze było, aby zacząć, więc akurat wybrałem moduł openejb-ejbd, w którym wybrałem klasę DeploymentIndex (obecnie ma 59% pokrycia, ale jeszcze wczoraj było 0!). Sama prezentacja pokrycia w postaci zielonych i czerwonych miejsc wskazuje, które są objęte testami, a które wymagają troski.

Po rozmowie z innym programistą projektu OpenEJB i jego liderem - Davidem Blevinsem - okazało się, że:
Co to jednak ma wspólnego z refactoringiem?! Podczas pracy z klasą testową - DeploymentIndexTest - rozpocząłem niewinnie z pojedyńczą metodą, która później rozwinęła się w dwie, a później dodałem metodę setUp(), która ustawia środowisko (=zmienne) i jest wykonywana każdorazowo przed każdym testem - metoda oznaczona adnotacją @Before. Okazało się, że wbrew temu jak do tej pory podchodziłem do sprawy modyfikacji klas metodą Ctrl-C/Ctrl-V, tym razem postanowiłem spróbować przyzwyczaić się do kolejnego elementu środowisk IDE (korzystałem z Eclipse IDE 3.4M6) i podczas zmiany rangi zmiennej lokalnej do poziomu zmiennej instancji skorzystałem z menu Refactor > Convert Local Variable to Field...

Po chwili miałem temat z głowy. Wystarczy umiejscowić kursor na zmiennej lokalnej i wybrać menu, aby przenieść ją na poziom zmiennej instancji. Przydała się również funkcja Refactor > Rename (Alt+Shift+R), która jednak była już kilkakrotnie przeze mnie wykorzystywana. Piszę o tym, gdyż mając w nawyku pracę z różnej maści edytorami byłem przyzwyczajony do ciągłego stosowania techniki Copy-Paste, która była uniwersalna, i mimo wiedzy na temat funkcjonalności Refactoring w Eclipse (również NetBeans czy IntelliJ IDEA) nie miałem nawyku jej stosowania tracąc czas na rzeczy, które nie były ani ciekawe, ani miłe. Zdecydowanie polecam tego typu podejście do zmiany struktury kody, niż owe Copy-Paste.
W trakcie poznawania zmian w JUnit 4 natrafiłem na sposób deklarowania oczekiwanego wyjątku w teście. Do tej pory stosowałem technikę:
Pytanie konkursowe: W jaki sposób deklarujemy oczekiwany wyjątek w JUnit 4?
Rozpocząłem moją przygodę od uruchomienia mvn clean cobertura:cobertura w ramach projektu mavenowego (wspomniałem, że był to moduł OpenEJB - openejb-ejbd, ale tak na prawdę nie ma to większego znaczenia).
jlaskowski@work /cygdrive/c/oss/openejb3/server/openejb-ejbdUruchomienie polecenia wykonuje testy oraz za pomocą wtyczki cobertura-maven-plugin następuje badanie pokrycia kodu źródłowego testami. W wyniku, w katalogu target/site/cobertura, znajduje się dokumentacja HTML z prezentacją pokrycia testami.
$ mvn clean cobertura:cobertura
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'cobertura'.
[INFO] ------------------------------------------------------------------------
[INFO] Building OpenEJB :: Server :: EJBd
[INFO] task-segment: [clean, cobertura:cobertura]
[INFO] ------------------------------------------------------------------------
...
[INFO] [cobertura:cobertura]
[INFO] Cobertura 1.9 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
Cobertura: Loaded information on 13 classes.
Report time: 594ms
[INFO] Cobertura Report generation was successful.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
jlaskowski@work /cygdrive/c/oss/openejb3/server/openejb-ejbdOtworzenie strony index.html prezentuje następujący raport:
$ ls -l target/site/cobertura/
cobertura/ org.apache.openejb.server.ejbd.AuthRequestHandler.html
css/ org.apache.openejb.server.ejbd.BasicClusterableRequestHandler.html
frame-packages.html org.apache.openejb.server.ejbd.CallContext.html
frame-sourcefiles-org.apache.openejb.server.ejbd.html org.apache.openejb.server.ejbd.ClientObjectFactory.html
frame-sourcefiles.html org.apache.openejb.server.ejbd.ClusterableRequestHandler.html
frame-summary-org.apache.openejb.server.ejbd.html org.apache.openejb.server.ejbd.DeploymentIndex.html
frame-summary.html org.apache.openejb.server.ejbd.EjbDaemon.html
help.html org.apache.openejb.server.ejbd.EjbRequestHandler.html
images/ org.apache.openejb.server.ejbd.EjbServer.html
index.html org.apache.openejb.server.ejbd.JndiRequestHandler.html
js/ org.apache.openejb.server.ejbd.ServerSideResolver.html

Widać na nim, że jedynie klasa BasicClusterableRequestHandler jest pokryta w 100% przez testy, a pozostałe prezentują się marnie. Pokrycie w 100% nie powinno być celem samym w sobie, ale dla mnie najważniejsze było, aby zacząć, więc akurat wybrałem moduł openejb-ejbd, w którym wybrałem klasę DeploymentIndex (obecnie ma 59% pokrycia, ale jeszcze wczoraj było 0!). Sama prezentacja pokrycia w postaci zielonych i czerwonych miejsc wskazuje, które są objęte testami, a które wymagają troski.

Po rozmowie z innym programistą projektu OpenEJB i jego liderem - Davidem Blevinsem - okazało się, że:
<jlaskowski> write...I'm all ears (trying to polish a junit test for DeploymentIndex)...czyli klasa nie jest w ogóle w użyciu. No cóż pierwsze podejście nie musi być idealne ;-) Mimo wszystko dobrze było rozpocząć rozpoznawanie kodu źródłowego OpenEJB wybierając dowolną klasę, której pokrycie jest bliskie zeru, a że nie jest w użyciu jeszcze - nic straconego. Od razu Dave przyszedł mi jednak z pomocą i napisał:
<dblevins> we don't use the DeploymentIndex anymore
<jlaskowski> what?!
<dblevins> kind of an unfortunate place to start, but yea, it's cruft at the moment
<dblevins> I suggest the Assembleri Dave rozwinął jak to tam w środku się dzieje. Mam się czym zająć w wolnych chwilach i mam pewność, że dana klasa jest w użyciu. Jestem ocalony!
<jlaskowski> org.apache.openejb.assembler.classic.Assembler?
<dblevins> right
<jlaskowski> k
<dblevins> and the ConfigurationFactory
<dblevins> the flow of the system startup is this...
Co to jednak ma wspólnego z refactoringiem?! Podczas pracy z klasą testową - DeploymentIndexTest - rozpocząłem niewinnie z pojedyńczą metodą, która później rozwinęła się w dwie, a później dodałem metodę setUp(), która ustawia środowisko (=zmienne) i jest wykonywana każdorazowo przed każdym testem - metoda oznaczona adnotacją @Before. Okazało się, że wbrew temu jak do tej pory podchodziłem do sprawy modyfikacji klas metodą Ctrl-C/Ctrl-V, tym razem postanowiłem spróbować przyzwyczaić się do kolejnego elementu środowisk IDE (korzystałem z Eclipse IDE 3.4M6) i podczas zmiany rangi zmiennej lokalnej do poziomu zmiennej instancji skorzystałem z menu Refactor > Convert Local Variable to Field...

Po chwili miałem temat z głowy. Wystarczy umiejscowić kursor na zmiennej lokalnej i wybrać menu, aby przenieść ją na poziom zmiennej instancji. Przydała się również funkcja Refactor > Rename (Alt+Shift+R), która jednak była już kilkakrotnie przeze mnie wykorzystywana. Piszę o tym, gdyż mając w nawyku pracę z różnej maści edytorami byłem przyzwyczajony do ciągłego stosowania techniki Copy-Paste, która była uniwersalna, i mimo wiedzy na temat funkcjonalności Refactoring w Eclipse (również NetBeans czy IntelliJ IDEA) nie miałem nawyku jej stosowania tracąc czas na rzeczy, które nie były ani ciekawe, ani miłe. Zdecydowanie polecam tego typu podejście do zmiany struktury kody, niż owe Copy-Paste.
W trakcie poznawania zmian w JUnit 4 natrafiłem na sposób deklarowania oczekiwanego wyjątku w teście. Do tej pory stosowałem technikę:
try {
...kod, który zgłaszał wyjątek...
fail("Powinien zostać zgłoszony wyjątek NazwaWyjątkuException");
} catch (NazwaWyjątkuException expected) {
// ignored
}W JUnit 4 zalecanym sposobem jest użycie atrybutu expected adnotacji @Test, np. @Test(expected= IndexOutOfBoundsException.class), czyli to, co zostało zaprezentowane wyżej teraz powinno wyglądać następująco:@Test(expected=NazwaWyjątkuException.class)Więcej informacji o JUnit w JUnit Cookbook. Warto się z nim zapoznać, bo zawiera kwintesencję JUnit i jego przeczytanie nie powinno zabrać więcej niż 5-10 minut (pewnie przeczytanie tego wpisu zajęło więcej ;-)). Wracam do testów jednostkowych...
public void mojTest() {
...kod, który zgłaszał wyjątek...
}
Pytanie konkursowe: W jaki sposób deklarujemy oczekiwany wyjątek w JUnit 4?
16 września 2007
Maven 2 Remote Resources Plugin oraz Project Group w NetBeans IDE 6
Przyszło mi się zmagać z opublikowaniem Apache OpenEJB 3.0 i podczas budowania wersji dystrybucyjnej zwrócono uwagę, że każdy plik będący w dystrybucji musi posiadać nagłówek z odpowiednią licencją ASLv2, a pliki typu jar czy zip pliki LICENSE oraz NOTICE. OpenEJB jest projektem rządzącym się prawami Apache Software Foundation, więc obowiązują go zasady opisane w dokumencie ASF Source Header and Copyright Notice Policy. Projekt OpenEJB zarządzany jest przez Apache Maven 2, więc do obsługi wspomnianych plików wykorzystywane są odpowiednie wtyczki - typowe rozwiązanie to kopiowanie ich z katalogu projektu. Nie byłoby w tym nic wyjątkowego, gdyby nie fakt, że plik NOTICE jest zbiorem licencji zależności wykorzystywanych przez projekt OpenEJB. Do dzisiejszej nocy konieczne było umieszczanie informacji o licencjach manualnie - każdorazowe dodanie zależności oraz co najbardziej bolesne zależności przechodnich, tj. takich, które były zależnościami pochodnymi zależności, którą deklaruje projekt, musiało wiązać się z odpowiednią adnotacją w pliku NOTICE. Można sobie wyobrazić, że nie było to przyjemne i podczas tworzenia wersji dystrybucyjnej konieczne było ponowne przeanalizowanie wszystkich zależności i ich licencji oraz dodanie brakujących do NOTICE. Bolesne. Aż do dzisiejszego wieczora, kiedy wykorzystałem wtyczkę Maven 2 Remote Resources Plugin (MRRP). Jej zadaniem jest automatyczne zarządzanie informacjami, które projekty i tak zobowiązane są umieszczać we własnym pliku pom.xml (serce projektu kontrolowanego przez Apache Maven 2). Wtyczka działa w ten sposób, że pobiera zdalny zestaw plików (parametr konfiguracyjny wtyczki resourceBundles), które umieszczane są w paczce dystrybucyjnej. Dodatkowo włączany plik może być szablonem Velocity, co daje możliwość modyfikacji jego zawartości na bazie konfiguracji wtyczki. Pozostaje jedynie zapewnić, że wymagane informacje o projekcie ów projekt udostępnia, co sprowadza się do poprawienia ich plików pom.xml albo samodzielne zarządzanie informacjami w pliku supplemental-models.xml (w katalogu src/main/appended-resources). Jeśli nawet wtyczka wymaga pewnych kroków konfiguracyjnych, to proces zarządzania dołączanymi plikami (wliczając w to również ich dynamiczną modyfikację) sprowadziła do minimum. Istnieje również możliwość budowania własnych zestawów plików do dołączenia, co przy wielu projektach pozwala na zbudowanie pojedyńczego repozytorium dołączanych dokumentów, a nie wyłącznie plików typu jar, zip, war, ear, itp.
Podczas rozpoznawania jak działa wtyczka MRRP postanowiłem pobrać jej źródła. Nie było ich wiele, więc lektura nie zabrała więcej niż kwadrans. Po ostatnich pozytywnych wrażeniach z pracą NetBeans IDE 6 i wtyczką NetBeans do obsługi projektów zarządzanych przez Maven 2 postanowiłem skorzystać z NetBeans IDE. Nie chciałem jednak zaśmiecać sobie widoku projektów modułów OpenEJB z projektem wtyczki i przypomniałem sobie o funkcjonalności, której nie miałem jeszcze sposobności wykorzystać - Project Group. Jest to bardzo podobne do przestrzeni roboczych (ang. workspaces) w Eclipse, czy grupowania projektów w Eclipse w widoku projektów. Zawsze mi tego brakowało w NetBeans, więc teraz przyszła pora na sprawdzenie, czy to jest właśnie to. Zdefiniowałem sobie grupę dla projektu OpenEJB, a drugą dla wtyczki MRRP. Pamiętam podobną funkcjonalność z IntelliJ IDEA, gdzie bodajże już w wersji 4 było to ciekawie rozwiązane, gdzie przełączenie to było jedynie ukrycie projektów, które de facto cały czas były otwarte, albo podobnie. W przypadku NetBeans Project Group działa podobnie. Chciałbym mieć możliwość otwarcia grupy w osobnym oknie NetBeans, więc nie do końca byłem zachwycony, ale ogólnie ocena 4+.
Podczas rozpoznawania jak działa wtyczka MRRP postanowiłem pobrać jej źródła. Nie było ich wiele, więc lektura nie zabrała więcej niż kwadrans. Po ostatnich pozytywnych wrażeniach z pracą NetBeans IDE 6 i wtyczką NetBeans do obsługi projektów zarządzanych przez Maven 2 postanowiłem skorzystać z NetBeans IDE. Nie chciałem jednak zaśmiecać sobie widoku projektów modułów OpenEJB z projektem wtyczki i przypomniałem sobie o funkcjonalności, której nie miałem jeszcze sposobności wykorzystać - Project Group. Jest to bardzo podobne do przestrzeni roboczych (ang. workspaces) w Eclipse, czy grupowania projektów w Eclipse w widoku projektów. Zawsze mi tego brakowało w NetBeans, więc teraz przyszła pora na sprawdzenie, czy to jest właśnie to. Zdefiniowałem sobie grupę dla projektu OpenEJB, a drugą dla wtyczki MRRP. Pamiętam podobną funkcjonalność z IntelliJ IDEA, gdzie bodajże już w wersji 4 było to ciekawie rozwiązane, gdzie przełączenie to było jedynie ukrycie projektów, które de facto cały czas były otwarte, albo podobnie. W przypadku NetBeans Project Group działa podobnie. Chciałbym mieć możliwość otwarcia grupy w osobnym oknie NetBeans, więc nie do końca byłem zachwycony, ale ogólnie ocena 4+.
16 grudnia 2006
IBM WebSphere Application Server Version 6.1 Feature Pack for EJB 3
Na ostatnim spotkaniu Warszawa JUG poruszono temat wsparcia dla Java EE 5 w serwerach aplikacyjnych, również i tych komercyjnych, oraz wsparcie samych narzędzi. Moja prezentacja demonstrowała Java EE 5 w wykonaniu NetBeans IDE 5.5, M2 oraz Glassfish v2 i można było stwierdzić, że była zbyt ekstremalna w tym sensie, że większość z czynności wymagała znajomości Java EE i integracji narzędzi. Oczywiście znajomość technologii jest istotna w jej poprawnym zastosowaniu, jednakże z perspektywy czasu stwierdzam, że mogłoby być ciekawiej, jeśli prezentacja dotyczyłaby Java EE z punktu widzenia wsparcia przez narzędzia wspomagające tworzenie aplikacji (był NetBeans IDE, chociaż czułem, że większość pracuje z Eclipse IDE) oraz wsparcia przez produkcyjnie gotowe serwery aplikacyjne. M2 był dobrze odebrany, ale połączenie M2 i Java EE tworzyło temat nie na godzinę, badź dwie, ale na cały dzień (!)
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.
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.
Subskrybuj:
Posty (Atom)