java 8 升级 java 11
由于orcle 停止对jdk8的免费后续安全更新,经过决策之后采用升级 jdk 至 11 的决策。
具体版本:
当前版本
java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
目标版本
java -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.2+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.2+9, mixed mode)
升级过程:
下载安装使用 jdk11
-
JDK 下载
JDK11 版本的选型为:AdoptOpenJDK 11.0.2+9
https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/tag/jdk-11.0.2+9
下载
https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.2%2B9/OpenJDK11U-jdk_x64_windows_hotspot_11.0.2_9.zip -
(将环境变量修改为 jdk11,若不在命令行启动java程序 如Tomcat,则可跳过此步骤,一般windows上使用IDE的不用进行)
-
IDE设置:
- 添加 JDK11 :ctrl shift alt + s --> SDKs --> + 选择jdk --> 确定目录
- 指定项目的编译器为刚添加的 JDK11:ctrl shift alt + s ——> Project ——> Project SDK 和 Project SDK Level 改为刚添加的 11,其余不变(项目由maven的pom.xml控制)
更新项目编译器为JDK11 - pom.xml 修改,详细过程见下
pom.xml改造
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
这个插件用于编译源代码; 将其中的configuration代表着使用11来进行编译
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<argLine>
--illegal-access=permit
</argLine>
</configuration>
</plugin>
surefire 插件用来在maven构建生命周期的test phase执行一个应用的单元测试。它会产生两种不同形式的测试结果报
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.23.1-GA</version>
</dependency>
问题罗列:
若本文提供的办法未能解决,可以进行以下尝试
-
将整个项目/工程 clean,再用 java 11 重新编译
IDEA中:
Build —— Build Artifacts —— All —— Clean
Build —— Build Artifacts —— All —— Build -
删除 tomcat/webapps 下面对应的组件 (清空缓存)
问题1
症状表现
Resource cannot be resolved to a type
javax.annotation.Resource
原因
找不到Resource类; java11 中已去除,替代解决方案
解决方式
pom.xml中添加:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
参考自 Stack Overflow
问题2
Error:java: 找不到符号
符号: 类 Resource
位置: 程序包 javax.annotation
解决方式:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
问题3
JAXB (java.xml.bind)问题
表现如下:
Error:(10, 33) java: 程序包javax.xml.bind.annotation不存在
Error:(24, 2) java: 找不到符号
符号: 类 XmlRootElement
Error:(28, 6) java: 找不到符号
符号: 类 XmlElement
位置: 类 com.xxx.xxx.xxxx.xxx.entity.xxx
.....
原因
openJDK11删除了一些包,以下为公告:
Removal Of Java EE Modules
There used to be a lot of code in Java SE that was actually related to Java EE. It ended up in six modules that were deprecated for removal in Java 9 and removed from Java 11. Here are the removed technologies and packages:)
the JavaBeans Activation Framework (JAF) in javax.activation
CORBA in the packages javax.activity, javax.rmi, javax.rmi.CORBA, and org.omg.*
the Java Transaction API (JTA) in the package javax.transaction
JAXB in the packages javax.xml.bind.* ############ 该包为引起该问题的原因
JAX-WS in the packages javax.jws, javax.jws.soap, javax.xml.soap, and javax.xml.ws.*
Commons Annotation in the package javax.annotation
版本对应如下:
<!-- Java 6 = JAXB version 2.0 -->
<!-- Java 7 = JAXB version 2.2.3 -->
<!-- Java 8 = JAXB version 2.2.8 -->
<!-- Java 9 = JAXB version 2.3.0 -->
注:之前项目是哪个版本的 jdk 就引入哪个版本,比如我之前是 java8,所以我要引入的JAXB版本为 2.2.8
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.8</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.8</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.8</version>
</dependency>
参考自 Stack Overflow
问题4
Warning:(54, 44) java: java.lang.Class中的newInstance()已过时
解决方式:
查看 open jdk 11 java.lang.Class中的newInstance() 源码,部分注释如下
/* can be replaced by
*
* <pre>{@code
* clazz.getDeclaredConstructor().newInstance()
*}</pre>
*/
大概意思为可以用以上方法替换
即将所有
clazz.newInstance();
替换成
clazz.getDeclaredConstructor().newInstance();
问题5
启动Tomcat后
Artifact upm-web:war: Error during artifact deployment. See server log for details.
查看日志如下:
19-Mar-2019 09:50:31.061 涓ラ噸 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [com.xxx.xxx.xxx.WebContextLoaderListener]
java.lang.UnsupportedClassVersionError: com/xxx/xxx/xxx/WebContextLoaderListener has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0 (unable to load class [com.xxx.xxx.xxx.WebContextLoaderListener])
at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2377)
at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:846)
...
19-Mar-2019 09:50:31.061 涓ラ噸 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.listenerStart Skipped installing application listeners due to previous error(s)
原因
根据异常信息的描述(不支持的xxx.class 版本),意思为当前要加载的class版本为 55(java 11),不能加载, 当前的java runtime最高支持 52 版本(java 8)的 .class 文件
其中java版本与 class 版本对应为:
J2SE 11 = 55 (0x33 hex),
J2SE 10 = 54 (0x33 hex),
J2SE 9 = 53 (0x33 hex),
J2SE 8 = 52 (0x33 hex),
J2SE 7 = 51 (0x33 hex),
J2SE 6.0 = 50 (0x32 hex),
J2SE 5.0 = 49 (0x31 hex),
JDK 1.4 = 48 (0x30 hex),
JDK 1.3 = 47 (0x2F hex),
JDK 1.2 = 46 (0x2E hex),
JDK 1.1 = 45 (0x2D hex).
可以看出,问题的实际原因是 java8 编译的程序(Tomcat)调用了 java11 编译的程序。
解决方式:
使用高版本 Tomcat 9
详细过程:
- 去Tomcat官网下载 Tomcat9
- 解压下载的 zip
- (修改Tomcat环境变量 不在命令行中使用可跳过)
- 修改 IDE 中设置的 Tomcat 为新安装的 Tomcat9,以 IDEA 为例:
- 右上运行设置 Edit Configurations —— Application Server 右边的 Configura…
- 点击左上 + 添加新安装的 Tomcat9 的文件位置 OK 确定保存
- 下方修改 Jre 改为新添加的 jdk 11
- 保存设置(注意下方提示区域是否有错误出现)
- 运行检查是否配置正确