【问题标题】:How to solve JNDI error while connecting mssql连接mssql时如何解决JNDI错误
【发布时间】:2019-06-16 19:32:12
【问题描述】:

我正在尝试使用 JNDI 方法连接我的 Microsoft sql 服务器。我的代码作为容器运行。详情如下

下面是我在 META-INF 下的 context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/CIBILDB"
          auth="Container"
          type="javax.sql.DataSource"
          validationQuery="SELECT 1"
          validationInterval="30000"
          maxActive="100"
          minIdle="10"
          maxWait="10000"
          initialSize="10"
          jmxEnabled="true"
          username="automationrobot"
          password="Soft2007"
          driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
          url="jdbc:sqlserver://TGSLAP-2154\\SQLEXPRESS:1433"/>
</Context>

下面是我的java代码

package com.CIBIL.dao;

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

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class InitialiseCIBILDBConnection {

	private static DataSource dataSource;
	private static final String  JNDI_LOOKUP_SERVICE = "java:/comp/env/jdbc/CIBILDB";
	static{
		try {
			Context context = new InitialContext();
			Object lookup = context.lookup(JNDI_LOOKUP_SERVICE);
			if(lookup != null){
				dataSource =(DataSource)lookup;
				
			}else{
				new RuntimeException("JNDI look up issue.");
			}
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}
	public static Connection getConnection(){
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
}

当我使用上面的代码时,我得到了错误

javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 您使用的是哪个服务器?某些服务器可能需要额外配置。
  • 我使用 MS Sql Server 2014 作为数据库服务器和 Apache Tomcat 作为 Web 服务器

标签: java jndi


【解决方案1】:

通过查看官方的 Tomcat documentation(参见标题为 JDBC 数据源的部分),您似乎还需要在 /WEB-INF/web.xml 文件中声明资源,如下所示:

<resource-ref>
  <description>
    Resource reference to a factory for java.sql.Connection
    instances that may be used for talking to a particular
    database that is configured in the <Context>
    configuration for the web application.
  </description>
  <res-ref-name>jdbc/CIBILDB</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

如果这不起作用,请尝试将初始上下文工厂设置为系统属性(取自this Stack Overflow 答案):

System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");

一些other Stack Overflow 的答案也建议在server.xml 中声明资源。我理解这一点的方式,这是可选的;这只是一种方便的方式来声明将由同一服务器上的多个 Web 应用程序使用的资源。

请记住,在静态初始化程序中获取初始上下文有些风险,尤其是当您需要设置上述Context.INITIAL_CONTEXT_FACTORY 系统属性时。您可以尝试将系统属性作为 JVM 参数(或类似参数)传递,但将这部分代码移动到“正常”(非静态)方法可能是个好主意。这样,您在调试时就少了一件需要担心的事情。

【讨论】:

  • 感谢您的回复,很抱歉回来晚了。除了 server.xml,我已经尝试了上述所有选项。现在我收到错误javax.naming.NameNotFoundException: Name [java:/comp/env/jdbc/CIBILDB] is not bound in this Context. Unable to find [java:].。我已将 JNDI_LOOKUP_SERVICE 值更改为 jdbc/CIBILDB 但仍然失败。它早些时候工作,但不确定它现在是如何失败的。请帮忙
  • 问题不在于 JNDI。实际上,如果我构建我的代码并转换为战争文件,那么它工作正常。因此,我相信我使用 JNDI 连接在调试模式下运行的方式是不正确的。你能帮我如何在春季开发的 Web 服务的调试模式下运行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 2018-01-28
  • 2021-01-23
相关资源
最近更新 更多