EJB注入异常:JNDI查找失败,寻求技术排查帮助
排查Java EE Stateful EJB JNDI查找失败问题
我来帮你一步步梳理这个JNDI查找的问题,这种购物车会话存储的场景在Java EE商城里很常见,咱们从最可能的原因开始排查:
1. 先确认JNDI名称的正确性
错误提示里的NameNotFoundException: Shop是关键——说明你用的全局JNDI名称里的<app-name>部分不对。Java EE全局JNDI的标准格式是:
java:global/<app-name>/<module-name>/<bean-name>!<全限定接口名>
这里几个核心点要核对:
<app-name>:只有当你的项目是EAR打包(把Shop-ejb和Shop-war打包成一个EAR应用)时才需要这个部分。如果是单独部署EJB和WAR模块,这个部分要去掉,格式变成java:global/<module-name>/<bean-name>!<全限定接口名>。<module-name>:你的EJB模块是Shop-ejb,但要确认GlassFish部署后的实际模块名——可以看GlassFish控制台的部署日志,或者登录GlassFish管理后台(默认http://localhost:4848),在Applications里找到你的EJB模块,查看它的JNDI名称列表,直接抄正确的名称用就不会错。- 全限定接口名:
cart.CartLocal要确认接口确实在cart包下,大小写、包名拼写都不能错。
2. 检查EJB的注解配置
- 确认
CartBean上的@Stateful注解是javax.ejb.Stateful,有没有导错包? - 给
CartLocal接口显式加上@Local注解(javax.ejb.Local),虽然Java EE 6+支持隐式本地接口,但显式标注能避免歧义,尤其是当Bean实现多个接口时。 - 如果你的
Shop-ejb模块有ejb-jar.xml配置文件,检查里面有没有错误的JNDI绑定,别覆盖了注解的配置。
3. 核对WAR与EJB的依赖关系
- 如果是EAR结构:确认
application.xml里正确包含了两个模块,示例如下:<application> <module> <ejb>Shop-ejb.jar</ejb> </module> <module> <web> <web-uri>Shop-war.war</web-uri> <context-root>/Shop-war</context-root> </web> </module> </application> - 如果是分开部署:在NetBeans里右键
Shop-war→ Properties → Libraries → Add Project,选择Shop-ejb添加依赖,确保GlassFish能识别两个模块的关联。
4. 简化EJB获取方式(推荐用注入)
手动JNDI查找容易出错,推荐直接用Java EE的注入方式获取EJB,容器会自动处理会话关联:
@WebServlet("/Servlet") public class CartServlet extends HttpServlet { // 直接注入Stateful EJB @EJB private CartLocal cart; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 将cart存入HttpSession request.getSession().setAttribute("cart", cart); // 后续业务逻辑... } }
如果一定要用JNDI查找,把之前的名称替换成GlassFish日志里显示的正确全局名称即可。
5. 查看GlassFish部署日志
在NetBeans的GlassFish控制台里,找部署Shop-ejb时的日志,会有类似这样的输出:
Info: Portable JNDI names for EJB CartBean: [java:global/Shop-ejb/CartBean!cart.CartLocal, java:global/Shop-ejb/CartBean]
直接用日志里给出的名称,就能避免拼写错误。
内容的提问来源于stack exchange,提问作者Mr. Kevin
相关产品推荐
相关产品推荐

