【问题标题】:javax.naming.NameNotFoundException: on WebSphere Libertyjavax.naming.NameNotFoundException:在 WebSphere Liberty 上
【发布时间】:2019-03-05 12:10:58
【问题描述】:

我正在尝试在 WebSphere Application Server Liberty 上使用配置为 JNDI 的数据源,但出现以下错误:

javax.naming.NameNotFoundException: java:comp/env/jdbc/myapp/master

Websphere 应用服务器中数据源的配置为:

<dataSource commitOrRollbackOnCleanup="commit" id="jdbc/myapp/master" jdbcDriverRef="ojdbc7" jndiName="jdbc/myapp/master">
        <properties.oracle URL="jdbc:oracle:thin:@127.0.0.1:1521:xe" oracleRACXARecoveryDelay="0" password="xxxxxxxx" user="app_master"> 
         </properties.oracle>
         <connectionManager maxPoolSize="50"/>
    </dataSource>

通过 servlet (jndi=jdbc/myapp/master) 中的此代码建立与数据库的连接:

Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            DataSource ds = (DataSource) envCtx.lookup(jndi);
            setConnection(ds.getConnection());
            System.out.println(getConnection().toString() );    

我做错了什么?

【问题讨论】:

    标签: java datasource jndi websphere-liberty


    【解决方案1】:

    java:comp/env 需要资源引用。您有以下选择来解决这个问题:

    1) 使用资源注入 - 所以不要直接查找它(通过 InitialContext),只需在您的 servlet 类中添加以下内容

    @Resource(lookup = "jdbc/myapp/master", name="jdbc/myapp/master")
    private DataSource dataSource;
    

    2) 在web.xml 中定义资源引用

    <resource-ref>
       <description>my datasource</description>
       <res-ref-name>jdbc/myapp/master</res-ref-name>
       <res-type>javax.sql.DataSource</res-type>
       <res-auth>CONTAINER</res-auth>
    </resource-ref>
    

    或者您也可以通过代码中的注释来创建引用。

    3) 使用直接 JNDI,无需参考(不是 Java EE 最佳实践)

     DataSource ds = (DataSource) initCtx.lookup("jdbc/myapp/master");
    

    【讨论】:

    • 我正在使用第三个选项,它似乎不起作用。奇怪的是它已与远程服务器一起使用,并且在更改为本地服务器后知道我遇到了麻烦。与同一数据库的 JDBC 连接按预期工作。
    • @SocketM 您没有使用第三个选项,因为您的 initCtx 上面有前缀 initCtx.lookup("java:comp/env");。因此,在您最初的问题中,您实际上是在查找java:comp/env/jdbc/myapp/master。相反,您只想查找 jdbc/myapp/master(即删除 java:comp/env 前缀)
    • @Gas 你能告诉我为什么不推荐选项3吗?
    • @SocketM 间接 JNDI 查找(资源引用)的优点是它使您的应用程序更易于维护,因为您无需在应用程序中硬编码 jndi 名称。如果资源的实际 JNDI 名称发生更改,则无需对您的应用程序进行更改。您可以在配置中更改绑定。如果是 Liberty &lt;application-bnd&gt;&lt;resource-ref name="jdbc/mydb" binding-name="jdbc/proddb" /&gt;&lt;/application-bnd&gt;。但它在 tWAS 中比 Liberty 更重要。所以也许我会将“不推荐”更改为“不是最佳实践”:-)
    【解决方案2】:

    除了其他答案中已经说明的内容外,您还应该检查是否启用了 jndi-1.0 功能。这是查找在 Liberty 中不起作用的常见原因。

    例如在server.xml中,

    <featureManager>
      <feature>jdbc-4.2</feature>
      <feature>jndi-1.0</feature>
      ... other features that you use
    </featureManager>
    

    如果这也不足以使其正常工作,您还应该检查 dataSource 所依赖的资源的配置,例如在您的配置 sn-p 中引用的 id 为 ojdbc7 的 jdbcDriver提供。

    【讨论】:

    • jndi 功能已启用。 jdbcDriver 配置为与 ojdbc7 一起运行。感谢您的输入。
    • 谢谢,这对我有帮助。伙计,不得不查找如此简单的解决方案总是让我觉得内心有点愚蠢......
    猜你喜欢
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多