HCRM博客

JNDI报错该如何解决?

JNDI报错详解及解决方案

一、JNDI

Java Naming and Directory Interface(JNDI)是Java EE标准之一,用于为Java应用程序提供命名和目录功能,它提供了一种统一的接口,允许应用程序与各种命名和目录服务进行交互,通过JNDI,开发人员可以使用不同的访问协议(如LDAP、RMI、CORBA等)来查找并操作资源对象。

JNDI报错该如何解决?-图1
(图片来源网络,侵权删除)

二、常见JNDI报错及解决方案

1. javax.naming.NameNotFoundException: Name jdbc is not bound in this Context

报错信息:

javax.naming.NameNotFoundException: Name jdbc is not bound in this Context

原因分析:

这个错误通常表明在当前的上下文环境中找不到名为jdbc的数据源,这可能是因为数据源未正确配置或绑定到当前上下文。

解决方案:

检查配置文件: 确保在Tomcat的server.XML或项目的context.xml中正确配置了数据源。

JNDI报错该如何解决?-图2
(图片来源网络,侵权删除)
  <Context>
    <Resource name="jdbc/myDataSource" auth="Container" type="javax.sql.DataSource"
        maxTotal="20" maxIdle="10" maxWaitMillis="1"
        username="root" password="password" driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://localhost:3306/mydatabase"/>
  </Context>

确保web.xml配置正确: 在项目的web.xml中添加以下配置:

  <resourceref>
    <description>My JDBC Data Source</description>
    <resrefname>jdbc/myDataSource</resrefname>
    <restype>javax.sql.DataSource</restype>
    <resauth>Container</resauth>
  </resourceref>

重新部署项目: 确保所有更改已生效,并且项目已重新部署。

2. org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'

报错信息:

org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'

原因分析:

此错误通常是由于缺少JDBC驱动程序或驱动类名拼写错误导致的,还可能是由于数据源配置错误。

JNDI报错该如何解决?-图3
(图片来源网络,侵权删除)

解决方案:

添加JDBC驱动程序: 确保将相应的JDBC驱动程序jar文件添加到Tomcat的lib目录中,对于MySQL数据库,需要添加mysqlconnectorjava.jar

检查驱动类名: 确保驱动类名正确无误,对于MySQL,驱动类名应为com.mysql.cj.jdbc.Driver

验证数据源配置: 确保在context.xmlserver.xml中的配置信息正确无误。

  <Resource name="jdbc/myDataSource" auth="Container" type="javax.sql.DataSource">
    <ResourceParams name="factory" value="org.apache.tomcat.jdbc.pool.DataSourceFactory"/>
    <ResourceParams name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <ResourceParams name="url" value="jdbc:mysql://localhost:3306/mydatabase"/>
    <ResourceParams name="username" value="root"/>
    <ResourceParams name="password" value="password"/>
    <ResourceParams name="maxActive" value="20"/>
    <ResourceParams name="maxIdle" value="10"/>
    <ResourceParams name="maxWaitMillis" value="1"/>
  </Resource>

3. java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory

报错信息:

java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory

原因分析:

此错误通常是由于缺少必要的依赖库或类路径未正确设置导致的。

解决方案:

添加依赖库: 确保项目中包含所需的依赖库,对于Maven项目,可以在pom.xml中添加以下依赖:

  <dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcatdbcp</artifactId>
    <version>8.5.4</version>
    <scope>provided</scope>
  </dependency>

检查类路径: 确保所有必要的类路径已正确添加到项目中,如果使用IDE,请确保构建路径中包含相关库。

三、FAQs

Q1: 如何在开发环境中解决Main方法无法注入JNDI的问题?

A1: 在开发环境中,可以通过配置Spring Boot的applicationdev.yml文件来解决Main方法无法注入JNDI的问题,具体步骤如下:

1、创建applicationdev.yml文件并添加以下内容:

   jndi:
     dev:
       driverclassname: com.mysql.jdbc.Driver
       url: jdbc:mysql://192.168.xxx.xxx:3306/test
       username: root
       password: root

2、创建一个配置类JndiDevConfig

   @Profile("dev")
   public class JndiDevConfig {
       @Value("${spring.datasource.jndiname}")
       private String jndiName;
       @Value("${jndi.dev.driverclassname}")
       private String driverClassName;
       @Value("${jndi.dev.url}")
       private String url;
       @Value("${jndi.dev.username}")
       private String username;
       @Value("${jndi.dev.password}")
       private String password;
       @Bean
       public ServletWebServerFactory servletContainer() {
           TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
               @Override
               protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
                   tomcat.enableNaming();
                   return super.getTomcatWebServer(tomcat);
               }
               @Override
               protected void postProcessContext(Context context) {
                   ContextResource resource = new ContextResource();
                   resource.setName(jndiName);
                   resource.setType(DataSource.class.getName());
                   resource.setProperty("driverClassName", driverClassName);
                   resource.setProperty("url", url);
                   resource.setProperty("username", username);
                   resource.setProperty("password", password);
                   context.getNamingResources().addResource(resource);
                   super.postProcessContext(context);
               }
           };
           return tomcat;
       }
   }

3、确保在开发环境中启用该配置。

Q2: 如何在高版本的JDK中绕过JNDI远程加载限制?

A2: 在JDK的高版本中,默认禁用了远程加载,可以通过设置系统属性来绕过这一限制,具体步骤如下:

1、设置系统属性com.sun.jndi.rmi.object.trustURLCodebasetrue

   Dcom.sun.jndi.rmi.object.trustURLCodebase=true

2、如果使用的是Spring Boot项目,可以在application.propertiesapplication.yml中添加以下配置:

   spring.jndi.rmi.object.trustURLCodebase=true

3、确保所有配置已生效,并重新运行应用程序。

通过以上详细的分析和解决方案,希望能够帮助你更好地理解和解决JNDI相关的报错问题,如果有任何进一步的问题,欢迎随时提问。

分享:
扫描分享到社交APP
上一篇
下一篇