gpt4 book ai didi

jsf - 从独立部署的 war 中访问 jar 中的 EJB3 bean(未打包在 ear 中)

转载 作者:行者123 更新时间:2023-12-04 12:34:55 25 4
gpt4 key购买 nike

由于某些原因,我想将我的应用程序部署为两个独立的工件:用户-ejb.jar 用户-war.war , 不同包装耳朵 (但仍然部署在同一个 JBoss AS 7.1 实例中)。在 用户-war.war 我有一个支持 bean(注释为 JSF 托管 bean),我希望在其中注入(inject)一个封装在 中的 EJB3。用户-ejb.jar .简单的 @EJB 当所有东西都打包在一个 中时,注入(inject)有效耳朵 时不再工作用户-ejb.jar 用户-war.war 分别部署。

我的设置的一个缩小的简化示例如下:

EJB3 bean

import javax.ejb.*;

(...)

@Stateless(name="userFacade")
@Local(IUserFacadeLocal.class)
@Remote(IUserFacadeRemote.class)
public class UserFacade extends AbstractFacade<User> implements IUserFacadeLocal, IUserFacadeRemote {

背 bean
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.ejb.EJB;

import entities.User;
import facades.IUserFacadeRemote;
import facades.IUserFacadeLocal;

@ManagedBean(name="indexBackingBean")
@SessionScoped
public class IndexBackingBean implements Serializable {

@EJB(beanName="userFacade")
private IUserFacadeLocal userFacade;

我尝试了各种组合,例如将支持 bean 中的 EJB3 bean 的类型声明为 IUserFacadeRemote(而不是 IUserFacadeLocal),但是当 出现相同的异常时,它们都失败了。用户-war.war 模块已部署:
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException:
JBAS014543: No EJB found with interface of type 'facades.IUserFacadeLocal' and
name 'userFacade' for binding controllers.IndexBackingBean/userFacade

用户-ejb.jar 部署到 JBoss AS 7.1 没有任何提示,但是当 用户-war.war 部署后,JBoss 提示它找不到他应该注入(inject)的 bean。

但是,我可以使用 JNDI 获取对 EJB3 bean 的引用:
String jndiName = "java:global/Users-ejb/userFacade!facades.IUserFacadeRemote";
this.userFacade = (IUserFacadeRemote) new InitialContext().lookup(jndiName);

尽管如此,@EJB 注入(inject)似乎不起作用。

更新:
我按照 Tom Anderson 下面给出的建议并且有效的注入(inject)是:
@EJB(mappedName = "java:global/Users-ejb/userFacade!facades.IUserFacadeRemote")

如果我理解正确,它使用供应商特定的 mappedName 属性。我无法让注入(inject)以独立于供应商的方式工作。

最佳答案

我希望我对 EE 规范的这个领域有足够的了解,可以给你一个明确的答案,但我没有。

JBoss EJB documentation有话要说:

  • The @EJB annotation also has a mappedName() attribute. The specification leaves this a vendor specific metadata, but JBoss recognizes mappedName() as the global JNDI name of the EJB you are referencing. If you have specified a mappedName(), then all other attributes are ignored and this global JNDI name is used for binding.
  • If you specify @EJB with no attributes defined [...] Then the following rules apply:
    • The EJB jar of the referencing bean is searched for an EJB with the interface, used in for @EJB injection. If there are more than one EJB that publishes same business interface, then an exception is thrown. If there is only one bean with that interface then that one is used.
    • Search the EAR for EJBs that publish that interface. If there are duplicates, then an exception is thrown. Otherwise the matching bean is returned.
    • Search globally in JBoss for an EJB of that interface. Again, if duplicates, an exception is thrown.
  • @EJB.beanName() corresponds to . If the beanName() is defined, then use the same algorithm as @EJB with no attributes defined except use the beanName() as a key in the search. An exception to this rule is if you use the ejb-link '#' syntax. The '#' syntax allows you to put a relative path to a jar in the EAR where the EJB you are referencing lives. See spec for more details


“在 JBoss 中全局搜索该接口(interface)的 EJB”当然表明您编写的注入(inject)应该可以工作。事实上,它应该在没有 beanName 的情况下工作.但是,我怀疑从 WAR 中的组件的角度来看,EJB-JAR 中的组件是远程的,因此您将需要使用远程接口(interface)。

所以,我要尝试的第一件事是:
@EJB
private IUserFacadeRemote userFacade;

没有 beanName ,以防出现问题。不过,听起来你已经尝试过了。

如果正常的注入(inject)方法不起作用,我可能会转而尝试通过 mappedName 进行注入(inject)。 ,在 JBoss 中是一个全局 JNDI 名称。所以:
@EJB(mappedName = "java:global/Users-ejb/userFacade!facades.IUserFacadeRemote")
private IUserFacadeRemote userFacade;

这显然是相当丑陋的。

无论如何,祝你好运!

编辑 :您可以尝试的其他方法是使用合格的亲属 beanName明确命名 EJB-JAR:
@EJB(beanName = "Users-ejb.jar#userFacade")
private IUserFacadeRemote userFacade;

由于 WAR 和 EJB-JAR 未打包在 EAR 中,因此可能需要:
@EJB(beanName = "../Users-ejb.jar#userFacade")
private IUserFacadeRemote userFacade;

但到目前为止,我只是猜测。

编辑反击 : 我们可能忽略了一些非常简单的事情。 lookup @EJB 的属性注释允许您指定“包含目标 EJB 组件的 JNDI 名称的可移植查找字符串”,因此:
@EJB(lookup = "java:global/Users-ejb/userFacade!facades.IUserFacadeRemote")
private IUserFacadeRemote userFacade;

可能会奏效。这本质上是 JBoss 特定使用 mappedName 的可移植版本。 .

关于jsf - 从独立部署的 war 中访问 jar 中的 EJB3 bean(未打包在 ear 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11934057/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com