JBoss 5中EAR打包时EJB Session Bean无法绑定的问题排查
解决JBoss5 EAR中Session Bean无法绑定的问题
针对你遇到的EAR打包后Session Bean无法绑定的问题,我们可以从模块加载顺序、类可见性和EJB注入配置这几个关键点来排查和修复:
1. 调整EAR模块的加载顺序
在JBoss中,EAR内模块的启动顺序完全遵循application.xml的声明顺序。你当前的配置先启动WAR模块,再启动EJB模块,这会导致WAR初始化时,EJB还未完成JNDI绑定,最终注入失败。
修改application.xml,将EJB模块放在WEB模块之前,确保Session Bean先完成绑定:
<?xml version="1.0" encoding="UTF-8"?> <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" id="Application_ID" version="5"> <display-name>X3</display-name> <!-- 先部署EJB模块,保证Session Bean优先完成绑定 --> <module> <ejb>x3.jar</ejb> </module> <module> <web> <web-uri>x3.war</web-uri> <context-root>x3</context-root> </web> </module> </application>
2. 确保业务接口在共享类路径中
你的业务接口ManageStudentSessionBeanLocal目前仅存在于EJB模块(x3.jar)中,而WAR模块需要访问这个接口才能完成注入。我们可以通过优化打包策略,将接口类放到EAR的共享lib目录,让所有模块都能访问:
修改build.xml的打包逻辑:
<!-- 新增:单独打包业务接口和实体类到共享Jar --> <target name="interface-jar"> <jar jarfile="${build}/x3-ejb-shared.jar"> <fileset dir="${compiledWebClasses}"> <include name="**/ejb/session/*Local.class"/> <include name="**/ejb/domain/*.class"/> <!-- 实体类也需要被WAR访问 --> </fileset> </jar> </target> <!-- 修改ear任务,将共享Jar放入EAR的lib目录 --> <target name="ear" depends="interface-jar"> <jar destfile="${dist}/x3.ear"> <metainf dir="${descriptors}"> <include name="application.xml"/> <include name="jboss-app.xml"/> </metainf> <fileset file="${build}/x3.war"/> <fileset file="${build}/x3.jar"/> <!-- 将共享Jar放入EAR的lib目录,实现模块间类共享 --> <fileset file="${build}/x3-ejb-shared.jar" prefix="lib/"/> </jar> </target> <!-- 更新all任务,包含新的interface-jar步骤 --> <target name="all" depends="clean, createFolders, compile, jar, war, interface-jar, ear"> <echo message="done" /> </target>
3. 优化EJB注入的可靠性
你当前使用@EJB(mappedName="ManageStudentSessionBean/local")的方式没问题,但可以通过添加web.xml中的EJB引用声明,进一步明确EAR内部的模块关联,避免JNDI查找异常:
修改Servlet的注入注解:
@EJB(lookup="java:comp/env/ManageStudentSessionBean/local") private ManageStudentSessionBeanLocal manageStudentSessionBeanLocal;
在web.xml中添加EJB本地引用:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>x3</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 新增EJB本地引用,明确关联EAR内的EJB模块 --> <ejb-local-ref> <ejb-ref-name>ManageStudentSessionBean/local</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local>com.lmd.dev.ejb.session.ManageStudentSessionBeanLocal</local> <ejb-link>x3.jar#ManageStudentSessionBean</ejb-link> </ejb-local-ref> <!-- 原有Servlet配置 --> <servlet> <description></description> <display-name>ManageStudentServlet</display-name> <servlet-name>ManageStudentServlet</servlet-name> <servlet-class>com.lmd.dev.controller.ManageStudentServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ManageStudentServlet</servlet-name> <url-pattern>/ManageStudentServlet</url-pattern> </servlet-mapping> </web-app>
4. 保留正确的类加载器配置
你的jboss-app.xml已经配置了共享类加载器,这个设置能让EAR内的所有模块使用同一个类加载器,避免类隔离导致的接口无法访问问题,不需要修改:
<?xml version="1.0" encoding="ISO-8859-1" ?> <jboss-app> <loader-repository>dev.lmd.com:loader=x3.ear</loader-repository> </jboss-app>
验证步骤
- 执行
ant all重新构建项目 - 将生成的
x3.ear部署到JBoss5 - 查看JBoss启动日志,确认出现类似
Bound EJB 'ManageStudentSessionBean' to JNDI name 'ManageStudentSessionBean/local'的成功绑定日志 - 测试Servlet功能,确认Session Bean能正常注入并调用
内容的提问来源于stack exchange,提问作者Virendra Singh Rathore
相关产品推荐
相关产品推荐

