分类
代码

使用 IDEA 创建 EJB 工程

可能是由于现在 EJB 已经落伍了,网上都找不到最近的文章,我们教材也是以 Eclipse 为例演示的。但是作为一个已经放弃 Eclipse 转投 IDEA 的社会主义好青年,只好亲自试验一番啦。

开发环境

JDK8 + WildFly10 + IDEA2016.1.2

JDK多个是可以共存的,但 JAVA_HOME 变量只能设置一个。WildFly 是压缩包,和 JBoss7.1 也是可以共存的,运行哪个就是哪个。IDEA 作为最智能的 Java IDE 就不解释了。

新建EJB 工程

如图一,打开 IDEA, 新建工程,左侧栏选择 Java Enterprise, 右侧找到 EJB: Enterprise Java Beans, 同时设置好 JDK 版本,应用服务器 WildFly 注意下方勾选 Create ejb-jar.xml 并且 Libraries 选择 Download 这样 IDEA 会自动下载所需的 javax.ejb-api.jar 并且设置好 classpath.

01新建工程
01新建工程

下一步填好保存位置,点击完成,等待下载库文件完毕,IDEA 会自动打开工程。这里我选择名称为 EJBDemo. 如图二。

02工程目录
02工程目录

新建会话 Bean

以实现远程接口的无状态会话 Bean 为例,我们新建一个 Stateless Session Bean.

创建远程接口

如图三所示,新建一个 SayHello 接口。

03新建接口
03新建接口

并修改代码如下:

package com.youthlin.javaee.ejb.stateless;

import javax.ejb.Remote;

/**
 * Created by lin on 2016-05-19-019.
 * 无状态会话 Bean 接口
 */
@Remote
public interface SayHello {
    String sayHello(String name);
}

注意使用 @Remote 标注,表明这是一个远程接口,我们在客户端使用 EJB 需要这个接口文件,因此远程的意思是说相对于客户端来说,他是远程的。

创建实现类

新建一个 SayHelloImpl 实现类。代码如下:

package com.youthlin.javaee.ejb.stateless.impl;

import com.youthlin.javaee.ejb.stateless.SayHello;

import javax.ejb.Stateless;

/**
 * Created by lin on 2016-05-19-019.
 * 接口实现类
 */
@Stateless
public class SayHelloImpl implements SayHello {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name;
    }
}

标注 @Stateless 表明这是一个无状态的会话 Bean. 这个实现类对客户端是透明的,客户端仅需要拥有刚刚建立的接口即可,不需要关心具体实现。

部署 EJB

由于 IDEA 会把生成的包重命名,比如这里的 EJBDemo 工程生成的是 EJBDemo_ejb_exploded.rar. 为了不出错并和教材兼容,方便起见,我们还是重命名一下改回来。打开 Project Structure(Ctrl + Alt + Shift + S), 定位到 Artifacts 把 Output Directory 从 ...\EJBDemo_ejb_exploded.rar 改为 ...\EJBDemo 并点击 OK. 如图四所示。

04部署设置
04部署设置

之后就可以点击工程右上角的 Run 或 Debug 按钮,以便把工程部署到 Jboss10 上了。不出意外的话,肯定就是成功啦,如图五所示。

05部署成功
05部署成功

如果想在 JBoss 管理后台查看或移除部署的 EJB 可以打开 http://localhost:9990/ 不过你首先得添加一个管理用户,运行 %JBoss_Home%/bin/add-user.bat 按提示操作即可。

客户端调用

因为我们用的是实现远程接口的,因此客户端可以在任意能连接我们 Jboss 服务器的地方工作。比如另一个工程的普通 Java 程序,或 Web 应用。这里为了方便起见,我只是新建一个 Module 测试一下。

复制远程接口文件

新建 Module 后,把远程接口文件拷贝过来。直接在原地 Ctrl + C, 然后再新的 Module 的 src 文件夹上 Ctrl + V 即可,选择保持原有路径。不过因为新建的 Module 是普通 Java 工程,我们发现 @Remote 报错。

在新建的 Module 里新建 lib 文件夹,拷贝 JBoss_Home%/bin/client/jboss-client.jar 到 lib 文件夹中。并打开 Project Structure 设置依赖添加这个 lib 文件夹,如图六。

06jboss-client
06jboss-client

创建客户端程序

新建一个类,SayHelloClient, 代码如下:

package com.youthlin.javaee.ejb.client;

import com.youthlin.javaee.ejb.stateless.SayHello;

import javax.naming.*;
import java.util.Hashtable;

/**
 * Created by lin on 2016-05-19-019.
 * 客户端测试
 */
public class SayHelloClient {
    public static void main(String[] args) {
        Hashtable<String, String> jndiProperties = new Hashtable<>();
        jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        try {
            Context context = new InitialContext(jndiProperties);
            final String appName = "";
            final String moduleName = "EJBDemo";
            final String distinctName = "";
            final String fullName = "ejb:" + appName + "/" + moduleName + "/" + distinctName
                    + "/SayHelloImpl!com.youthlin.javaee.ejb.stateless.SayHello";
            System.out.println("EJB全名=" + fullName);
            SayHello hello = (SayHello) context.lookup(fullName);
            System.out.println(hello.sayHello("Lin"));
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
}

这时还不能直接运行,还需要在 src 下新建一个 jboss-ejb-client.properties 文件,内容如下:

endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.username=lin
remote.connection.default.password=lin

其中端口是8080, 非常重要!旧版本的 JBoss 7等端口都是 4447, WildFly 10 已经是众多服务都在同一个端口了。

端口用8080
Here we are listing 2 connections named “one” and “two”. Ultimately, each of the connections will map to a EJB receiver. So if you have 2 connections, that will setup 2 EJB receivers that will be added to the EJB client context. Each of these connections will be configured with the connection specific properties as follows:
remote.connection.default.host=10.20.30.40
remote.connection.default.port = 8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
As you can see we are using the “remote.connection..” prefix for specifying the connection specific property. The connection name here is “default” and we are setting the “host” property of that connection to point to 10.20.30.40. Similarly we set the “port” for that connection to 4447.参见:http://bbs.csdn.net/topics/390798267#post-398647327

另外 username, password 就是添加 JBoss 用户时设置的用户名和密码。

这时就可以成功运行了,如下图所示。

07运行成功
07运行成功

可能会遇到各种报错,比如 EJBCLIENT000025: No EJB receiver available for handling 就是因为客户端配置文件错误(如端口号)造成的。一般遇到这些错误,在 stackoverflow.com 上都能搜到。其他会话 Bean 的情况也是差不多的,就不再多说了。祝好运。

还有一个例子是我们《软构建与中间件技术》的实验课作业,用的是 JSF + EJB + JPA, 可以在 GitHub 上找到。

END.


“使用 IDEA 创建 EJB 工程”上的5条回复

太感谢作者了,8080的问题难了一天,一直不知道哪里出问题 [/流泪]

创建客户端程序前,需要将module的src文件夹marked as source files,否则无法创建java class文件,不知道是不是IDEA版本的问题
Ps. 我是2014级学弟,给学长通俗易懂的博客点赞(我要是早看到,上机实验就不至于gg了 [/难过]

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

[/鼓掌] [/难过] [/调皮] [/白眼] [/疑问] [/流泪] [/流汗] [/撇嘴] [/抠鼻] [/惊讶] [/微笑] [/得意] [/大兵] [/坏笑] [/呲牙] [/吓到] [/可爱] [/发怒] [/发呆] [/偷笑] [/亲亲]