EJB到底是什么是这个看完才知道Enterprise Java Bean,其实就是进一步封装了RMI的一个技术,让编程人员可以更专注于功能的实现而不是其连接。引用原文中的一段话如下
通过RMI 技术,J2EE 将EJB 组件创建为远程对象,EJB 虽然用了RMI 技术,但是却只需要定义远程接口而无需生成他们的实现类,这样就将RMI 技术中的一些细节问题屏蔽了。但不管怎么说,EJB 的基础仍然是RMI,所以,如果你想了解EJB 的原理,只要把RMI的原理搞清楚就行了。你也就弄清楚了什么时候用EJB 什么时候不需要用EJB 了。
环境配置
jdkeclipsewildfly(以前叫Jboss)
可以直接在eclipse的插件市场中下载Help -> Eclipse Markerplace , 搜素“JBoss”并install
不过这个还只是在eclipse开启wildfly服务的一个插件,真正的wildfly还要再下载
Window -> Show View -> Other里面找到Server文件夹下的Servers,打开Servers窗口 Servers窗口里右键New->Server,建立一个新的服务器,比如选择WildFly 8.X然后Next -> Next,然后就既不能Next也不能Finish了,因为你还没有装wildfly,此时页面里的Home Directory是空的,其右上角有个链接Download and install runtime,通过这个链接可以直接下载安装wildfly。装好wildfly后就可以顺利的新建server了。
关于wildfly
我们写的EJB项目是要发布在一个ejb container里作为服务端程序运行wildfly是一个ejb containerwildfly同时也是一个web container,可以发布web服务,也就是网页EJB基于RMI,可以用来做分布式计算,因为调用的是服务端的方法,网络上只传输参数和结果
wildfly上发布ejb项目
eclipse中建立EJB项目
在eclipse的插件市场里装好JBoss后,就可以直接建立EJB项目了 File -> New -> Other -> EJB -> EJB Project
手动发布EJB项目
假设正在编辑的EJB项目名为EJB首先右键项目,Export -> EJB EJB JAR files,生成一个名为EJB.jar的文件指定Destination,则可以在桌面看到生成的EJB.jar将这个EJB.jar文件放到“wildfly根目录/standalone/deployments”文件夹下 运行“wildfly根目录/standalone/add-user.bat”来添加用户,根据提示操作即可运行“wildfly根目录/standalone/standalone.bat”即可以启动wildfly,其自动检测“wildfly根目录/standalone/deployments”目录下的jar文件并发布。ejb程序这就开始运行了,其运行的输出结果也会显示在这个命令行界面上
直接在eclipse里运行EJB Project
右键项目Run as -> Run on server 选择刚刚安装好的wildfly服务器OK这就运行了,输出会显示在eclipse里的Console里,没有这个窗口就Window->Show View里去打开
Hello EJB
惯例写一个Hello程序来体验学习整个结构如下
Server端HelloEJB项目
项目建立参照前文eclipse中建立EJB项目server包
IHello接口HelloBean类实现了IHello接口
package server;
public interface IHello {
String say();
}
package server;
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Stateless
@Remote(IHello.class)
public class HelloBean implements IHello{
@Override
public String
say() {
return "Hello EJB";
}
}
server端就这么点东西
client端HelloEJBClient项目
这是建立的一个普通的java projectsrc目录下client包,一个client.java,代码具体后面内容再说
//client
.java
package client
import javax
.naming.Context
import javax
.naming.InitialContext
import javax
.naming.NamingException
import server
.IHello
public class client {
public static void main(String[] args) {
try {
java
.util.Properties p = new java
.util.Properties()
p
.put(Context
.URL_PKG_PREFIXES,
"org.jboss.ejb.client.naming")
Context context = new InitialContext(p)
IHello obj = (IHello) context
.lookup(
"ejb:/HelloEJB/HelloBean!" + IHello
.class.getName())
String str = obj
.say()
System
.out.println(str)
} catch (NamingException e) {
e
.printStackTrace()
}
}
}
因为需要用到HelloEJB项目里的server包下的IHello接口,所以 把HelloEJB项目添加到HelloEJBClient的build path里
右键HelloEJBClient项目 -> Build Path -> Configure Build Path找到Projects标签卡,Add里选中HelloEJB项目
配置client端的属性
src目录下右键New->Other->General->File文件名为“jboss-ejb-client.properties”,eclipse会识别.properties 这个后缀,即配置文件保证该文件位于src目录下添加如下内容
添加client端依赖的jboss包,方法简而言之就是根据console的错误提示,缺失哪个包就到wildfly里面去找
那么前提就是要运行client端来输出错误信息
右键HelloEJB项目,Run As -> Run on Server启动服务端右键client.java,Run As -> Java Application
最终确定下HelloEJBClient项目所需要的数目最少的包为下面这几个
均位于“wildfly-8.2.1.Final\modules\system\layers\base\org\jboss”目录下
client端代码
java
.util.Properties p = new java
.util.Properties()
p
.put(Context
.URL_PKG_PREFIXES,
"org.jboss.ejb.client.naming")
Context context = new InitialContext(p)
获取一个上下文Context那么什么是上下文呢,我也不知道
IHello obj = (IHello) context
.lookup(
"ejb:/HelloEJB/HelloBean!" + IHello
.class.getName())
通过JDNI来获取远程对象关于lookup的参数格式,以stateful为例
// The JNDI lookup name
for a stateful session bean has the syntax
of:
// ejb:<appName>/<moduleName>/<distinctName>/<beanName>!<viewClassName>?stateful
//
// <appName> The application name
is the name
of the EAR that the EJB
is deployed
in
// (without the .ear).
If the EJB JAR
is not deployed
in an EAR
then this
is
// blank. The app name can also be specified
in the EAR
's application.xml
//
// <moduleName> By the
default the module name
is the name
of the EJB JAR
file (without the
// .jar suffix). The module name might be overridden
in the ejb-jar.xml
//
// <distinctName> : WildFly allows each deployment
to have an (optional) distinct name.
// This example does
not use this so leave it blank.
//
// <beanName> : The name
of the session been
to be invoked.
//
// <viewClassName>: The fully qualified classname
of the remote interface. Must include
// the whole
package name.
至于stateless,就不加最后的“?stateful”即可
关于stateful和stateless的javabean的区别,不赘述了
其实通过server端启动的输出信息也可以看到发布的ejb的jndi
String str = obj
.say()
System
.out.println(str)
通过IHello接口调用远程对象方法,获得返回信息str并输出到console注意在say()这个方法的实现里,即Hello.java里的这个方法的实现里的System.out.println()是会输出到server端的标准输出的,也就是server端启动时输出了一堆启动信息的那个控制台上
运行client端
前提:server已上线
EJB探索未解之谜
为什么eclipse在手动export引用了第三方类库(比如jdbc)的EJB Project的时候,并不会把我引用的类库也发布到生成的jar里面呢为什么我设置了EJB Project项目的Deploment Assembly(右键项目Properities),将我引用的第三方类库添加到了export里,还是看不到第三方类库的发布呢,相反仅仅在配置文件MANIFEST.MF的Class-Path里看到了类库的名字。坑爹呢!而我按照这个教程去修改了发布的EJB.jar包,结果毫无作用。。。。。。好气啊
而我如果想让wildfly在启动的时候直接添加某个第三方类库又应该 如何配置wildfly呢?tomcat可以直接放在lib目录下,可毕竟是tomcat是个web container,不同于我所需求的EJB项目
一个超笨的方法
目前我有个需求,需要让server端的bean来访问数据库,通过jdbc来访问sql server。无第三方类库的EJB测试通过,唯独调用jdbc来连接sql server的时候报错client报错
server报错
仔细看了看报的错
client端报空指针
也就是说我没能拿到与数据库连接的connection,于是写个输出测试一下(DB跑由Bean调用在server端,输出也在server)
server端并没有输出这两句的任何一句,相反让我找到了这个
好气啊,为什么找不到呢,我明明在eclipse里的build path添加了啊后来经过前文的尝试毫无作用,于是直接把我所需要的第三方类sqljdbc42.jar解压,com和microsoft两个文件夹直接添加到了EJB Project里,反正里面就是我需要的.class文件呗再发布果然运行成功
转载请注明原文地址: https://ju.6miu.com/read-8230.html