【发布时间】: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