【问题标题】:JEE6 : Alternative EJB declarationJEE6:替代 EJB 声明
【发布时间】:2013-01-04 10:57:35
【问题描述】:

我正在使用带有 CDI 的 JBoss 7.1.1。

我在 JNDI 中有一个名为 ServiceAccount 的无状态 bean。这是真正的服务实现。 我有另一个名为 ServiceAccountMock 的 Statelss bean,它是一个 Mock 服务。 两者都继承自同一个接口,并封装在一个 service.ear 中。

我想要做的是在 bean.xml 中声明模拟服务作为替代,重新​​部署我的服务耳,然后所有客户端都看到模拟版本(在客户端不更改任何内容)。

当我部署 service.ear 时,JBoss 说:

java.lang.IllegalArgumentException: JBAS011046: A component named 'ServiceAccount' is already defined in this module

这是真的,两个服务的声明方式相同 (@Stateless(name="ServiceAccount"))。

如果我更改模拟版本的名称,我必须在客户端更改使用哪个 EJB(我不想这样做)。

有人知道怎么做吗?

【问题讨论】:

  • 当您在 @Stateless 注释中为替代无状态 EJB 指定不同名称时,部署错误是否会消失?

标签: ejb-3.0 java-ee-6 jboss7.x cdi


【解决方案1】:

我认为您无法在同一个应用程序中部署 2 个具有相同名称的 bean。

如果bean的客户端只是本地的,你应该使用CDI类型注入选择。

  • 如果您确实需要一个名称,请删除 bean 的名称或使用不同的名称(模拟将具有与实际实现不同的名称)。
  • 在模拟上保留@Alternative 注释。
  • 在注入点,使用接口作为变量的类型(并且可能使用@Inject 注释而不是@EJB 可能会有所帮助)。

EJB 规范和 CDI 尚未完全一致。 EJB 有一些元素,例如名称,需要在应用程序中是唯一的,并且在 CDI 替代功能中没有考虑到。

所以我认为您不能混合使用 EJB 名称注入选择和 CDI 替代注入选择。

【讨论】:

  • 这也是我的结论。我实现的解决方法是拥有一个独特的 EJB 外观,其中注入了一个不同的 CDI 实现:对于客户端 EJB 始终相同,我可以透明地将调用路由到其他模拟 bean。
【解决方案2】:

首先你需要用@Alternative注释ServiceAccountMock,告诉容器如果没有指示不要使用它。

@Stateless(name="ServiceAccount")
@Alternative
public class ServiceAccountMock{
....
}

然后在beans.xml 中,您需要告诉 A/S 选择模拟实现:

...
<alternatives>
    <class>xx.yy.ServiceAccountMock</class>
</alternatives>
...

【讨论】:

  • @jmcollin92 在这种情况下,我认为一些代码应该会有所帮助。特别是 ServiceAccountServiceAccountMock 的类签名
  • 感谢您的回答。就像上面的 Kazaag,我认为这不太可能。 CDI 不处理 JNDI:@Alternative 不要修改 JNDI。我在上面发布了一个解决方法,供可能感兴趣的人使用。
猜你喜欢
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 2011-01-02
  • 2014-06-08
  • 2011-04-12
  • 1970-01-01
相关资源
最近更新 更多