工厂方法“dataSource”抛出 NullPointerException

Posted

技术标签:

【中文标题】工厂方法“dataSource”抛出 NullPointerException【英文标题】:Factory method 'dataSource' threw NullPointerException 【发布时间】:2021-11-02 22:08:35 【问题描述】:

下面有关于这个问题的类似问题,但那里提供的解决方案对我没有帮助: Factory method 'dataSource' threw exception while startup 问题是我尝试使用 CRUD 操作创建简单的 Websocket 应用程序。在成功构建后运行应用程序时,我收到了堆栈跟踪中显示的消息:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/home/admin1/.m2/repository/org/springframework/spring-core/5.0.8.RELEASE/spring-core-5.0.8.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2021-09-05 15:31:51.296 ERROR 14659 --- [ost-startStop-1] o.s.b.web.embedded.tomcat.TomcatStarter  : Error starting Tomcat context. Exception:
Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/example/websocket/configuration/DbConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NullPointerException

Process finished with exit code 0

它检测到 DbConfig 类中的问题,该类抛出 NullPointerException。下面是 DbConfig.java 类:

package com.example.websocket.configuration;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;

@RequiredArgsConstructor
@Configuration
public class DbConfig 

    private final Environment env = null;

    @Bean
    public DataSource dataSource() 
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();
        assert false;
        dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("spring.datasource.url"));
        dataSource.setUsername(env.getProperty("spring.datasource.username"));
        dataSource.setPassword(env.getProperty("spring.datasource.password"));
        return dataSource;
    

根据前面提到的问题,我还检查了 pom.xml 依赖项和 application.properties 中的设置

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ch.simas.examples</groupId>
    <artifactId>websocket</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>2.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>2.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.0.4.RELEASE</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>2.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.7</version>
        </dependency>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.25.0-GA</version>
        </dependency>
        <dependency>
            <groupId>org.xerial</groupId>
            <artifactId>sqlite-jdbc</artifactId>
            <version>3.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.properties

server.port=8965
logging.level.root=INFO
spring.jpa.database-platform=com.example.websocket.configuration.SQLiteDialect
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:sqlite:database.db
spring.datasource.driver-class-name=org.sqlite.JDBC
spring.datasource.username=**
spring.datasource.password=**
spring.jpa.show-sql=true

主应用程序类如下所示:

package com.example.websocket;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.socket.config.annotation.EnableWebSocket;

@EnableWebSocket
@SpringBootApplication
public class WebsocketApp

    public static void main(String[] args) 
        SpringApplication.run(WebsocketApp.class, args);
    

如果可能,请指出我在哪里做错了。 更新 我已经更改了 DbConfig 类 - 删除了 assert=false 并添加了 @Autowired private final Environment env ; 。 NullPointerException 消失但出现 BeanCreation 异常:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]:Receiver class org.sqlite.Conn does not define or inherit an implementation of the resolved method 'abstract boolean isValid(int)' of interface java.sql.Connection.

【问题讨论】:

【参考方案1】:

您的env 对象是null

private final Environment env = null;

所以在第 21 行调用时

env.getProperty("spring.datasource.driver-class-name")

你会得到NullPointerException

您应该在DbConfig 类中注入(@AutowiredEnvironment(并删除final 修饰符):

@RequiredArgsConstructor
@Configuration
public class DbConfig 

    @Autowired
    private Environment env;

    @Bean
    public DataSource dataSource() 
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("spring.datasource.url"));
        dataSource.setUsername(env.getProperty("spring.datasource.username"));
        dataSource.setPassword(env.getProperty("spring.datasource.password"));
        return dataSource;
    

我还删除了assert false; 行,它有什么意义?它会抛出一个AssertionError 异常并破坏你的程序!

更新

对于错误:

Receiver class org.sqlite.Conn does not define or inherit an implementation of the resolved method 'abstract boolean isValid(int)' of interface java.sql.Connection.

您必须更新您的 SQLite 驱动程序,您在 pom.xml 中使用的版本3.7.2ancient!它可以追溯到 2010 年!

<dependency>
    <groupId>org.xerial</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>3.7.2</version>
</dependency>

使用最新版本,例如

<version>3.36.0.3</version>

【讨论】:

感谢您的回复,NullPointerException 消失了,现在被列为以前的问题,“BeanCreationException”引用到主类“WebsocketApp”。它说“接收器类 org.sqlite.Conn 没有定义或继承实现接口java.sql.Connection的解析方法'abstract boolean isValid(int)'。"【参考方案2】:

您不需要DbConfig。只需放下它并仅使用application.properties。 Spring Boot 会根据这些属性自动配置数据源。

【讨论】:

以上是关于工厂方法“dataSource”抛出 NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章

为啥我收到错误工厂方法'halLinkDisocoverer'在springboot中抛出异常?

Kurento媒体服务器抛出“处理方法时出现意外错误:未找到工厂'PlayerEndPoint''”

为啥设置 DataSource 时 ComboBox 不抛出异常?

创建在类路径资源[applicationcontext]中定义名为“工厂”的bean时出错。:在设置bean属性“dataSource”时,无法解析对bean“dataSource”的引用;嵌套异常是

Failed to configure a DataSource

服务器:[http-nio-8080-exec-7] org.apache.coyote.http11.Http11Processor.service 处理请求时出错 java.lang.NullPo