【问题标题】:Why does WebSphere create duplicate EJB environment entries?为什么 WebSphere 创建重复的 EJB 环境条目?
【发布时间】:2015-09-04 06:15:24
【问题描述】:

我在带有@Resource 注释的EJB 中指定了一个字符串资源。 EJB 封装在一个 EJB 模块中。 ejb.jar 有一个 ejb-jar.xml,它指定了 String 资源的默认值。 ejb.jar 与 web 模块一起打包在一个 ear 存档中。

当 ear 部署到 WebSphere 时,EJB 模块的环境条目部分显示 三个 EJB 条目:

  1. 我为 ejb 模块映射的字符串资源;
  2. 我为ejb模块映射的String资源,只是这次叫EJB_fully_qualified_name/resource_name;
  3. 资源的完全限定名称相同,但现在映射到 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>

【问题讨论】:

  • 请添加您的 EJB 片段和资源,以及定义资源的 ejb-jar.xml 片段。可能资源引用名称不同,这就是您看到的原因 2. 关于 web 模块 - 检查您的 ejb.jar 是否也没有错误地添加到 WEB-INF/lib,它应该只在耳朵级别添加。
  • Web 模块的 WEB-INF/lib 中确实有 ejb 模块 - 我在新构建中删除了它,但 WebSphere 仍然显示 Web 模块的 ejb 条目。至于映射,我以here 的身份完成了它。
  • 也许你没有重新部署?将名称添加到 ejb-jar.xml 中的 @Resource(name="myRef") and also use same myRef` 名称。如果您提供代码片段,而不是指向第三方页面,会容易得多。
  • @Gas 添加了示例。我不仅重新部署而且重新安装了整个应用程序。
  • 我看到特蕾西已经为你解释过了。

标签: ejb websphere


【解决方案1】:

您定义了 2 个完全不同的资源;都可以查到。

根据 Java EE 规范,当您不使用 @Resource 注释的“名称”属性时,系统会为您提供默认名称,即存在注释的全限定类名,后跟 JavaBeans 属性名称(基本上是字段的名称,或者删除了“set”并且下一个字符为小写的方法的名称)。 @Resource 注释的 javadoc 有点误导,因为它只是说默认是字段名称;但没有明确说明字段名称是什么;它实际上是类名后跟字段名,就像您打印出代表它的java.lang.reflect.Field 时看到的一样。

在组合注解和 XML 时,XML 仅在“名称”匹配时才会覆盖注解。在提供的示例中,名称不匹配,因此您实际上有 2 个不同的资源。

如果您希望 XML 中的 &lt;env-entry&gt; 覆盖 @Resource 注释,以便您可以注入一个值,那么您需要将您的注释更改为如下所示:

@Resource(name="serviceLookup")

或将&lt;env-entry-name&gt; 更改为完全限定的类名/serviceLookup。

此外,当 EJB 模块包含在 WAR 模块中时,事情会变得有点复杂。不是“名称”方面,而是您可以提供价值的地方。除了在ejb-jar.xml 中提供值之外,WebSphere 还允许您在ibm-ejb-jar-bnd.xml 中提供值。但是,当 EJB 模块位于 WAR 中时,它也可以在 ibm-web-bnd.xml... 中提供,因为所有 EJB 的所有资源都在整个 WAR 模块的 java:comp/env 名称空间中可见。因此,在示例中,由于默认设置,您将获得两个不同的名称,并且看起来是两个额外的副本,实际上只是提供了两个副本,以防您想要覆盖 ibm-web-bnd.xml 中的值。

【讨论】:

    【解决方案2】:

    我认为您在这里看到的是不同的 JNDI 命名空间:

    https://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html

    可以使用原始名称从 EJB 模块内访问资源值,但如果需要从同一应用程序内的另一个模块访问它,则应提供由模块名称限定的 JNDI 路径,以确保唯一性(和可追溯性)等其他应用程序和全局命名空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-19
      • 2020-01-27
      • 1970-01-01
      • 1970-01-01
      • 2023-02-02
      相关资源
      最近更新 更多