为什么 WebSphere 创建重复的 EJB 环境条目?
Why does WebSphere create duplicate EJB environment entries?
我使用 @Resource
注释在 EJB 中指定了一个字符串资源。 EJB 打包在 EJB 模块中。 ejb.jar 有一个 ejb-jar.xml 指定字符串资源的默认值。 ejb.jar 与 Web 模块一起打包在 ear 存档中。
当 ear 部署到 WebSphere 时,EJB 模块的环境条目部分显示 三个 个 EJB 条目:
- 我为ejb模块映射的字符串资源;
- 我为ejb模块映射的String资源,只是这次调用了
EJB_fully_qualified_name/resource_name
;
- 相同的资源完全限定名称,但现在映射到 Web 模块。
除非我为上面的所有变体提供默认值,否则不会注入资源。如果我将 ejb-jar.xml 添加到 Web 模块,WebSphere 会显示 四个 条目(每个模块一个资源的简单名称和一个完全限定名称)。这是 WebSphere 的怪癖还是我做错了什么?我在集群环境中使用 WebSphere 8.5.5.3。
这是豆子:
@Singleton
@Startup
public class ConfigSingleton {
@Resource
private String serviceLookup;
}
这里是ejb-jar.xml:
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>ConfigSingleton</ejb-name>
<env-entry>
<env-entry-name>serviceLookup</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>value</env-entry-value>
</env-entry>
</session>
</enterprise-beans>
</ejb-jar>
我认为您在这里看到的是不同的 JNDI 命名空间:
https://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html
资源值可以从EJB模块内部使用原来的名称访问,但是如果需要从同一个应用程序中的另一个模块访问它,应该给出一个由模块名称限定的JNDI路径,以确保唯一性(和可追溯性),以及其他应用程序和全局命名空间等。
您定义了2个完全不同的资源;两者都可以查到。
根据 Java EE 规范,当您不使用 @Resource
注释的 'name' 属性时,系统会为您提供一个默认名称,即完全限定 class 注释存在的名称后跟 JavaBeans 属性 名称(基本上是字段的名称,或者删除了 'set' 的方法的名称和下一个小写字符)。 @Resource
注释的 javadoc 有点误导,因为它只是说默认是字段名;但没有明确说明字段名称是什么;它实际上是 class 名称后跟字段名称,就像您打印出代表它的 java.lang.reflect.Field
时看到的那样。
当组合注释和 XML 时,XML 仅在 'name' 匹配时覆盖注释。在提供的示例中,名称不匹配,因此您实际上有 2 个不同的资源。
如果您希望 XML 中的 <env-entry>
覆盖 @Resource
注释,以便您可以注入一个值,那么您要么需要将注释更改为如下所示:
@Resource(name="serviceLookup")
或将 <env-entry-name>
更改为完全限定的 class 名称/serviceLookup。
此外,当 EJB 模块包含在 WAR 模块中时,事情会变得有点复杂。不是 'name' 方面,而是您可以提供价值的地方。除了在 ejb-jar.xml
中提供值外,WebSphere 还允许您在 ibm-ejb-jar-bnd.xml
中提供值。但是,当 EJB 模块位于 WAR 中时,它也可能在 ibm-web-bnd.xml
中提供...因为所有 EJB 的所有资源都在 java:comp/env
名称中可见space 用于整个 WAR 模块。因此,在示例中,由于默认值,您将获得两个不同的名称,并且看起来是两个额外的副本,实际上只是为了防止您想要覆盖 ibm-web-bnd.xml
.
中的值而提供的
我使用 @Resource
注释在 EJB 中指定了一个字符串资源。 EJB 打包在 EJB 模块中。 ejb.jar 有一个 ejb-jar.xml 指定字符串资源的默认值。 ejb.jar 与 Web 模块一起打包在 ear 存档中。
当 ear 部署到 WebSphere 时,EJB 模块的环境条目部分显示 三个 个 EJB 条目:
- 我为ejb模块映射的字符串资源;
- 我为ejb模块映射的String资源,只是这次调用了
EJB_fully_qualified_name/resource_name
; - 相同的资源完全限定名称,但现在映射到 Web 模块。
除非我为上面的所有变体提供默认值,否则不会注入资源。如果我将 ejb-jar.xml 添加到 Web 模块,WebSphere 会显示 四个 条目(每个模块一个资源的简单名称和一个完全限定名称)。这是 WebSphere 的怪癖还是我做错了什么?我在集群环境中使用 WebSphere 8.5.5.3。
这是豆子:
@Singleton
@Startup
public class ConfigSingleton {
@Resource
private String serviceLookup;
}
这里是ejb-jar.xml:
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>ConfigSingleton</ejb-name>
<env-entry>
<env-entry-name>serviceLookup</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>value</env-entry-value>
</env-entry>
</session>
</enterprise-beans>
</ejb-jar>
我认为您在这里看到的是不同的 JNDI 命名空间:
https://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html
资源值可以从EJB模块内部使用原来的名称访问,但是如果需要从同一个应用程序中的另一个模块访问它,应该给出一个由模块名称限定的JNDI路径,以确保唯一性(和可追溯性),以及其他应用程序和全局命名空间等。
您定义了2个完全不同的资源;两者都可以查到。
根据 Java EE 规范,当您不使用 @Resource
注释的 'name' 属性时,系统会为您提供一个默认名称,即完全限定 class 注释存在的名称后跟 JavaBeans 属性 名称(基本上是字段的名称,或者删除了 'set' 的方法的名称和下一个小写字符)。 @Resource
注释的 javadoc 有点误导,因为它只是说默认是字段名;但没有明确说明字段名称是什么;它实际上是 class 名称后跟字段名称,就像您打印出代表它的 java.lang.reflect.Field
时看到的那样。
当组合注释和 XML 时,XML 仅在 'name' 匹配时覆盖注释。在提供的示例中,名称不匹配,因此您实际上有 2 个不同的资源。
如果您希望 XML 中的 <env-entry>
覆盖 @Resource
注释,以便您可以注入一个值,那么您要么需要将注释更改为如下所示:
@Resource(name="serviceLookup")
或将 <env-entry-name>
更改为完全限定的 class 名称/serviceLookup。
此外,当 EJB 模块包含在 WAR 模块中时,事情会变得有点复杂。不是 'name' 方面,而是您可以提供价值的地方。除了在 ejb-jar.xml
中提供值外,WebSphere 还允许您在 ibm-ejb-jar-bnd.xml
中提供值。但是,当 EJB 模块位于 WAR 中时,它也可能在 ibm-web-bnd.xml
中提供...因为所有 EJB 的所有资源都在 java:comp/env
名称中可见space 用于整个 WAR 模块。因此,在示例中,由于默认值,您将获得两个不同的名称,并且看起来是两个额外的副本,实际上只是为了防止您想要覆盖 ibm-web-bnd.xml
.