【问题标题】:Spring boot - External tomcat 7 error in JNDI configuration : JNDI name is not related to this contextSpring boot - JNDI 配置中的外部 tomcat 7 错误:JNDI 名称与此上下文无关
【发布时间】:2021-10-17 11:16:37
【问题描述】:

我需要认真的帮助!!我在同一个问题上被困了 10 天:/ !!

我有一个部署在 WAS 中的带有 java8 的 Web 应用程序,我正在将它迁移到 tomcat 7。

我在 spring boot 1.5.22 中集成了该应用程序,到目前为止它可以正常工作,但数据库连接仍然无法正常工作。我想使用 OJDBC6.jar 将它连接到 oracle 10g

在数据库配置类中我有这个代码:

import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class TDFAdminDBConnection
{
    protected String JNDILookup = "rnz_fta/jdbc/Datasource";
    
    protected DataSource ds = null;
    
    public TDFAdminDBConnection() {}
    
    public void freeConnection(Connection conn) throws SQLException
    {
        if(conn != null) conn.close();}
    
    public void connectToDataSource(String lookup) throws NamingException
    {
        try {
        InitialContext context = new InitialContext();
        this.ds = (DataSource)context.lookup(lookup);
        context.close();
    }catch(NamingException e) {
        System.out.println("connection failed ," + e.toString()); }}
    
    public Connection getConnection() throws SQLException
    {
        if(ds == null)
        {
            try {
                this.connectToDataSource(this.JNDILookup);
            }catch (NamingException e) {
                throw new SQLException(e.toString()); }}
        
        return this.ds.getConnection();
    }
    public Connection getConnection(String lookup) throws NamingException, SQLException
    {
        Connection connection = null;
        InitialContext context = new InitialContext();
        DataSource ds = (DataSource)context.lookup(lookup);
        connection = ds.getConnection();
        context.close();
        return connection;
    }   }

在应用程序的 web.xml 中我添加了这个:

<resource-ref>
         <description>Oracle Datasource</description>
         <res-ref-name>rnz_fta/jdbc/Datasource</res-ref-name>
         <res-type>javax.sql.DataSource</res-type>
         <res-auth>Container</res-auth>
      </resource-ref>

我在外部 Tomcat web.xml 中添加了相同的代码;

在 server.xml 我在下面添加了这个:

<Resource  auth="Container" global="rnz_fta/jdbc/Datasource" name="rnz_fta/jdbc/Datasource"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@xxx:1509:xxx"
              username="xxx" password="xxx" maxActive="20" maxIdle="10"
              maxWait="5000" />

我在 context.xml 中添加了这个:

<ResourceLink name="rnz_fta/jdbc/Datasource" auth="Container" global="rnz_fta/jdbc/Datasource" type="javax.sql.DataSource"   />

但我总是得到这个错误:

connection failed ,javax.naming.NameNotFoundException: Le Nom [rnz_fta/jdbc/Datasource] n'est pas lié à ce Contexte

JNDI 名称与此上下文无关 我按照官方 Tomcat 7.0.108 文档作为我使用的版本; 然后我像这样更改了数据库配置类:

import java.sql.Connection;
import java.sql.SQLException;
import oracle.jdbc.pool.OracleDataSource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

public class TDFAdminDBConnection
{
    protected String JNDILookup = "rnz_fta/jdbc/Datasource";
    private LogService log_dbg;
    protected DataSource ds = null;
    
    public TDFAdminDBConnection() {}
    
    public void freeConnection(Connection conn) throws SQLException
    {
        if(conn != null) conn.close();}
    
    public void connectToDataSource(String lookup) throws NamingException
    {
        try {
            Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            this.ds = (DataSource)envCtx.lookup(lookup);
        envCtx.close();
        }catch(NamingException e) {
            System.out.println("connection failed ," + e.toString());
        }
         log_dbg.debug("datasource =" + ds);}

    public Connection getConnection() throws SQLException
    {
        if(ds == null)
        {
            try {
                this.connectToDataSource(this.JNDILookup);
            }catch (NamingException e ) {
                throw new SQLException(e.toString());}}
         log_dbg.debug("datasource =" + ds);
           
        return this.ds.getConnection();}

    public Connection getConnection(String lookup) throws NamingException, SQLException
    {
        Connection connection = null;
        Context initCtx = new InitialContext();
        Context envCtx = (Context) initCtx.lookup("java:comp/env");
        DataSource ds = (DataSource)envCtx.lookup(lookup);
        connection = ds.getConnection(); 
        envCtx.close();
        log_dbg.debug("datasource =" + ds);
        log_dbg.debug("connection =" + connection);
        return connection;}}
    
But also didn't solve the problem !!

我在 /src/main/webapp/META-INF 的我的应用程序中创建了一个 context.xml 并添加了以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\tdfadmin-0.0.1-SNAPSHOT.war" path="" reloadable="true"  debug="1">
<Resource name="rnz_fta/jdbc/Datasource" auth="Container"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@xxx:1509:xxx"
              username="xxx" password="xxx" maxActive="20" maxIdle="10"
              maxWait="5000" removeAbandoned="true" removeAbandonedTimeout="30" logAbandoned="true"/>
<ResourceLink global="rnz_fta/jdbc/Datasource" name="rnz_fta/jdbc/Datasource" type="javax.sql.DataSource"/>
</Context>

also same error !!

i added ojdbc6.jar and tomcat-jdbc.jar in tomcat/lib and in vain!!

即使是 app.properties 中的 property spring.datasource.jndi-name 也没有解决问题:/

这是我的一些 maven 依赖项:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
<dependency>
            <groupId>oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.3</version>
        </dependency>

这是tomcat中控制台输出的最后一行:

connection failed ,javax.naming.NameNotFoundException: Le Nom [rnz_fta/jdbc/Datasource] n'est pas lié à ce Contexte
Sat Aug 14 17:44:38 CEST 2021
java.lang.NullPointerException
  at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Unknown Source)

这是 ControlerConnection 类:

import java.sql.Connection;
import java.sql.SQLException;


public class ControlerConnection {
    protected Connection connection;

    public TDFAdminDBConnection tdfDBConnection = null;
    
    public ControlerConnection() 
    {
        tdfDBConnection = new TDFAdminDBConnection();
    }
    
    public void freeConnection(Connection conn) throws SQLException
    {
        tdfDBConnection.freeConnection(conn);
    }

    public void getConnection() throws SQLException
    {
        this.connection = tdfDBConnection.getConnection();
//      connection.setAutoCommit(false);
    }
}

我真的很坑!!请问有人有同样的问题吗??????

【问题讨论】:

    标签: spring spring-boot tomcat datasource jndi


    【解决方案1】:

    最好关注JNDI naming convention

     Resource Manager     Connection Factory Type  JNDI Subcontext  
         JDBC™             javax.sql.DataSource    java:comp/env/jdbc
    

    所以在 java 上类似:

        Context envCtx = (Context) initCtx.lookup("java:comp/env");
        DataSource ds = (DataSource) envCtx.lookup("jdbc/rnzFtaDatasource");
    

    Resource global= 属性至少应以jdbc 开头。
    jdbc JDNI 或 Adding custom resource factories 上的 Tomcat 7 文档,如果您需要以 rnz_fta 开头的 JDNI 名称。

    【讨论】:

    • 非常感谢,它帮助了我很多,错误消失了:现在问题是我仍然得到 java.lang.NullPointerException 和“unknownHost”!我试图将连接变量放在记录器中,我发现它是空的!它没有任何价值!!我编辑了我的问题并在使用 DB 配置类的帖子中添加了 ControlerConnection 类!
    • 连接由读取配置的池类处理。 unknown host 听起来像是 DNS 问题,请仔细检查异常以查找更多信息或提高池包的调试级别。堆栈跟踪应该提供更多线索。另外,尝试使用newest jdbc driver possible
    • 我在以前的应用程序中使用了相同的数据库和相同的 ojdb6 jar,它们可以正常工作,但不同之处在于之前的应用程序是 springboot 2.5 和 app.properties 中的 db 配置,而不是 jndi .但是这个 App 是带有 jndi 配置的 springBoot 1.5.22!
    • 非常感谢,我会尝试验证配置中的 db url 并添加记录器
    【解决方案2】:

    解决了! 问题是我使用了错误版本的 ojdbc 驱动程序! ojdbc6-11.1.0.7.0.jar解决了问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-08
      • 1970-01-01
      • 1970-01-01
      • 2021-01-12
      • 2013-06-10
      • 2017-09-17
      相关资源
      最近更新 更多