将JDK17转换为JDK1.8
- java: 警告: 源发行版 17 需要目标发行版 17
- 原因
- 解决思路
- 安装jdk
- 修改项目设置中编译器jdk版本
- 修改pom文件
- 报错类文件具有错误的版本 61.0 应为 52.0
- 程序包jakarta.annotation不存在
- 程序包jakarta.servlet.http不存在
- 不兼容的类型: javax.servlet.http.HttpServletRequest无法转换为jakarta.servlet.http.HttpServletRequest
- 程序包jakarta.validation不存在
- 程序包jakarta.activation不存在
- Patterns in 'instanceof' are not supported at language level '8'
java: 警告: 源发行版 17 需要目标发行版 17
原因
项目中的JDK与本地实际安装的JDK版本不匹配。
解决思路
安装jdk
在本地安装新的与之相匹配的JDK版本即可,即安装Java17,不过该方法不推荐。安装路径:https://www.oracle.com/java/technologies/downloads/#java17。
修改项目设置中编译器jdk版本
将 Settings --> Build, Execution, Deployment --> Complier --> Java Complier 配置下的 Project bytecode version 改为与项目使用的JDK版本一样即可。
因为我本地使用的是JDK1.8,所以应该选择Java8,并在每个项目模块右侧将17改为8:
不过,我使用这种方法没用,依旧报错:java: 警告: 源发行版 17 需要目标发行版 17。
修改pom文件
找到项目中的父项目的pom.xml
文件,查看其编写的Java版本:
<properties><java.version>17</java.version></properties>
将Java版本修改为本地安装的1.8版本即可:
<properties><java.version>1.8</java.version></properties>
修改之后刷新Maven即可运行。如果依旧不可以,依旧JDK17错误,则再在该pom.xml
中添加以下代码:
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.12.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin></plugins></build>
<!-- 或者添加如下,都差不多,就是有些参数加了有些参数没加,可以选择性添加 --><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.12.1</version><configuration><compilerArgs><arg>-parameters</arg></compilerArgs><source>1.8</source><target>1.8</target></configuration></plugin></build>
报错类文件具有错误的版本 61.0 应为 52.0
java: 无法访问org.springframework.data.redis.core.RedisTemplate错误的类文件: /C:/Users/EDY/.m2/repository/org/springframework/data/spring-data-redis/3.2.1/spring-data-redis-3.2.1.jar!/org/springframework/data/redis/core/RedisTemplate.class类文件具有错误的版本 61.0, 应为 52.0请删除该文件或确保该文件位于正确的类路径子目录中。
报错之后跳转的位置在import org.springframework.data.redis.core.RedisTemplate;
,找到该依赖包,如下:
查询到:该版本3.2.1
偏大,该Spring Boot
版本好最少要使用JDK17
,而我的是JDK8
,对应版本如下:
所以应该调小版本,我这3.2.1
版本描述的pom.xml
如下:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.1</version></parent><properties><java.version>1.8</java.version><spring-boot.version>3.2.1</spring-boot.version><spring-framework.version>6.1.2</spring-framework.version><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><includeSystemScope>true</includeSystemScope></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>
将版本改为2.5.2
后重新运行解决了该问题,代码如下:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.2</version></parent><properties><java.version>1.8</java.version><spring-boot.version>2.5.2</spring-boot.version><spring-framework.version>6.1.2</spring-framework.version><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties>
但是又出现了新的相同问题:
java: 无法访问org.springframework.stereotype.Component错误的类文件: /C:/Users/EDY/.m2/repository/org/mybatis/mybatis-spring/3.0.3/mybatis-spring-3.0.3.jar!/org/mybatis/spring/annotation/MapperScan.class类文件具有错误的版本 61.0, 应为 52.0请删除该文件或确保该文件位于正确的类路径子目录中。
查看有关mybatis的依赖如下:
<dependency><groupId>com.fhs-opensource</groupId><artifactId>easy-trans-mybatis-plus-extend</artifactId><version>3.0.0</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version></dependency>
需修改其版本号,依赖注入代码如下:
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.7</version></dependency>
该问题解决,但又出现了新的相同问题:
java: 无法访问org.springframework.stereotype.Component错误的类文件: /C:/Users/EDY/.m2/repository/org/springframework/spring-context/6.1.2/spring-context-6.1.2.jar!/org/springframework/stereotype/Component.class类文件具有错误的版本 61.0, 应为 52.0请删除该文件或确保该文件位于正确的类路径子目录中。
查找版本号为6.1.2
的pom.xml
文件如下:
<properties><java.version>1.8</java.version><spring-boot.version>2.5.2</spring-boot.version><spring-framework.version>6.1.2</spring-framework.version><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties>
因为<spring-framework.version>6.1.2</spring-framework.version>
,spring-context依赖版本是6.1.2,这是属于Spring Framework 6.x的版本,而Spring Framework 6.x需要Java 17或更高版本。由于我使用的是Java 8,应当降级spring-context及其相关依赖到与Java 8兼容的版本。Spring Boot 2.5.x通常与Spring Framework 5.x系列兼容,因此应当将相关依赖调整至5.x系列, 更改<spring-framework.version>为5.x的版本,同时检查并更新所有依赖以确保它们与Java 8和Spring Boot 2.5.2兼容:
<spring-framework.version>5.3.23</spring-framework.version>
解决该问题,但是又报了新的错,如下:java: 程序包jakarta.annotation不存在。
程序包jakarta.annotation不存在
这个错误信息表明项目在编译时找不到jakarta.annotation
包,这通常是由于依赖管理不正确导致的。这是因为项目中使用了Java EE(Java Enterprise Edition)的注解,但项目中没有包含相应的Java EE库。
在Java EE 8
以及更早的版本中,注解位于javax.annotation
包中,而在Java EE 9
及更高的版本中,这个注解被移动到jakarta.annotation
包中,如果项目是Java EE 9
及更高的版本并且正在使用jakarta.annotation
包中的注解,那么需要确保项目中包含Jakarta EE
库,如果项目是Java EE 8
以及更早的版本则确保包含Java EE
库。
例如,原本使用了Java 17
环境运行该项目,注入了如下依赖引入Jakarta EE
库:
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.3.0</version></dependency>
由Knife4j文档可知Spring Boot3使用OpenAPI3规范,Spring Boot2可以使用OpenAPI2和OpenAPI3规范相关扩展信息。
或者也可以引入如下依赖引入Jakarta EE
库:
<dependency><groupId>jakarta.platform</groupId><artifactId>jakarta.jakartaee-api</artifactId><version>9.1.0</version></dependency>
在JDK 1.8环境中使用knife4j-openapi3-jakarta-spring-boot-starter时,报错提示java: 程序包jakarta.annotation不存在,这可能是由于Jakarta命名空间的引入与JDK版本之间的适配问题。jakarta.annotation包是从Java EE迁移到Jakarta EE时改名而来的(原先为javax.annotation),而JDK 1.8原生支持的是Java EE标准,并非直接支持Jakarta EE标准。这边尝试先按提示之际导入jakarta.annotation-api依赖,解决该问题提示:
<dependency><groupId>jakarta.annotation</groupId><artifactId>jakarta.annotation-api</artifactId><version>2.1.1</version></dependency>
解决该问题,之后又报错提示:java: 程序包jakarta.servlet.http不存在。
程序包jakarta.servlet.http不存在
如果使用Jakarta Servlet API时遇到该问题,可能是没有引入该Servlet API依赖或者使用的该依赖版本过低:
<dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>5.0.0</version></dependency>
如果引入jakarta.servlet-api依赖后仍未解决该问题,可以尝试将版本升高。引入该依赖后运行如下报:不兼容的类型: javax.servlet.http.HttpServletRequest无法转换为jakarta.servlet.http.HttpServletRequest。
不兼容的类型: javax.servlet.http.HttpServletRequest无法转换为jakarta.servlet.http.HttpServletRequest
// 在我的代码中其他import jakarta.servlet...的代码没报错,只有这一块代码报错
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
public class CommonServletUtil {public static HttpServletRequest getRequest() {ServletRequestAttributes servletRequestAttributes;try {servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();} catch (Exception e) {log.error(">>> 非Web上下文无法获取Request:", e);throw new CommonException("非Web上下文无法获取Request");}if (servletRequestAttributes == null) {throw new CommonException("非Web上下文无法获取Request");} else {return servletRequestAttributes.getRequest(); // 报错位置,不兼容的类型}}public static HttpServletResponse getResponse() {ServletRequestAttributes servletRequestAttributes;try {servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();} catch (Exception e) {log.error(">>> 非Web上下文无法获取Response:", e);throw new CommonException("非Web上下文无法获取Response");}if (servletRequestAttributes == null) {throw new CommonException("非Web上下文无法获取Response");} else {return servletRequestAttributes.getResponse(); // 报错位置,不兼容的类型}}
}
因为项目中同时存在Java EE的javax.servlet包和Jakarta EE的jakarta.servlet包的引用,导致类型不匹配。servletRequestAttributes.getRequest()方法报错,这很可能是因为Spring框架在处理请求时,默认返回的是javax.servlet.http.HttpServletRequest类型的对象,与现在使用的Jakarta不兼容。
将servletRequestAttributes.getRequest()与servletRequestAttributes.getResponse()单独提取出来并Alt+Enter得到完整类型:
javax.servlet.http.HttpServletRequest request = servletRequestAttributes.getRequest();javax.servlet.http.HttpServletResponse response = servletRequestAttributes.getResponse();
这个时候需要强转类型,将
javax.servlet.http.x
转换为jakarta.servlet.http.x
,如下:
return (HttpServletRequest) servletRequestAttributes.getRequest();return (HttpServletResponse) servletRequestAttributes.getResponse();
程序包jakarta.validation不存在
引入依赖如下:
<dependency><groupId>jakarta.validation</groupId><artifactId>jakarta.validation-api</artifactId><version>3.0.2</version></dependency>
程序包jakarta.activation不存在
引入依赖如下:
<dependency><groupId>jakarta.activation</groupId><artifactId>jakarta.activation-api</artifactId><version>2.1.2</version></dependency>
Patterns in ‘instanceof’ are not supported at language level ‘8’
因为使用的是JDK1.8,但之前该项目环境是在JDK17中编写的,所以语法有所不同。
点击Alt+Enter后弹出解决提示,即可操作并转换:
将代码进行修改即可,前部分是原先的代码,后部分是修改后的代码
// 前部分:修改前if (e instanceof NotLoginException notLoginException) {// 如果是未登录异常 401commonResult = CommonResult.get(HttpStatus.HTTP_UNAUTHORIZED, notLoginException.getMessage(), null);} else if (e instanceof NotRoleException notRoleException) {// 如果是角色异常 403commonResult = CommonResult.get(HttpStatus.HTTP_FORBIDDEN, "无此角色:" + notRoleException.getRole() +",接口地址:" + CommonServletUtil.getRequest().getServletPath(), null);} else if (e instanceof NotPermissionException notPermissionException) {// 如果是权限异常 403commonResult = CommonResult.get(HttpStatus.HTTP_FORBIDDEN, "无此权限:" + notPermissionException.getPermission(), null);} else if (e instanceof DisableServiceException disableServiceException) {// 如果是被封禁异常 403commonResult = CommonResult.get(HttpStatus.HTTP_FORBIDDEN, "账号被封禁:" + disableServiceException.getDisableTime() + "秒后解封", null);} else if (e instanceof SaTokenException saTokenException) {// 如果是SaToken异常 直接返回commonResult = CommonResult.error(saTokenException.getMessage());}
// 后部分:修改后if (e instanceof NotLoginException) {NotLoginException notLoginException = (NotLoginException) e;// 如果是未登录异常 401commonResult = CommonResult.get(HttpStatus.HTTP_UNAUTHORIZED, notLoginException.getMessage(), null);} else if (e instanceof NotRoleException) {NotRoleException notRoleException = (NotRoleException) e;// 如果是角色异常 403commonResult = CommonResult.get(HttpStatus.HTTP_FORBIDDEN, "无此角色:" + notRoleException.getRole() +",接口地址:" + CommonServletUtil.getRequest().getServletPath(), null);} else if (e instanceof NotPermissionException) {NotPermissionException notPermissionException = (NotPermissionException) e;// 如果是权限异常 403commonResult = CommonResult.get(HttpStatus.HTTP_FORBIDDEN, "无此权限:" + notPermissionException.getPermission(), null);} else if (e instanceof DisableServiceException) {DisableServiceException disableServiceException = (DisableServiceException) e;// 如果是被封禁异常 403commonResult = CommonResult.get(HttpStatus.HTTP_FORBIDDEN, "账号被封禁:" + disableServiceException.getDisableTime() + "秒后解封", null);} else if (e instanceof SaTokenException) {SaTokenException saTokenException = (SaTokenException) e;// 如果是SaToken异常 直接返回commonResult = CommonResult.error(saTokenException.getMessage());}
其他的类似的错误比如 if(model instanceof CommonException exception){} 也可以进行类似的修改为 if(model instanceof CommonException) { CommonException exception = (CommonException) model;} 即可。
解决以上报错有关程序包jakarta的问题会不断地冒出,所以要一个一个不断地解决,还有个处理方式,就是将所有的jakarta
库相关引入包都改为javax
库引入。