当使用ClassLoader.getSystemClassLoader().getResourceAsStream(“db.properties“);报空指针异常

错误重现

当我们在项目中自定义JdbcUtils时

public class JdbcUtils {

private static DataSource dataSource = null;

static{
    try {
        Properties properties = new Properties();
        System.out.println(properties);
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
        properties.load(is);
        dataSource = DruidDataSourceFactory.createDataSource(properties);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {

    }

    public static void close(Connection conn){
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

或者使用德鲁伊连接池时

    private static DataSource source;
    static {
        try {
            Properties pros=new Properties();
            InputStream in=ClassLoader.getSystemClassLoader().getResourceAsStream("db.properties");
            pros.load(in);
            source= DruidDataSourceFactory.createDataSource(pros);
        }

自定义的ClassLoader.getSystemClassLoader().getResourceAsStream(“db.properties”);这个方法在不涉及 Tomcat 服务器时,在本地测试没有问题,可以连接数据库,但启动 Tomcat测试就报错。

报错异常:

java.lang.NullPointerException
	at java.util.Properties$LineReader.readLine(Properties.java:434)
	at java.util.Properties.load0(Properties.java:353)
	at java.util.Properties.load(Properties.java:341)
	at com.atguigu.utils.JdbcUtils.<clinit>(JdbcUtils.java:24)

发现在获取properties文件处也就是下方代码处出现空指针异常

InputStream in=ClassLoader.getSystemClassLoader().getResourceAsStream("db.properties");

有两种解决方法:

第一种方法:使用自定义类的加载器替换系统类加载器,即把上方代码替换成

InputStream is = 
JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");

第二种方法:更改掉加载配置文件的方式
将此处的 jdbc.properties 文件放置在 idea 的 module 一级目录下,然后在上述代码处使用如下代码代替:

FileInputStream is = 
	new FileInputStream(new File("jdbc.properties"));

即可

原因

ClassLoader.getSystemResourceAsStream使用系统类加载(ClassLoader.getSystemClassLoader)来搜索资源。
this.getClass().getClassLoader().getResourceAsStream()
使用为“this”对象加载类的相同ClassLoader。该 ClassLoader 可能是系统 ClassLoader的子级,因此可以访问系统 ClassLoader 没有的资源。但由于它是 System ClassLoader的子类,它也会请求其父级(System)帮助它查找资源。因此,使用此方法将允许您在该 ClassLoader 和 SystemClassLoader 中找到内容。 搜索顺序在 ClassLoader.getResource 的 javadoc中定义(首先是父级,然后是子级)。
例如,假设您正在从 Servlet 运行一些代码。SystemClassLoader 包含您在启动 Web Server 时放入 CLASSPATH 中的任何内容,但 servlet 类可能由服务器为处理 WebApp 的WEB-INF/lib 和 WEB-INF/classes 目录而创建的另一个ClassLoader 加载。使用该 WebApp的ClassLoader 可以访问这些目录中的内容,但不会在 CLASSPATH 中 ,因此 System ClassLoader不知道它们。

因此,如果您想从静态方法中获取属性,最好使用:SomeClass.class.getClassLoader().getResourceAsStream(“XX.properties”));

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值