有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

WebSphere9上的JavaSpring启动数据源JNDI查找

我有一个Spring引导应用程序,通常部署在Tomcat服务器上。现在,我希望能够在websphere9上部署它,尽管大多数时候它仍将部署在普通的Tomcat服务器上。我将该应用程序打包为war,并通过管理界面将其部署到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”(例如答案注释中的here),这是正确的(我可以让它工作),但我希望代码与tomcat上的常规部署保持兼容

作为旁注,getDataSource方法会自动添加前缀(如果没有),这意味着我需要这样做:

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

这仍然很有用,因为它工作得很好,它证明了我的问题不是服务器端错误的数据源定义

因为我希望我的代码保持与tomcat兼容的代码不变,所以我保留了“java:comp/env/jdbc/foobar”查找,并查看了建议添加一些配置的答案,最明显的是this one。我找到了IBMWebBND。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>

然后,因为我没有网络。xml在我的战争中,我尝试了@Resource技巧:

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

我可以验证servlet是否正确加载,但资源注释似乎没有起到作用。然后我注意到一张网。xml也是由Websphere在IBMWebBND旁边创建的。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与真实的xml(在我的例子中不存在)。我也尝试将上面显示的代码添加到此文件中,但效果并不好

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


共 (1) 个答案

  1. # 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,这两个模块都需要更新