jdk8项目升级到jdk17——岁月云实战
由于很早之前就升级springboot版本到2.7.9,以前做好了铺垫,相对升级要容易一些。
1 项目打包成exe
1.1 jpackage打包jar
C:\Users\39305\Desktop\数量核对>jpackage ^
More? --type exe ^
More? --name zp-server ^
More? --input C:\Users\39305\Desktop\数量核对 ^
More? --main-jar zp-server.jar ^
More? --main-class com.dzmsoft.zp.server.ZpServerApplication ^
More? --icon E:\workspace\vuework\fay-web\public\favicon.ico ^
More? --app-version 1.0 ^
More? --vendor "dj" ^
More? --description "子平服务"
[08:33:59.830] 找不到 WiX 工具 (light.exe, candle.exe)
[08:33:59.830] 从 https://wixtoolset.org 下载 WiX 3.0 或更高版本,然后将其添加到 PATH。
错误:类型 [exe] 无效或不受支持
jpackage依赖wix tools,在wix3中下载
安装wix311需要.net 3.5.1环境,
执行打包脚本,exe文件可以生成,但是启动后程序一闪而过,这个问题是咋回事呢
jpackage ^
--input .\in ^
--type exe ^
--description "子平服务" ^
--name "zp-server" ^
--main-jar "zp-server.jar" ^
--main-class "com.dzmsoft.zp.server.ZpServerApplication" ^
--icon ".\favicon.ico" ^
--win-console ^
--win-dir-chooser ^
--win-shortcut ^
--win-shortcut-prompt ^
--java-options "-Dfile.encoding=UTF-8 -Xmx512m -Xms256m"
添加一个脚本zp-server.bat,接着就可以看到错误原因
@echo off
REM 启动应用程序并保持窗口打开
cmd /k "D:\Program Files\zp-server\zp-server.exe"
错误消息终于出来了,为什么找不到启动类呢?
查看这个文件,就知道为什么了,因为MANIFEST.MF
文件包含正确的主类声明
内容如下,原来springboot启动类是org.springframework.boot.loader.JarLauncher
Manifest-Version: 1.0
Created-By: Maven JAR Plugin 3.2.2
Build-Jdk-Spec: 17
Implementation-Title: zp-server
Implementation-Version: 3.0.0
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.dzmsoft.zp.server.ZpServerApplication
Spring-Boot-Version: 2.7.9
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
因此打包命令调整如下,这样挺好的,因为只需要改少部分就可以了。
jpackage ^
--input .\in ^
--type exe ^
--description "服务" ^
--name "test-server" ^
--main-jar "zp-server.jar" ^
--main-class "org.springframework.boot.loader.JarLauncher" ^
--icon ".\favicon.ico" ^
--win-console ^
--win-dir-chooser ^
--win-shortcut ^
--win-shortcut-prompt ^
--java-options "-Dfile.encoding=UTF-8"
1.2 nsis
2 项目升级
2.1 网关
Spring Cloud Gateway 并不是设计为与 Spring MVC 一起工作的,
- Spring Cloud Gateway:是一个基于非阻塞 I/O 的 API 网关,适用于构建微服务架构中的网关层。
- Spring MVC:是基于 Servlet 的传统 Web 框架,适用于构建传统的 Web 应用程序。
Description:
Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.
Action:
Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.
因此需要将spring-boot-starter-web相关的依赖排查掉即可。
<dependency>
<groupId>com.whty</groupId>
<artifactId>com.whty.framework.redis</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-web</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
2.2 非公成员访问问题
ava 9 及以上版本引入了模块系统(Jigsaw),加强了类库和应用程序之间的封装。在这些版本中,反射访问非公共成员(如私有字段或方法)受到更严格的限制,除非显式地允许。
java.lang.reflect.InaccessibleObjectException: Unable to make field private int java.lang.StackTraceElement.lineNumber accessible: module java.base does not "opens java.lang" to unnamed module @120f102b
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.getFieldMap(JavaDeserializer.java:340)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.<init>(JavaDeserializer.java:80)
在开发环境中Idea配置如下
2.3 java: 错误: 不支持发行版本 5
这是因为有些jar需要明确编译版本,比如api的组件,为了兼容性。
2.4 javax.xml包
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
2.5 sun.awt.image.BufferedImageGraphicsConfig
下面是作电子签章的时候一段代码,但是jdk17已经没有这个类了,
// 创建画布
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g;
if (isTransparency) { // 透明背景
BufferedImageGraphicsConfig config = BufferedImageGraphicsConfig.getConfig(image);
image = config.createCompatibleImage(image.getWidth(), image.getHeight(), Transparency.TRANSLUCENT);
g = image.createGraphics();
g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 0.7f)); // 章透明
} else {
g = image.createGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
}
调整代码如下,通过选择 BufferedImage.TYPE_INT_ARGB
类型来创建支持透明度的 BufferedImage
,而不是使用 BufferedImageGraphicsConfig
这个内部类
BufferedImage image ;
Graphics2D g;
if (isTransparency) { // 透明背景
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g = image.createGraphics();
g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 0.7f)); // 章透明
} else {
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g = image.createGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
}