【问题标题】:Spring Boot Datasource JNDI lookup on Websphere 9Websphere 9 上的 Spring Boot 数据源 JNDI 查找
【发布时间】:2021-05-10 07:53:14
【问题描述】:

我有一个通常部署在 Tomcat 服务器上的 Spring Boot 应用程序。现在我希望能够在 Websphere 9 上部署它,尽管它大部分时间仍会部署在通常的 Tomcat 服务器上。我将应用程序打包为一个战争,并通过管理界面将其部署在 Websphere 上,然后运行该应用程序。正如许多其他帖子所指出的那样,它不起作用,因为 JNDI 查找的工作方式不同。我尝试了这里和那里提供的解决方案,但没有任何效果。

我的数据源在 Websphere 中定义为 jdbc/foobar。我的查找是在我的 Spring Boot 应用程序中完成的:

JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource ds = dataSourceLookup.getDataSource("java:comp/env/jdbc/foobar");

这适用于 Tomcat,但不适用于 Websphere。关于此问题的其他 SO 帖子上的许多答案说,对于 Websphere,必须查找不带前缀的“jdbc/foobar”(例如答案的 cmets 中的 here),这是真的(我可以让它工作),但我希望代码与 Tomcat 上的常规部署保持兼容。

附带说明,getDataSource 方法会在前缀不存在时自动添加前缀,这意味着我需要改为这样做:

JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
dataSourceLookup.getJndiTemplate().getContext().lookup("jdbc/foobar");

这仍然很有用,因为它运行良好,证明我的问题不是服务器端的数据源定义错误。

由于我希望我的代码保持与 tomcat 兼容的相同代码,我保留了“java:comp/env/jdbc/foobar”查找并查看了建议添加一些配置的答案,最值得注意的是this one。我找到了 ibm-web-bnd.xml 文件,该文件由 Websphere 在部署时创建并放在 WEB-INF 文件夹中。我在那里添加了建议的resource-ref 标签:

<?xml version="1.0" encoding="UTF-8"?>
<web-bnd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://websphere.ibm.com/xml/ns/javaee"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd" version="1.0">
  <virtual-host name="default_host"/>
  <resource-ref name="jdbc/foobar" binding-name="jdbc/foobar" />
</web-bnd>

然后,由于我的战争中没有 web.xml,我尝试了@Resource 技巧:

@Component
@Resource(name = "jdbc/foobar",type = javax.sql.DataSource.class)
public class MyServlet extends HttpServlet {

我可以验证 servlet 是否已正确加载,但 Resource 注释似乎无法解决问题。然后我注意到 Websphere 在 ibm-web-bnd.xml 文件旁边也创建了一个 web.xml,所以我想我可以尝试一下,我在里面添加了 resource-ref 标签(其余的已经在这里,由Websphere):

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">

    <env-entry>
        <env-entry-name>logback/context-name</env-entry-name>
        <env-entry-type>java.lang.String</env-entry-type>
        <env-entry-value>main</env-entry-value>
    </env-entry>

    <listener>
        <listener-class>ch.qos.logback.classic.selector.servlet.ContextDetachingSCL</listener-class>
    </listener>

    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>

    <resource-ref>
        <description />
        <res-ref-name>jdbc/foobar</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>
</web-app>

这仍然不起作用。我还注意到 Websphere 创建了另一个名为 web_merged.xml 的文件,它似乎将自动创建的 web.xml 与真实的 web.xml 合并(在我的情况下不存在)。我也尝试将上面显示的相同代码添加到此文件中,但效果不佳。

现在,我不知道了。是否有人有其他想法,或者可能注意到我犯了一个明显的错误?

【问题讨论】:

    标签: java spring-boot websphere jndi


    【解决方案1】:

    假设您在指定绑定的同一个 Web 模块中执行查找(因为它是 java:comp 范围的),您在绑定文件中尝试的内容看起来应该可以工作。

    即便如此,您也应该能够以完全标准的方式完成此操作,而无需绑定文件(其中很难使所有语法正确),只需单独使用 @Resource 注释,

    @Resource(name = "java:comp/env/jdbc/foobar", lookup = "jdbc/foobar", type = javax.sql.DataSource.class)
    

    我建议摆脱您正在试验的额外绑定/部署描述符,并尝试仅使用注释,至少在开始时。如果事实证明您不在同一个模块中,您可以使用 java:app(如果在同一个应用程序中)或以其他方式使用 java:global 而不是 java:comp,您需要在这两个地方进行更新。

    【讨论】:

    • 感谢您的回答,我明天试试。
    猜你喜欢
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 2017-06-15
    • 1970-01-01
    • 2015-12-11
    • 1970-01-01
    相关资源
    最近更新 更多