Spring项目报错Exception in thread main java.lang.NullPointerException Cannot invoke com.study.spring.ioc

文章讲述了在Springboot项目中,因JDK版本升级导致的@Resource注解失效问题,提供了手动导入javax.annotation包和迁移到jakarta.annotation的解决方案,以及SpringBoot6.0及以上版本的处理方式。

Spring项目报错Exception in thread main java.lang.NullPointerException Cannot invoke com.study.spring.ioc.bean.zhuangpei.zhujie.service.UserService.save() because this.userService is null

1.先来展示一下我的报错

Exception in thread “main” java.lang.NullPointerException: Cannot invoke “com.study.spring.ioc.bean.zhuangpei.zhujie.service.UserService.save()” because “this.userService” is null

image-20231209205021951

2.说下问题

我把我的代码检查了一下午,代码逻辑肯定是没有问题的,那哪里出现了问题呢?

在这里,主要感谢一下高老师,帮我解决问题,并给我提供了一个非常好的思路
👍👍👍👍👍👍👍👍👍👍👍👍

3.原因分析

因为JDK版本升级的改动,在Jdk9~17环境下,搭建Springboot项目,会出现原有@Resource(javax.annotation.Resource)不存在的问题,导致项目从Jdk8迁移到高版本时遇到的问题

image-20231209210501157

你可能会问,为什么javax.annotation.Resource注解不存在呢?

从Jdk9开始,JavaEE从Jdk中分离,jdk就移除掉了javax.annotation.jar包的默认集成,从而导致版本不兼容。所以一旦spring项目从JDK8升到高版本,都会出现javax.annotation.Resource无法引用报红。

java EE 即 java Enterprise Edition,企业级应用,目标是制定一系列企业级应用的标准服务。常见的 javax.servlet, javax.annotation。

Oracle 收购了创造 java 的 SUN 公司,Oracle 又不想发展 java EE 了,就把 java EE 交给 Eclipse 社区了,但是又因为不知名的原因,禁止社区使用 javax 这个名字。所以,javax.servlet 就变成了 jakarta.servlet, jakarta.annotation。api无法向前兼容。

java ee 的最后一个版本也是 8,以后就再也没有 java ee 的新版本。

4.解决方案

(1)Jdk9以上、Springboot3/Spring6.0以前版本的问题

解决方案:

1、手动导入javax.annotation包

<!--引入@Resource注解的包-->
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

2、降到Jdk8,你发任你发,我用Java8

(2)Springboot3/Spring6.0以上版本的问题

从Java EE APIs 到 Jakarta EE

Spring Boot 3开始,所有的Java EE Api都需要迁移到Jakarta EE上来。

大部分用户需要修改import相关API的时候,要用jakarta替换javax。比如:原来引入javax.servlet.Filter的地方,需要替换为jakarta.servlet.Filter

但是当Spring版本升级到6.0以上的版本,即使手动引入javax.annotation包,但是还是会有问题,你会发现类无法注入,导致引用的类is Null,报空指针。

因为Spring也放弃了javax.annotation.Resource注解的支持,而是对jakarta.annotation.Resource注解的支持
通过跟代码进去,发现@Resouce的源代码是 jakarta.annotation下的

package jakarta.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Resources.class)
public @interface Resource {
    String name() default "";
String lookup() default "";
 
Class<?> type() default Object.class;
 
Resource.AuthenticationType authenticationType() default Resource.AuthenticationType.CONTAINER;
 
boolean shareable() default true;
 
String mappedName() default "";
 
String description() default "";
 
public static enum AuthenticationType {
    CONTAINER,
    APPLICATION;
 
    private AuthenticationType() {
    }
}
}

所以,解决方法是引用jakarta包来解决问题,导入到maven的配置文件中pom.xml

<dependency>
    <groupId>jakarta.annotation</groupId>
    <artifactId>jakarta.annotation-api</artifactId>
    <version>2.1.1</version>
</dependency>

(我解决时,用的2.1.1版本的包,10.1.7版本的包不知道为什么导入不成功,不过无伤大雅)

image-20231209211609543

导入成功后

应通过import引入

import jakarta.annotation.Resource;

image-20231209211704099

这样就运行成功了

image-20231209211837279

解决思路来源:敬爱的高老师

博客参考:http://t.csdnimg.cn/tj3rO

<think>嗯,用户遇到了Java中的FileInputStream对象为空导致的NullPointerException问题。我需要先理清楚这两个异常之间的关系和产生原因。 首先,NullPointerException通常发生在试图调用一个空对象的方法或访问其属性时。而FileNotFoundException则是在文件路径不存在或不可访问时由FileInputStream的构造函数抛出的。用户可能在创建FileInputStream实例时,文件路径不正确,导致对象未被正确初始化,从而在后续使用时出现NullPointerException。 接下来,我要检查用户可能的代码结构。例如,用户可能在声明FileInputStream变量后,没有正确初始化它,或者在try块外部使用了这个变量。例如,如果文件路径错误,FileInputStream的构造函数抛出异常,而用户可能在异常处理中没有妥善处理,导致fin变量仍为null,随后在读取时抛出NullPointerException。 然后,解决方案需要分步骤。第一步是确保文件路径正确,检查绝对路径和相对路径是否正确。第二步是在创建FileInputStream对象时进行空值检查,确保对象被正确初始化。第三步是正确使用try-catch块来捕获可能的FileNotFoundException,并在处理异常后避免继续使用未初始化的流对象。此外,使用try-with-resources语句可以自动管理资源,避免资源泄漏,同时减少空指针的可能性。 还需要考虑异常处理的范围。如果FileInputStream在try块外声明,但在try块内初始化,当初始化失败时,变量可能仍为null,导致后续代码中的空指针。因此,应该将流的初始化和使用放在同一个try块内,或者在使用前检查是否为null。 最后,用户可能需要查看具体的代码示例来理解如何正确实现这些步骤。提供示例代码可以帮助用户对照自己的代码,找出问题所在。同时,提醒用户注意文件权限问题,确保程序有权限访问目标文件,这也是导致FileNotFoundException的常见原因。</think>以下是解决Java中$FileInputStream$对象为空导致的$NullPointerException$问题的分步方案: ### 一、问题诊断 1. **对象未初始化**:当$FileInputStream$对象$fin$为null时调用$read()$方法,会触发$NullPointerException$ 2. **文件路径错误**:如果传递给$FileInputStream$构造函数的文件路径不存在,会抛出$FileNotFoundException$[^1],此时$fin$仍为null 3. **异常处理缺陷**:在未正确处理$FileNotFoundException$的情况下继续使用$fin$ ### 二、解决方案 #### 1. 基础检查(代码示例) ```java try { File file = new File("test.txt"); if (!file.exists()) { System.out.println("文件不存在"); return; } FileInputStream fin = new FileInputStream(file); // 正确初始化 // 后续操作... } catch (FileNotFoundException e) { e.printStackTrace(); } ``` #### 2. 异常处理最佳实践 - 使用try-with-resources自动关闭流 - 分开处理不同异常类型 ```java try (FileInputStream fin = new FileInputStream("data.bin")) { // Java7+特性 int data; while ((data = fin.read()) != -1) { // 处理数据 } } catch (FileNotFoundException e) { System.err.println("错误:文件未找到 - " + e.getMessage()); } catch (IOException e) { System.err.println("IO异常: " + e.getMessage()); } ``` #### 3. 空指针防御编程 ```java public void readFile(String path) { FileInputStream fin = null; try { fin = new FileInputStream(path); // 使用前显式检查 if (fin != null) { int byteData; while ((byteData = fin.read()) != -1) { System.out.print((char) byteData); } } } catch (FileNotFoundException e) { System.out.println("文件路径错误: " + path); } catch (IOException e) { e.printStackTrace(); } finally { if (fin != null) { try { fin.close(); } catch (IOException e) { /* 日志记录 */ } } } } ``` ### 三、关键注意点 1. **路径验证**:使用$File.exists()$预检查文件存在性 2. **资源管理**:始终在finally块或使用try-with-resources关闭流 3. **异常传播**:根据业务需求选择捕获异常或声明throws[^2] 4. **日志记录**:建议使用日志框架记录异常堆栈信息 ### 四、进阶建议 1. 使用NIO的$Files$类进行现代文件操作 2. 配置合适的文件权限(Linux系统注意SELinux策略) 3. 使用相对路径时确认工作目录:`System.getProperty("user.dir")`
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值