如何在分散在整个.ear文件中的一个镜头中覆盖许多EJB引用?

时间:2013-07-26 18:19:50

标签: ejb java-ee-6

我有一个.ear文件,里面有几十个EJB jar文件。

每个EJB jar文件中都包含数十个EJB。

每个EJB都有@EJB个引用,没有其他信息(没有name属性等)。

目前一切正常工作:恰好,对于任何给定的@EJB - 注释注入目标,只有一个具体的EJB存在于.ear文件中以填充插槽。 / p>

我出于各种原因需要引入一些包含EJB的EJB jar文件,这些文件可以填充其中一些插槽。

因此,我需要告诉我的Java EE容器哪个EJB注入哪个存在冲突的插槽。

我熟悉ejb-jar.xml deployment descriptor mechanism for overriding EJB references,但如果这是我唯一的办法,我正在考虑改变这些条目。

我在application.xml schema version 6注意到那里也支持<ejb-local-ref>元素,这是我想要的抽象方式。但我无法弄清楚如何利用这些元素来做我想做的事。

在一些抽象的完美世界中,我想以某种方式在一个地方说“嘿,Java EE容器,当你看到一个@EJB - 注释字段时这样:

@EJB
SomeType bean;

...请将beanNamefred的EJB注入其中。在这个应用程序的任何地方。“我该怎么做?

2 个答案:

答案 0 :(得分:4)

没有标准的方法可以做到这一点,据我所知,没有通用的特定于供应商的方法。

这是我试图在EJB 3.1中为EJB和JPA引用的内容:如果注入点使用默认规则,因为只有一个SomeType bean,但是某天某一秒{{1} } bean被添加......直言不讳,你被软管:) SomeType@PersistenceContext refs也存在这个问题。这个想法是/有一些“这是标准部署描述符中的@PersistenceUnit选项的默认impl,并在这些情况下保释人员。

我们仍应将此纳入规范。如果这是你的问题,我会重新发布该提议,如果你能跟进关于这对你来说有多少噩梦的信息,我几乎可以保证我们将为EJB.next修复这个问题。

获取规范xml

目前,一种可能的方法是使用标志SomeType在TomEE中临时部署此耳朵。 TomEE / OpenEJB实际上将为您的应用程序提供所有有效的部署描述符。如果您的应用程序与您声明的一样大,可以为您节省几个小时或几天。在内部我们1)读入部署描述符,2)使用注释来“填写”部署描述符。结果是我们有一个树,它是每个EJB模块的规范“元数据”集。设置openejb.descriptors.output=true标志后,我们会将每个ejb-jar.xml文件写入磁盘并记录该位置。

掌握了ejb-jar.xml文件后,您可以随意修改并返回GlassFish,也许还有更好的运气。

覆盖:控制引用计数

就如何在Java EE中实际管理它而言,您必须了解如何成功覆盖引用。在注释引用如何转换为xml时,需要了解一些关键信息。目标是有1个参考而不是N.

当您的引用未命名时:

openejb.descriptors.output=true

...有一个固定的规则,默认名称必须是package org.some.awesome.code; public class Foo { @EJB SomeType orange; 。类名和包成为名称的一部分,以便在覆盖时为您提供最精细的控制。以下xml将覆盖此引用:

org.some.awesome.code.Foo/orange

此引用现在将链接到类型<ejb-local-ref> <ejb-ref-name>org.some.awesome.code.Foo/orange</ejb-ref-name> <local>org.some.awesome.code.SomeType</local> <ejb-link>Fred</ejb-link> </ejb-local-ref> 的EJB,其beanName为'Fred'。

这样做的缺点是,如果您有100个像这样的引用并且想要全部更改它们,则需要100个xml声明来执行此操作。

没有办法摆脱这个不涉及更改代码的问题 - 这就是我的“使用它作为默认”提案有价值的地方,它允许一个xml更改来处理所有100个没有代码更改的情况。这很简单,因为能够说“当我在我的代码中不具体时,我的意思是通过部署描述符使用X”。

也许只使用类型在xml中声明覆盖是合法的,如下所示:

SomeType

如上所述,目前这不合法。

更改代码

有一些代码更改方法可用,但其中一种方法是为每个<ejb-local-ref> <local>org.some.awesome.code.SomeType</local> <ejb-link>Fred</ejb-link> </ejb-local-ref> 引用相同的名称。那么你最终只会得到1个参考而不是N.

@EJB

这里明确给出了引用的名称,所以在xml中覆盖它可以更简单地完成如下:

package org.some.awesome.code;

public class Foo {

    @EJB(name "purple")
    SomeType orange;

如果有100个<ejb-local-ref> <ejb-ref-name>purple</ejb-ref-name> <local>org.some.awesome.code.SomeType</local> <ejb-link>Fred</ejb-link> </ejb-local-ref> 引用,则所有这些引用都会被上述声明覆盖。

结论

简短回答,目前还没有简单的方法。您正在寻找广泛的xml或广泛的代码更改。

从长远来看,我们可以有希望改进规范的这一部分,以便人们在超出默认匹配规则时不会受到惩罚。

答案 1 :(得分:0)

我目前正在解决同样的问题。我正在研究覆盖JNDI上下文的可能性,因此它提供了除标准实例之外的其他实例。您只需将系统属性 java.naming.factory.initial (例如,在jndi.properties中)设置为您的实现,并将实现放在根类路径上。然后在工厂中,您可以使用重写的查找方法创建自己的上下文版本。听起来很简单,但我好好想好几天。