哪个 JNDI 数据源名称同时适用于 Wildfly 和 Websphere?

Which JNDI datasource name works both on Wildfly and Websphere?

我有一个 java/spring 网络应用程序需要在 Wildfly 和 Websphere 上部署为 war 文件

该应用正在使用具有 JNDI 名称的数据源:

WebConfig.java 包含:


    public DataSource dataSource() {
        final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
        dsLookup.setResourceRef(true);
        DataSource dataSource = dsLookup.getDataSource("jdbc/myDS");

        return dataSource;
    }

... 和 运行 在 JNDI 数据源名称为 jdbc/myDS.

的 Websphere 上完美

Wildfly JNDI 名称必须以 'java:/' 或 'java:jboss/'

开头

更改 WebConfig.java 即可:

DataSource dataSource = dsLookup.getDataSource("java:/myDS");

哪个 JNDI 数据源名称同时适用于 Wildfly 和 Websphere(可能还适用于其他应用程序服务器?)

如果您使用资源引用进行查找,它们将相对于 Liberty 和 Wildfly 中的 java:comp/env。

有两种定义数据源的方法。一种是使用 javax.annotation.Resource 注释。这可以用于类型、方法或字段定义。

您也可以在 web.xml 或 ejb-jar.xml 中使用 resource-ref 元素执行此操作:

<resource-ref>
    <description />

    <res-ref-name>myRef</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

如果您在应用程序代码中提供 userid/password,则 res-auth 元素应包含 Application

我遇到了同样的情况(尽管我有一个 ejb-jar.xml)。
在 WebSphere 上,我们被要求让 DataSource 在部署时手动绑定到正确的 JNDI 名称,所以为了让它工作,我声明 resource-ref 是这样的:

[ ... ]

<session>
    <ejb-name>MyEjb</ejb-name>

    <resource-ref>
        <description>DataSource</description>
        <res-ref-name>java:comp/env/jdbc/myDatasource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
    </resource-ref>

    [ other stuff... ]
</session>

[ ... ]

在代码中,我会像这样进行查找:

(DataSource) InitialContext.doLookup("java:comp/env/jdbc/myDatasource");

现在,我的老板希望我能够在 WildFly 上部署相同的应用程序,其中 DataSource 的 JNDI 名称始终是 java:/myDatasource,并且它必须在不在代码中添加检查的情况下工作使用另一个查找字符串(因此,使用我上面写的同一行)。
几个小时后,我有了一个可行的解决方案。 我在 ejb 的 META-INF 文件夹中添加了一个 jboss-ejb3.xml 文件,我在其中覆盖了 resource-ref ,如下所示:

[ ... ]

<session>
    <ejb-name>MyEjb</ejb-name>

    <resource-env-ref>
        <description>DataSource</description>
        <resource-env-ref-name>jdbc/myDatasource</resource-env-ref-name>
        <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
        <lookup-name>java:/myDatasource</lookup-name><!-- JNDI name of the DataSource -->
    </resource-env-ref>
</session>

[ ... ]

由于 jboss-ejb3.xml 文件被 WebSphere 忽略,应用程序可以部署在两个 Web 服务器上。
请注意我必须如何将节点定义为 resource-env-ref。原因(据我了解)是在 java:comp/env "node" 中找不到名称以 "java:" 开头的资源引用(不是资源环境引用)。因此,我必须将 DataSource 的引用配置为资源环境引用。 lookup-name 节点将其映射到正确的 JNDI 名称。这样就可以通过使用相同的字符串 "java:comp/env/jdbc/myDatasource" 进行查找来找到它。

Here's the documentation about the jboss-ejb3.xml file.

需要注意的一件事:在对 ejb-jar.xml 进行这些更改后部署我的应用程序时,我遇到了可能是 WildFly 中的错误添加 jboss-ejb3.xml 文件。以前版本的应用程序已经部署,当我替换它时,部署失败并出现此错误:

java.lang.IllegalArgumentException: WFLYEE0047: Incompatible conflicting binding at java:jboss/exported/MyApp/my-ejb/MyEjb!com.example.MyEjbRemote source: org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor@65f33ac5

停止 WildFly,清除 "tmp" 文件夹并重新启动它允许我的应用程序部署。