今天返璞归真,在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
分享到:
相关推荐
内容概要:本文详细介绍了基于多目标粒子群(MOPSO)算法的冷热电联供(CCHP)综合能源系统运行优化的方法和技术细节。文章首先构建了一个涵盖冷、热、电负荷的优化调度模型,该模型不仅考虑了多种能源资源如燃气轮机、电制冷机、锅炉和风光机组,还包括与上级电网的购售电交易。随后,文章展示了MOPSO算法的具体实现步骤,包括粒子初始化、迭代更新、惯性权重调整、非支配排序和拥挤度计算等关键技术环节。此外,文中还讨论了MATLAB仿真平台的优势及其在处理多时间尺度耦合、风光出力波动等方面的应用。最终,通过Pareto前沿分析,揭示了系统在不同条件下的最优运行模式。 适用人群:适用于从事能源系统优化的研究人员、工程师以及对多目标优化算法有兴趣的学习者。 使用场景及目标:①帮助研究人员理解和应用MOPSO算法进行CCHP系统的优化;②为工程师提供具体的代码实现和仿真工具,以便更好地设计和管理实际的能源系统;③促进学术交流和技术进步,推动可持续能源的发展。 其他说明:文章提供了详细的MATLAB代码片段,便于读者理解和复现实验结果。同时,强调了多目标优化在解决复杂能源系统问题中的重要性和优越性。
原始数据集
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 编译闪电般迅速,并发性能卓越,部署轻松简单!Go 语言以极简设计理念和出色工程性能,成为云原生时代的首选编程语言。从 Docker 到 Kubernetes,全球顶尖科技企业都在采用 Go。点击了解 Go 语言的核心优势、实战窍门和未来走向,开启高效编程的全新体验!
数据库
内容概要:本文详细介绍了基于Matlab 2021a的异步电机矢量控制系统中电流滞环控制的实现过程。首先,文章解释了电流环的整体结构,包括定子电流的坐标变换、转矩分量和励磁分量的分离以及旋转变压器模块的应用。接着,展示了电流滞环控制的核心代码,强调了带积分修正的滞环控制机制,并讨论了SVPWM模块的实现技巧。此外,文章探讨了速度环PI参数的自整定设计、谐波分析、磁链观测器的改进方案以及仿真加速技巧。最后,分享了一些实用的调试经验和仿真优化方法,如参数自适应调整、变步长求解器的选择和数据存储格式的优化。 适合人群:从事电机控制领域的研究人员和技术人员,尤其是对异步电机矢量控制和电流滞环控制感兴趣的读者。 使用场景及目标:适用于希望深入了解异步电机矢量控制系统中电流滞环控制实现细节的研究人员和技术人员。目标是帮助读者掌握电流滞环控制的关键技术和调试技巧,提高仿真实践能力。 其他说明:文中提供了丰富的代码片段和调试经验,有助于读者更好地理解和应用所介绍的技术。同时,报告中还包括详细的故障分析和解决方案,确保读者能够避免常见陷阱并顺利进行仿真。
内容概要:本文详细介绍了如何在LabVIEW 2019环境中实现与三菱PLC的通信及其多线程交互。首先探讨了使用OPC和MC两种通讯协议与三菱PLC建立连接的方法,接着讲述了SQLite数据库用于数据存储的具体步骤,然后阐述了JKI状态机框架的应用,最后讲解了通过数组队列实现多线程交互的技术细节。文中不仅提供了具体的代码示例,还分享了许多实用的经验技巧,如异常处理、性能优化等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些正在使用或计划使用LabVIEW进行PLC通信和数据处理的人群。 使用场景及目标:适用于需要构建高效稳定的工业控制系统的企业和个人开发者。主要目的是帮助读者掌握如何利用LabVIEW平台完成复杂的PLC通信任务,提高系统的可靠性和效率。 其他说明:作者强调了在实际应用过程中需要注意的问题,例如硬件兼容性、网络稳定性、数据安全性等方面的内容,并给出了针对性的解决方案。此外,还提到了一些常见的误区和潜在的风险点,为后续的工作提供了宝贵的参考资料。
计算机视觉_深度学习_图像处理_目标检测_OpenCV_TensorFlow_PyTorch_基于YOLOv5改进算法的高精度实时多目标检测与跟踪系统_用于智能监控_自动驾驶_工业
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 编译闪电般迅速,并发性能卓越,部署轻松简单!Go 语言以极简设计理念和出色工程性能,成为云原生时代的首选编程语言。从 Docker 到 Kubernetes,全球顶尖科技企业都在采用 Go。点击了解 Go 语言的核心优势、实战窍门和未来走向,开启高效编程的全新体验!
内容概要:本文详细介绍了威纶通触摸屏与施耐德ATV12变频器之间的Modbus通讯方法,涵盖硬件接线、参数设置、控制程序编写以及调试技巧。首先,文章讲解了正确的硬件连接方式,强调了接线规范和注意事项,如使用带屏蔽的双绞线并确保正确接地。接着,针对ATV12变频器的具体参数设置进行了详尽说明,包括通信模式的选择、波特率、校验位等重要参数的配置。随后,文章展示了如何在威纶通触摸屏上创建Modbus RTU设备,并提供了具体的配置参数和控制命令示例。此外,文中还分享了一些常见的调试问题及其解决办法,如通讯超时、频率设定异常等。最后,给出了实用的调试建议,如使用串口助手抓包分析和加入通讯心跳检测等功能。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些负责PLC编程、HMI界面开发以及设备集成工作的专业人员。 使用场景及目标:适用于需要将威纶通触摸屏与施耐德ATV12变频器进行Modbus通讯连接的实际工程项目中,帮助技术人员顺利完成设备间的通讯配置,确保系统稳定可靠运行。 其他说明:本文不仅提供了详细的理论指导,还结合了丰富的实践经验,能够有效地提高读者在实际工作中解决问题的能力。同时提醒读者,在进行相关操作前务必仔细阅读官方文档,避免因误操作造成不必要的损失。
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 Rust 以内存安全、零成本抽象和并发高效的特性,重塑编程体验。无需垃圾回收,却能通过所有权与借用检查机制杜绝空指针、数据竞争等隐患。从底层系统开发到 Web 服务构建,从物联网设备到高性能区块链,它凭借出色的性能和可靠性,成为开发者的全能利器。拥抱 Rust,解锁高效、安全编程新境界!
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 编译闪电般迅速,并发性能卓越,部署轻松简单!Go 语言以极简设计理念和出色工程性能,成为云原生时代的首选编程语言。从 Docker 到 Kubernetes,全球顶尖科技企业都在采用 Go。点击了解 Go 语言的核心优势、实战窍门和未来走向,开启高效编程的全新体验!
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 Rust 以内存安全、零成本抽象和并发高效的特性,重塑编程体验。无需垃圾回收,却能通过所有权与借用检查机制杜绝空指针、数据竞争等隐患。从底层系统开发到 Web 服务构建,从物联网设备到高性能区块链,它凭借出色的性能和可靠性,成为开发者的全能利器。拥抱 Rust,解锁高效、安全编程新境界!
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 Rust 以内存安全、零成本抽象和并发高效的特性,重塑编程体验。无需垃圾回收,却能通过所有权与借用检查机制杜绝空指针、数据竞争等隐患。从底层系统开发到 Web 服务构建,从物联网设备到高性能区块链,它凭借出色的性能和可靠性,成为开发者的全能利器。拥抱 Rust,解锁高效、安全编程新境界!
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 Rust 以内存安全、零成本抽象和并发高效的特性,重塑编程体验。无需垃圾回收,却能通过所有权与借用检查机制杜绝空指针、数据竞争等隐患。从底层系统开发到 Web 服务构建,从物联网设备到高性能区块链,它凭借出色的性能和可靠性,成为开发者的全能利器。拥抱 Rust,解锁高效、安全编程新境界!
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 编译闪电般迅速,并发性能卓越,部署轻松简单!Go 语言以极简设计理念和出色工程性能,成为云原生时代的首选编程语言。从 Docker 到 Kubernetes,全球顶尖科技企业都在采用 Go。点击了解 Go 语言的核心优势、实战窍门和未来走向,开启高效编程的全新体验!
内容概要:本文详细介绍了直流无感无刷电机的方波控制方法及其初始位置检测方案。主要内容涵盖ADC和比较器结合用于初始位置检测的技术细节,包括代码示例;多种控制方式如开环控制、速度环控制和双闭环控制的具体实现;通信部分采用串口进行数据交换;多重保护机制确保系统的安全可靠;以及启动方式的选择和优化。此外,还讨论了一些硬件特色,如休眠电路和防打火电路的设计。 适合人群:从事电机控制系统设计的研发工程师和技术爱好者,尤其是对直流无感无刷电机有研究兴趣的专业人士。 使用场景及目标:适用于需要深入了解直流无感无刷电机控制原理的研究人员,帮助他们掌握具体的实现技术和优化技巧,从而应用于实际项目中,提高电机控制系统的性能和可靠性。 其他说明:文中提供了大量实用的代码片段和实践经验,强调了实际应用中的注意事项和调试技巧,对于解决常见问题非常有帮助。
内容概要:本文详细介绍了如何利用S7-200可编程逻辑控制器(PLC)和组态王软件实现空调系统的自动化控制。主要内容涵盖IO分配、梯形图编程、接线图与原理图的设计,以及组态王人机界面(HMI)的创建。文中通过具体的例子解释了如何配置温度传感器、手动启停按钮等输入设备,以及如何控制压缩机、风机等输出设备。梯形图编程部分展示了如何根据温度变化控制空调设备的工作状态,确保系统稳定运行。接线图和原理图则提供了硬件连接的具体指导。组态王的画面设计使得操作人员能够直观地监控和控制空调系统,提高了操作便捷性和效率。 适合人群:从事工业自动化控制领域的工程师和技术人员,特别是对PLC编程和HMI设计有一定基础的学习者。 使用场景及目标:适用于需要构建或优化空调控制系统的企业和个人。通过学习本文,读者可以掌握S7-200 PLC和组态王的基本应用方法,提高空调系统的自动化水平,减少人工干预,提升工作效率。 其他说明:文章还分享了一些实际项目中的经验和教训,如正确的接线方式、避免电磁干扰的方法、温度量程转换的注意事项等,帮助读者少走弯路,更快地上手实际操作。
内容概要:本文详细探讨了永磁同步电机(PMSM)的模型预测控制(MPC),涵盖了几种典型的控制方法和技术细节。首先介绍了双环PI控制与空间矢量脉宽调制(SVPWM)的经典组合,讨论了其优点和局限性,并提供了相关代码片段。随后,重点讲解了无差拍预测控制的实现方式,强调了离散化处理的重要性以及其实现过程中需要注意的问题。接着,文章深入分析了矢量选择的方法,包括单矢量、双矢量和三矢量的选择策略及其各自的优缺点。此外,还提到了一些实际测试中遇到的问题,如延迟补偿、参数敏感性和过调制处理等,并分享了一些实用的经验和解决方案。最后,列举了若干重要的参考文献供进一步研究。 适合人群:从事电机控制系统设计的研发工程师、高校师生及相关领域的研究人员。 使用场景及目标:帮助读者理解并掌握PMSM的MPC技术,能够应用于实际工程项目中,提高电机控制系统的性能和稳定性。 其他说明:文中提供的代码片段可以直接用于实验验证,有助于加深对理论的理解。同时,针对不同的应用场景提出了具体的优化建议,便于读者根据实际情况选择合适的控制方案。