FeaturesPluginsDocs & SupportCommunityPartners

使用GlassFish v2、Apache Maven 2和NetBeans IDE 6.0构建EJB 3.0 应用程序

为了修复Apache OpenEJB运行中的潜在错误,即系统错误地拒绝使用remove()方法(GERONIMO-3452 Stateless Session EJBs cannot contain a remove() method),我需要构建一个环境,我决定使用一些可用的工具创建环境并最小化创建时间。我决定通过以下方法解决问题:首先在符合Java EE 5规范的GlassFish v2应用服务器(Java EE 5的参考实现)上运行它,然后根据它是否能够正确运行再采取措施。

内容

  1. 软件需求
  2. 创建项目结构
    1. 创建父结构——ejb3-remove-stateless
    2. 创建子项目——ejb3-remove-stateless-ejb3
    3. 创建子项目——ejb3-remove-stateless-client
    4. 完整的项目结构
  3. 创建EJB bean——Removable
    1. 声明EJB 3.0库的依赖关系
    2. 远程业务接口——RemovableRemote
    3. bean类型——RemovableBean
  4. 创建远程客户机——RemovableClient
  5. 启动
    1. GlassFish服务器启动
    2. 安装EJB bean——Removable
    3. 远程客户机启动——RemovableClient

软件需求

要创建EJB 3.0应用程序构建环境,需要使用以下项目:

假定以上软件已全部安装并且运行正常。软件安装的方法为将文件解压到所选目录中。

要安装NetBeans Maven2项目支持插件,需要启动NetBeans IDE 6.0。接下来,选择Tools > Plugins 菜单,从出现的对话框中选择Available Plugins选项卡并选择插件。

完整的项目可从ejb3-remove-stateless.zip获得。

创建项目结构

2.1 创建父项目——ejb3-remove-stateless

为了使Apache Maven 2(后文简称为m2)运行的项目更具条理性,我们首先将创建一个父项目(主项目)。创建一个pom类型的项目,其中包含两个子项目——EJB bean模块和远程客户机模块。

我们也可以手动创建项目——使用mvn命令,或者使用NetBeans Maven2 project support插件。使用插件可以简化环境创建过程,并且可以更轻松地使用m2。有了插件后,我们能够在IDE级别执行大部分的管理功能。目前,这些功能是通过命令行执行的。

假设NetBeans Maven2项目支持插件已正确安装,选择File > New Project菜单,然后选择Maven类别中的Maven Project


(单击查看大图)

单击Next >


(单击查看大图)

再次单击Next > ,选择Maven Quickstart Project 原型。

在接下来出来的界面中选择以下项目设置:

  • Project Name: ejb3-remove-stateless
  • Project Location: C:\
  • Group Id: pl.jaceklaskowski.javaee
  • Version: 1.0
  • Package: pl.jaceklaskowski.javaee


(单击查看大图)

这些设置可能与前面给出的不同,但是本文后面的内容假设这些内容是相同的。

单击Finish完成项目的创建。

现在,我们已经创建了一个jar类型的项目。我们将修改项目的配置,使它能够履行父项目的角色。选择新的ejb3-remove-stateless项目,右键单击鼠标并从下拉菜单中选择Properties选项。将Packaging字段的jar值改为pom


(单击查看大图)

我们还需要修改项目的属性,因为我们要使用Java版本。


(单击查看大图)

单击OK,确认修改。

最后一步是删除src目录,它是在创建项目时默认创建的,但我们在这里不会使用到,至此,项目准备完毕。要删除目录,转到Files选项卡,选择src目录,并从下拉菜单中选择Delete

从项目中删除测试库junit-3.8.1(我们稍后将修改为版本4.2)。

创建子项目——ejb3-remove-stateless-ejb3

要创建ejb3-remove-stateless-ejb3 子项目,我们还要再一次使用NetBeans IDE 6.0。我们将执行与创建ejb3-remove-stateless主项目类似的过程,仅仅需要修改目标子项目的位置,使它显示在主项目的目录中(类似于在父类别中执行mvn create:archetype命令)。

选择以下项目设置:

  • Project Name: ejb3-remove-stateless-ejb3
  • Project Location: C:\ejb3-remove-stateless
  • Group Id: pl.jaceklaskowski.javaee
  • Version: 1.0
  • Package: pl.jaceklaskowski.javaee


(单击查看大图)

单击Finish完成项目创建。

成功创建项目后,由于对模块ejb3-remove-stateless-ejb3进行了注册,父项目的pom.xml文件将被修改。

<modules>

   <module>ejb3-remove-stateless-ejb3</module>

</modules>

同父项目的处理相同,我们将删除junit-3.8.1测试库。我们还将删除用于单个测试的Test Packages库(方法为选择Files 选项卡,展开ejb3-remove-stateless-ejb3 (jar) > src 文件夹删除以感叹号标记的test目录)。

我们将对项目进行配置,方法为:将Packaging改为ejb。右键单击鼠标,选择Properties菜单并在对话框中将Packaging字段的值由jar改为ejb


(单击查看大图)

单击OK确认修改。

删除pl.jaceklaskowski.javaee.App类别(从Source Packages部分)。最后,对项目进行配置,使它包含EJB 3.0 bean。要进行修改必须直接编辑pom.xml文件。我们将在文件配置中添加maven-ejb-plugin

<plugin>

   <groupId>org.apache.maven.plugins</groupId>

   <artifactId>maven-ejb-plugin</artifactId>

   <configuration>

      <ejbVersion>3.0</ejbVersion>

   </configuration>

</plugin>

pom.xml文件修改完毕后,将看到以下内容:

<?xml version="1.0" encoding="UTF-8"?>

<project>

   <parent>

      <artifactId>ejb3-remove-stateless</artifactId>

      <groupId>pl.jaceklaskowski.javaee</groupId>

      <version>1.0</version>

   </parent>

   <modelVersion>4.0.0</modelVersion>

   <groupId>pl.jaceklaskowski.javaee</groupId>

   <artifactId>ejb3-remove-stateless-ejb3</artifactId>

   <name>ejb3-remove-stateless-ejb3</name>

   <packaging>ejb</packaging>

   <version>1.0</version>

   <url>http://www.JacekLaskowski.pl</url>

   <build>

      <plugins>

         <plugin>

            <groupId>org.apache.maven.plugins</groupId>

            <artifactId>maven-ejb-plugin</artifactId>

            <configuration>

               <ejbVersion>3.0</ejbVersion>

            </configuration>

         </plugin>

      </plugins>

   </build>

</project>

创建子项目——ejb3-remove-stateless-client

我们将创建ejb3-remove-stateless-client项目,方法与前一个子项目的创建方式相同。但是Project Location 必须为ejb3-remove-stateless 父项目目录。

选择以下项目设置

  • Project Name: ejb3-remove-stateless-client
  • Project Location: C:\ejb3-remove-stateless
  • Group Id: pl.jaceklaskowski.javaee
  • Version: 1.0
  • Package: pl.jaceklaskowski.javaee


(单击查看大图)

删除junit-3.8.1.jar 测试目录(测试库)、pl.jaceklaskowski.javee.App 类别(源代码包)以及pl.jaceklaskowski.javaee.AppTest测试包,此时,我们已完成了项目的准备阶段。

完整的项目结构

项目结构如下所示:

创建EJB bean - Removable

声明EJB 3.0库的依赖关系

创建EJB bean的第一步是定义项目依赖关系。

我们将添加EJB 3.0库,org.apache.geronimo.specs:geronimo-ejb_3.0_spec:1.0.

远程业务接口——RemovableRemote

我们将在ejb3-remove-stateless-ejb3 项目中创建远程业务接口RemovableRemote (类别pl.jaceklaskowski.javaee.RemovableRemote)。

package pl.jaceklaskowski.javaee;

import javax.ejb.Remote;

@Remote

public interface RemovableRemote {

   public void remove(String message);

}

Bean类型——RemovableBean

我们将通过实现RemovableRemote业务接口创建bean类型RemovableBean(类别pl.jaceklaskowski.javaee.RemovableBean)。

package pl.jaceklaskowski.javaee;

import javax.ejb.Stateless;

@Stateless(mappedName="Removable")

public class RemovableBean implements RemovableRemote {

    public void remove(String msg) {

        System.out.println(msg);

    }

}

使用@Stateless annotation mappedName属性可以指定一些名称,然后使用这些名称可以通过远程客户机搜索EJB bean(有关更多信息,请参阅How are Global JNDI names assigned to Session / Entity beans?)。

创建远程客户机——RemovableClient

根据GlassFish——How do I access a Remote EJB from a stand-alone java client?中针对bean操作的远程访问说明,我们将创建RemovableClient

首先,我们将通过Libraries > Add Library...定义子项目ejb3-remove-stateless-ejb3(客户机将使用这个子项目类别) 的依赖关系。

添加了依赖关系后,您将在本地库中看到一条错误消息,表示依赖关系是无效的。


(单击查看大图)

要解决这个问题,我们需要构建一个EJB bean——也就是Removable,构建ejb3-remove-stateless-ejb3 项目,然后将库放入m2本地库中。构建方法为选择ejb3-remove-stateless-ejb3 项目,右键单击鼠标并从下拉菜单中选择Build选项。

正确执行这个命令并重新加载ejb3-remove-stateless-client客户机项目(菜单Reload Project)将解决这一问题。

下一步是创建客户机类——pl.jaceklaskowski.javaee.RemovableClient。这一步非常的简单,因此不多做说明。客户机的简单性源于GlassFish库——appserv-rt.jar,其中包含了JNDI配置。我们还需注意如何使用EJB bean的名称——Removable——它是通过@Stateless annotation mappedName属性在bean类别中定义的。

package pl.jaceklaskowski.javaee;

import javax.naming.Context;

import javax.naming.InitialContext;

public class RemovableClient {

    public static void main(String[] args) throws Exception {

        Context ctx = new InitialContext();

        RemovableRemote removable = (RemovableRemote) ctx.lookup("Removable");

        removable.remove("Look at the server's log");

    }

}

这时,我们需要添加项目依赖关系,即属于GlassFish服务器——appserv-rt.jar的库以及system中的javaee.jar system(根据System Dependencies)。通过变量glassfish.home查看安装GlassFish的文件系统的依赖关系,默认位置为c:/apps/glassfish

<?xml version="1.0" encoding="UTF-8"?>

<project>

    <parent>

        <artifactId>ejb3-remove-stateless</artifactId>

        <groupId>pl.jaceklaskowski.javaee</groupId>

        <version>1.0</version>

    </parent>

    <modelVersion>4.0.0</modelVersion>

    <groupId>pl.jaceklaskowski.javaee</groupId>

    <artifactId>ejb3-remove-stateless-client</artifactId>

    <name>ejb3-remove-stateless-client</name>

    <version>1.0</version>

    <properties>

        <glassfish.home>c:/apps/glassfish</glassfish.home>

    </properties>

    <dependencies>

        <dependency>

            <groupId>glassfish</groupId>

            <artifactId>appserv-rt.jar</artifactId>

            <version>LATEST</version>

            <scope>system</scope>

            <systemPath>${glassfish.home}/lib/appserv-rt.jar</systemPath>

        </dependency>

        <dependency>

            <groupId>glassfish</groupId>

            <artifactId>javaee.jar</artifactId>

            <version>LATEST</version>

            <scope>system</scope>

            <systemPath>${glassfish.home}/lib/javaee.jar</systemPath>

        </dependency>

        <dependency>

            <groupId>pl.jaceklaskowski.javaee</groupId>

            <artifactId>ejb3-remove-stateless-ejb3</artifactId>

            <version>1.0</version>

        </dependency>

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>4.2</version>

            <scope>test</scope>

        </dependency>

    </dependencies>

    <build>

        <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-surefire-plugin</artifactId>

                <configuration>

                    <includes>

                        <include>none</include>

                    </includes>

                </configuration>

                <executions>

                    <execution>

                        <id>run RemovableClientTest</id>

                        <phase>integration-test</phase>

                        <configuration>

                            <includes>

                                <include>**/RemovableClientTest.java</include>

                            </includes>

                        </configuration>

                        <goals>

                            <goal>test</goal>

                        </goals>

                    </execution>

                </executions>

            </plugin>

        </plugins>

    </build>

</project>

模块配置的一个有趣的部分是maven-surefire-plugin的配置,默认情况下它只执行符合none模式的测试,以这种方式进行配置(在本例中none模式意味着不会执行任何测试,因为所有测试都不符合模式,但是执行单个的RemovableClientTest会更加准确),并且只在完成集成测试阶段期间执行。

不管客户机类的可访问性如何,我们将从m2级别执行自动启动,此过程需要借助一个测试——RemovableClientTestpl.jaceklaskowski.javaee.RemovableClientTest 类别),该测试是通过Test Packages文件夹构建的。

package pl.jaceklaskowski.javaee;

import javax.naming.Context;

import javax.naming.InitialContext;

import org.junit.Test;

public class RemovableClientTest {

    @Test

    public void runRemoteClient() throws Exception {

        Context ctx = new InitialContext();

        RemovableRemote removable = (RemovableRemote) ctx.lookup("Removable");

        removable.remove("Look at the server's log");

    }

}

这种类型的测试在默认情况下不会启动(请参考pom.xml文件中的maven-surefire-plugin配置),因为在启动测试之前,需要在GlassFish应用服务器上先启动bean(如果修改了测试实现方式,则不能够创建项目并且也不能在服务器上安装bean)。

启动

要启动项目,首先要在GlassFish服务器上安装Removable bean ,然后启动RemovableClientTest

GlassFish服务器启动

在安装bean之前,我们先要使用asadmin start-domain命令启动GlassFish(之前已定义了变量PATH以包含GlassFish bin 目录) 。

$ asadmin.bat start-domain domain1

Starting Domain domain1, please wait.

Log redirected to c:\apps\glassfish\domains\domain1\logs\server.log.

Redirecting output to C:/apps/glassfish/domains/domain1/logs/server.log

Domain domain1 is ready to receive client requests. Additional services are being started in background.

Domain [domain1] is running [Sun Java System Application Server 9.1 (build b58d-fcs)]

with its configuration and logs at: [c:\apps\glassfish\domains].

Admin Console is available at [http://localhost:4848].

Use the same port [4848] for "asadmin" commands.

User web applications are available at these URLs:

[http://localhost:8080 https://localhost:8181 ].

Following web-contexts are available:

[/web1  /__wstx-services ].

Standard JMX Clients (like JConsole) can connect to JMXServiceURL:

[service:jmx:rmi:///jndi/rmi://dev:8686/jmxrmi] for domain management purposes.

Domain listens on at least following ports for connections:

[8080 8181 4848 3700 3820 3920 8686 ].

Domain does not support application server clusters and other standalone instances.

安装EJB bean——Removable

在创建之前,先要安装bean 。然而,在定义客户机依赖关系(ejb3-remove-stateless-client 项目)的过程中实际已经完成了这一步骤。在ejb3-remove-stateless-ejb3项目target 目录,存在一个ejb3-remove-stateless-ejb3-1.0.jar文件。这是一个bean分配文件。我们将使用asadmin deploy 命令安装该文件。

$ asadmin.bat deploy --user admin ejb3-remove-stateless-ejb3/target/ejb3-remove-stateless-ejb3-1.0.jar

Command deploy executed successfully.

在服务器的管理控制台(默认情况下通过地址http://localhost:4848访问),我们将查看EJB Removable bean是否已经正确安装。


(单击查看大图)

远程客户机启动——RemovableClient

首先,我们将构建完整的ejb3-remove-stateless项目,方法为从菜单中选择Build选项。

成功启动命令后,您将看到以下通知内容:

...

------------------------------------------------------------------------

Reactor Summary:

------------------------------------------------------------------------

ejb3-remove-stateless ................................. SUCCESS [1.500s]

ejb3-remove-stateless-ejb3 ............................ SUCCESS [0.610s]

ejb3-remove-stateless-client .......................... SUCCESS [0.921s]

------------------------------------------------------------------------

------------------------------------------------------------------------

BUILD SUCCESSFUL

------------------------------------------------------------------------

...

当然,选择Build选项即可执行在m2中的安装 步骤,同时也宣告集成测试阶段的完成,本文的测试也告一段落。

使用mvn integration-test 命令即可立即启动客户机,在本文的例子中使用NetBeans IDE 6.0作为图形工具来启动m2命令——即选择ejb3-remove-stateless-client 项目,右键单击鼠标并从菜单中选择Custom > Goals...选项

可通过Build Lifecycle Phases页面获得m2阶段列表。

接下来我们将执行集成测试阶段。

成功启动测试后,您将在NetBeans IDE看到如下所示的内容:

...

-------------------------------------------------------

 T E S T S

-------------------------------------------------------

Running pl.jaceklaskowski.javaee.RemovableClientTest

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.203 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

------------------------------------------------------------------------

BUILD SUCCESSFUL

------------------------------------------------------------------------

...

同时将在事件的GlassFish日志(GlassFisha主目录的domains/domain1/logs/server.log文件)中看到如下内容

[#|2007-09-03T22:41:59.750+0200|INFO|sun-appserver9.1|javax.enterprise.system.stream.out|_ThreadID=16;_ThreadName=p:

thread-pool-1; w: 8;|

Look at the server's log|#]

尽管已经成功启动了远程服务器,但并不表示解决方案已经完成。还需要启动测试来安装bean。如果在安装之前尝试执行Build选项,则会收到一条错误消息。欢迎提出改进建议。接下来的文章将介绍Apache OpenEJB 3.0-SNAPSHOT服务器。

相关链接

Bookmark this page

del.icio.us furl simpy slashdot technorati digg
Companion
Projects:
MySQL Database Server   Open JDK: an Open SourceJDK   GlassFish Community: an Open Source Application Server    Mobile & Embedded Community    Open Solaris   java.net - The Source for Java Technology Collaboration   Virtual Box - full virtualizer  Open ESB - The Open Enterprise Service Bus Powered by