Embeddable EJB 3.1 z Apache OpenEJB 4, Apache Maven 3 i IntelliJ IDEA 10.5

Z Jacek Laskowski - Wiki Projektanta Java EE
Skocz do: nawigacji, wyszukiwania

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.

Embedded-ejb31-openejb4-intellijidea.png

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

Embedded-ejb31-openejb4-intellijidea-menu-new-stateless-session.png

, 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).

Embedded-ejb31-openejb4-intellijidea-new-stateless-session.png

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.

Embedded-ejb31-openejb4-intellijidea-test-source-root.png

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.

Embedded-ejb31-openejb4-intellijidea-create-test.png

Katalogiem docelowym jest właśnie utworzony src/main/test.

Embedded-ejb31-openejb4-intellijidea-choose-destination-directory.png

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.

Embedded-ejb31-openejb4-intellijidea-test-run.png

Wynik uruchomienia testu zgodny z oczekiwaniami. Całość zielona. Krótko i na temat. To lubię!

Osobiste
Przestrzenie nazw

Warianty
Działania
Nawigacja
Narzędzia