今天返璞归真,在JBoss上做了一个EJB2的简单例子,我是怎么做的呢?
首先我们看下面的RMI架构图,它说明了本地对象如何与远程对象进行通信:
我们采用WTP创建EJB工程的向导,还是利用那个经典的例子:
利用XDoclet自动生成的工程包含的文件有:
这里我们忽略Local接口。
在ConverterBean的foo()方法中编写我们的业务逻辑。
默认生成一个ejb-jar.xml配置文件,它是EJB规范中要求的描述文件,可能像这样:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar id="ejb-jar_1" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1">
<description><![CDATA[TestEJB2 generated by eclipse wtp xdoclet extension.]]></description>
<display-name>TestEJB2</display-name>
<enterprise-beans>
<!-- Session Beans -->
<session id="Session_Converter">
<description><![CDATA[An EJB named Converter]]></description>
<display-name>Converter</display-name>
<ejb-name>Converter</ejb-name>
<home>cn.com.samueli.ejb2.ConverterHome</home>
<remote>cn.com.samueli.ejb2.Converter</remote>
<ejb-class>cn.com.samueli.ejb2.ConverterBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
<!--
To add session beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called session-beans.xml that contains
the <session></session> markup for those beans.
-->
<!-- Entity Beans -->
<!--
To add entity beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called entity-beans.xml that contains
the <entity></entity> markup for those beans.
-->
<!-- Message Driven Beans -->
<!--
To add message driven beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called message-driven-beans.xml that contains
the <message-driven></message-driven> markup for those beans.
-->
</enterprise-beans>
</ejb-jar>
我们这里部署在JBoss4上,所以还需要特定于容器的部署描述文件,可能像这样:(jboss.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd">
<jboss>
<enterprise-beans>
<session>
<ejb-name>Converter</ejb-name>
<jndi-name>MyConverter</jndi-name>
</session>
</enterprise-beans>
</jboss>
万事俱备,我们部署我们的EJB应用到<JBoss-install>/server/default/deploy下面,并启动服务。
客户端我们采用两种方式来调用远程对象,一种利用Lookup查找接口,一种利用Spring的支持:
首先来看第一种:
public static void main(String[] args) {
try {
Context initial = new InitialContext();
Object objref = initial.lookup("MyConverter");
ConverterHome home = (ConverterHome) PortableRemoteObject.narrow(
objref, ConverterHome.class);
Converter c = home.create();
c.foo();
System.exit(0);
} catch (Exception ex) {
System.err.println("Caught an unexpected exception!");
ex.printStackTrace();
}
}
由于采用JNDI查找,我们还需要这样的配置文件:(jndi.properties)
# jndi.properties --
#
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
第二种方法,对于spring支持,我们首先需要有这样的配置文件:(applicationContext.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="jndiTemplate"
class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<!--
<prop key="java.naming.provider.url">
t3://127.0.0.1:7001
</prop>
<prop key="java.naming.factory.initial">
weblogic.jndi.WLInitialContextFactory
</prop>
<prop key="java.naming.provider.url">
iiop://127.0.0.1:2809
</prop>
<prop key="java.naming.factory.initial">
com.ibm.websphere.naming.WsnInitialContextFactory
</prop>
-->
<prop key="java.naming.provider.url">
localhost:1099
</prop>
<prop key="java.naming.factory.initial">
org.jnp.interfaces.NamingContextFactory
</prop>
</props>
</property>
</bean>
<bean id="ConvertorEJB"
class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean"
lazy-init="true">
<property name="jndiTemplate">
<ref local="jndiTemplate" />
</property>
<property name="jndiName">
<value>MyConverter</value>
</property>
<property name="businessInterface">
<value>cn.com.samueli.ejb2.Converter</value>
</property>
</bean>
</beans>
我们的代码中就很简单了,可能是这样:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Converter c = (Converter) context.getBean("ConvertorEJB");
try {
c.foo();
} catch (RemoteException e) {
e.printStackTrace();
}
OK,我们的两种客户端访问方式都可以调用远程对象的方法,并输出了理想中的结果。
当然在上面的过程也出现了一些问题,比如在客户端运行时出现了一些错误:
客户端代码片段:
try {
Context initial = new InitialContext();
Object objref = initial.lookup("java:comp/env/ejb/Converter/MyConverter");
ConverterHome home = (ConverterHome) PortableRemoteObject.narrow(
objref, ConverterHome.class);
Converter c = home.create();
c.foo();
System.exit(0);
} catch (Exception ex) {
System.err.println("Caught an unexpected exception!");
ex.printStackTrace();
}
报错:
javax.naming.NoInitialContextException: Cannot instantiate class:
org.jnp.interfaces.NamingContextFactory
[Root exception is java.lang.ClassNotFoundException:
org.jnp.interfaces.NamingContextFactory]
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.init(Unknown Source)
at javax.naming.InitialContext.<init>(Unknown Source)
at ConverterClient.main(ConverterClient.java:12)
原来是缺少客户端依赖文件,把<JBoss-install>/client目录下的:jbossall-client.jar和jnp-client.jar添加到Build path中,再运行仍然报错:
javax.naming.NameNotFoundException: comp not bound
Google了一下,发现原来问题是这样:
CJSDN开发者社区 写道
当你的程序运行在 container 环境中的时候 java:comp 才需要
当你的程序运行在客户端的时候,直接使用
lookup("interest/Interest") 就可以了
在运行之前你可以访问
http://localhost:端口/jmx-console/
然后使用 service=JNDIView
点击最后的 list 下面的 invoke 看一看现在 jboss3 的 jndi 里面都有哪些对象
直接看最下面的 global 部分就可以了,看看有没有 interest/Interest
如果有,那就说明部署成功了,调用应该就没有问题了
于是把我的客户端程序的:
Object objref = initial.lookup("java:comp/env/ejb/Converter/MyConverter");
修改为:
Object objref = initial.lookup("MyConverter");
运行OK了。
参考:
http://blog.csdn.net/baobao8505/archive/2007/05/21/1619368.aspx
http://www.blogjava.net/kawaii/archive/2007/02/06/98395.html
- j-rmi.zip (564.3 KB)
- 描述: IBM DW上的一个关于分布式对象的教程。
- 下载次数: 15
分享到:
相关推荐
在Myeclipse,基于JBOSS EJB3.0实现了EJB3.0的初次体验,确实比EJB2.0方便了许多。文中有完整的过程和代码。
数据 初次化 mysql@oracle 人性化的
RecyclerView的初次体验,item的点击和长按事件,类似与listview的条目条目点击事件,item的增删动画
研究表明,大倾角煤层基本顶初次断裂的空间顺序为"中上部→中下部→上部→下部"。结合数值模拟、现场监测等手段,验证了基本顶初次断裂过程中采场围岩应力场分布及矿压显现具有时序性和非对称特征。
针对祁南煤矿34下4综采工作面采用7.0 m×3.0 m的大断面开切眼,利用FLAC2D数值模拟软件,对综采工作面初次来压期间的应力分布规律进行了数值模拟,得到了工作面初次来压期间工作面的垂直应力及水平应力的分布规律,可为...
针对神东矿区顶板岩层强度不高、厚度较大、稳定性和整体性较好的特点,开展了水力压裂技术在神东矿区初次放顶中的应用研究。根据神东矿区顶板岩层特点和初次放顶存在的问题,选取神东锦界煤矿31405工作面为水力压裂...
为了研究阻化剂对煤样初次与二次氧化特性的影响,选用KCl、Ca Cl2、Mg Cl2和Na Cl等4种常用阻化剂对原煤样和初次氧化煤样分别进行处理,通过程序升温实验,研究阻化剂对煤的两次氧化过程自燃特性的影响程度。...
库卡机器人初次通电和IO配置说明文档 :提供“库卡机器人初次通电”免费资料下载,主要包括电气连接、初次上电、安全配置、零点校正、IO配置等内容
初次体验selenium在web测试中的应用
员工初次定级标准表.xls
针对潘三矿17181(1)工作面煤层上方厚硬顶板大面积悬露、严重威胁矿井安全生产的现状,实施深孔松动爆破技术以求减小厚硬顶板的初次垮落步距。实践表明:对爆破参数和炮孔布置进行合理设计,顶板的初次垮落步距从预测值...
适用于初次使用库卡机器人进行调试的工程人员,里面有库卡最基本的配置单元
针对神东补连塔煤矿顶板岩层厚度较大,强度不高,整体性好的基本特征,选取补连塔煤矿22309工作面作为水力压裂试验点,研究水力压裂对顶板岩层的弱化及初次放顶垮落的作用。基于空心包体应变测量技术,实时监测水力压裂...
以陕北榆神矿区浅埋近距离煤层群下行开采为背景,通过物理模拟研究了下煤层工作面初次来压的顶板结构特征。近距离煤层下煤层开采时,间隔岩层顶板一般具有单一关键层,顶板初次破断形成"非对称三铰拱结构",结构上的载荷...
在初次设计电源之前,应确保电源所采用的印刷电路板符合Power Integrations器件数据手册中指定的布局指南。如果在实验用面包板或原始样板上搭建设计的电路,会引入很多寄生元件,这样会影响电源的正常工作。而且,...
根据石嘴山矿区的地质条件及回采实践,分析了以2层煤为代表的"三软"煤层在初采初放期间,其顶板控制方面存在的问题,以及问题产生的机理。根据顶板常发、易发的问题分析,结合笔者的工作经验,提出了几点意见,以供参考...
华为s2700交换机初次使用常用配置命令
在采煤工作面初次放顶技术管理中,回采工作面初次放顶过程由于顶板岩层以及悬露面积增加,就会造成煤柱与切顶支柱承受压力增加,出现煤柱压碎、煤壁片邦等现象,甚至出现冒顶事故的发生。因此,要构建科学有效的技术运用...