Embeddable EJB 3.1 z Apache OpenEJB 4, Apache Maven 3 i IntelliJ IDEA 10.5
W poprzednich artykułach EJB 3.1 z OpenEJB 3.1 i NetBeans IDE 7.0 oraz Embeddable EJB 3.1 z GlassFish 3.1 i NetBeans IDE 7.0 przedstawiłem nową cechę kontenerów Enterprise JavaBeans (EJB) 3.1, którym w nowej wersji udostępniono możliwość uruchamiania w trybie zanurzonym (ang. embedded) i to bez jawnego wskazania na używany kontener. Zalet tej funkcjonalności jest kilka, ale najważniejsze, że rozpoznanie, który kontener jest w użyciu jest określone poza kodem źródłowym (które w przeciwnym wypadku wymagałoby ponownej rekompilacji - Java, Scala - lub ponownego wczytania - Clojure, Groovy, JRuby). Wad nie znaleziono.
Zestawienie środowiska potrzebne mi było do napisania poprawki do zgłoszenia OPENEJB-1128 Intercepting generic business method calls fails, z którym borykam się (=mam przypisane) od wieków.
Spis treści |
Utworzenie projektu - mvn archetype:generate
Rozpoczynam bardzo przewidywalnie - z linii poleceń i Apache Maven 3.0.3.
jacek:~/sandbox $ mvn --version Apache Maven 3.0.3 (r1075438; 2011-02-28 18:31:09+0100) Maven home: /Users/jacek/apps/maven Java version: 1.6.0_26, vendor: Apple Inc. Java home: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home Default locale: en_US, platform encoding: MacRoman OS name: "mac os x", version: "10.6.8", arch: "x86_64", family: "mac"
Wystarczy uruchomić zadanie archetype:generate z odpowiednimi parametrami i projekt jest gotowy do dalszych udoskonaleń.
jacek:~/sandbox
$ mvn archetype:generate -B \
-DarchetypeGroupId=org.codehaus.mojo.archetypes \
-DarchetypeArtifactId=ejb-javaee6 \
-DgroupId=pl.japila.javaee6.ejb31 \
-DartifactId=OPENEJB-1128 \
-Dversion=1.0
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:2.0:generate (default-cli) @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:2.0:generate (default-cli) @ standalone-pom <<<
[INFO]
[INFO] --- maven-archetype-plugin:2.0:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode
[INFO] Archetype [org.codehaus.mojo.archetypes:ejb-javaee6:1.5] found in catalog remote
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------Warto zwrócić uwagę na użycie archetypu org.codehaus.mojo.archetypes.ejb-javaee6, który załatwia sprawę właściwej konfiguracji projektu EJB 3.1 dla Apache Maven.
Otworzenie projektu w IntelliJ IDEA
Zanim wprowadzę zmiany w projekcie, otwieram go w IntelliJ IDEA Ultimate 10.5 (bez wyraźnych powodów, innych niż nabywanie umiejętności wskazania właściwego narzędzia dla danego zadania, kiedy zostanę o taką opinię poproszony - cenna rzecz). Samo użycie IDE to sprawa oczywista - łatwość zmian i wsparcie dla typowych zadań programistycznych - automatyczna kompilacja, budowanie projektu, itp.
Konfiguracja projektu - edycja pom.xml
W pom.xml podmieniam zależność javax/javaee-api/6.0 na org.apache.openejb/openejb-core/4.0.0-SNAPSHOT (skrót w IDEA: Cmd+N) i w zasadzie projekt jest gotowy do prac programistycznych.
Z kilkoma dodatkowymi, mniej istotnymi zmianami, pom.xml prezentuje się jak poniżej.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>pl.japila.javaee6.ejb31</groupId> <artifactId>OPENEJB-1128</artifactId> <version>1.0</version> <packaging>ejb</packaging> <name>OPENEJB-1128</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.apache.openejb</groupId> <artifactId>openejb-core</artifactId> <version>4.0.0-SNAPSHOT</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ejb-plugin</artifactId> <version>2.3</version> <configuration> <ejbVersion>3.1</ejbVersion> </configuration> </plugin> </plugins> </build> </project>
Zakładam czapeczkę programisty.
Utworzenie bezstanowego ziarna sesyjnego EJB 3.1 - MySession
Tworzę pojedynczy komponent EJB, który dla moich potrzeb będzie bezstanowym ziarnem sesyjnym EJB 3.1 (ang. stateless session bean) bez jawnego interfejsu biznesowego.
Korzystam ze skrótu Cmd+N
, aby później określić nazwę ziarna EJB i jego klasy (klasa jest nazwana w konwencji "<nazwa ziarna> + Bean", więc na potrzeby tego artykułu spełnia moje oczekiwania i nie potrzebna jest jakakolwiek interwencja).
Wprowadzam zmiany tak, aby ostatecznie uzyskać poniższą klasę.
package pl.japila.javaee6.ejb31; import javax.ejb.Stateless; @Stateless public class MySessionBean { private int count; public int countMethodCalls() { return ++count; } }
Klasa testująca - MySessionBeanTest
Nadeszła pora, kiedy utworzę klasę testującą funkcjonalność oferowaną przez komponent MySession. Korzystam z możliwości IntelliJ IDEA.
Tworzę katalog src/main/test, który oznaczam jako Test Source Root.
Postępując zgodnie z dokumentacją Creating JUnit Test Cases wciskam kombinację klawiszy Cmd+Shift+T w edytorze klasy MySessionBean i wybieram Create New Test... Zaznaczam metodę countMethodCalls(), dla której zostanie utworzona metoda testująca.
Katalogiem docelowym jest właśnie utworzony src/main/test.
Zmiany, zmiany i jeszcze raz zmiany, i klaska przedstawia się jak poniżej.
package pl.japila.javaee6.ejb31; import org.junit.Test; import javax.ejb.embeddable.EJBContainer; import javax.naming.Context; import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertNotNull; public class MySessionBeanTest { @Test public void testCountMethodCalls() throws Exception { final Context context = EJBContainer.createEJBContainer().getContext(); final MySessionBean myEjb = (MySessionBean) context.lookup("java:global/OPENEJB-1128/MySessionBean"); assertNotNull(myEjb); assertEquals(1, myEjb.countMethodCalls()); } }
Warto zwrócić uwagę na kilka cech nowej specyfikacji EJB 3.1 - możliwość uruchomienia kontenera w trybie wbudowanym przez wywołanie statycznej metody javax.ejb.embeddable.EJBContainer.createEJBContainer() oraz globalna przestrzeń nazewnicza JNDI z java:global i ustandaryzowanym nazewnictwem wpisów w drzewie JNDI. Wszystko to sprawia, że poprzednia ciężkość kontenerów EJB przechodzi po mału w zapomnienie i przypominana jest jeszcze w projektach, które nie tylko, że pamiętają Java EE 5, ale i wręcz J2EE 1.4. Aż strach pomyśleć, jak to kiedyś było, więc cieszmy się wciąż słoneczną pogodą za oknem i naszym świeżutkim projektem z nowiutkimi i lśniącymi możliwościami najnowszej wersji EJB 3.1. I znów radość zagościła w naszych sercach :)
Uruchomienie testu - Ctrl+Shift+R
Uruchamiam test korzystając z kombinacji klawiszy Ctrl+Shift+R.
Wynik uruchomienia testu zgodny z oczekiwaniami. Całość zielona. Krótko i na temat. To lubię!






