我在EJB中使用@Resource
注释指定了一个String资源。 EJB封装在EJB模块中。 ejb.jar有一个ejb-jar.xml,它指定String资源的默认值。 ejb.jar与web模块一起打包在ear存档中。
当将ear部署到WebSphere时,EJB模块的 Environment条目部分显示三个 EJB条目:
EJB_fully_qualified_name/resource_name
; 除非我为上述所有变体提供默认值,否则不会注入资源。如果我将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>
答案 0 :(得分:2)
您已经定义了2个完全不同的资源;要么被抬起头来。
根据Java EE规范,当您不使用@Resource
注释的“name”属性时,会为您提供一个默认名称,即存在注释的完全限定类名,后跟JavaBeans属性名称(基本上是字段的名称,或者删除了'set'的方法的名称,以及小写的下一个字符)。 @Resource
注释的javadoc有点误导,因为它只是说默认是字段名称;但没有明确说明字段名称是什么;它实际上是类名后跟字段名称,就像你打印出代表它的java.lang.reflect.Field
一样。
当组合注释和XML时,XML仅在“name”匹配时覆盖注释。在提供的示例中,名称不匹配,因此您实际上有2个不同的资源。
如果您希望XML中的<env-entry>
覆盖@Resource
注释,以便您可以注入值,那么您需要更改注释,如下所示:
@Resource(name="serviceLookup")
或者将<env-entry-name>
更改为完全限定的类名/ serviceLookup。
此外,当EJB模块包含在WAR模块中时,事情会变得复杂一些。不是“名称”方面,而是您可以提供价值的地方。除了在ejb-jar.xml
中提供值之外,WebSphere还允许您在ibm-ejb-jar-bnd.xml
中提供值。但是,当EJB模块在WAR中时,它也可能在ibm-web-bnd.xml
中提供...因为所有EJB的所有资源都在java:comp/env
名称空间中可见WAR模块。因此,在示例中,由于默认值,您将获得两个不同的名称,并且看起来是另外两个副本,这些副本实际上只是在您要覆盖ibm-web-bnd.xml
中的值时提供。
答案 1 :(得分:0)
我认为您在这里看到的是不同的JNDI名称空间:
https://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html
可以使用原始名称从EJB模块中访问资源值,但是如果需要从同一应用程序中的另一个模块访问它,则应该提供由模块名称限定的JNDI路径,以确保唯一性(其他应用程序和全局命名空间等等。可追溯性)。