将Spring Boot应用程序迁移到Java9:兼容性

时间:2023-01-04 11:40:50

将 Spring Boot 应用程序迁移到 Java 9:兼容性
  随着 Java 9 的到来,关于如何迁移应用程序以使用模块系统有很多的讨论。遗憾的是,大多数文章的焦点都集中于简单的 Hello World 程序上。或者更糟的是,对于 Spring 应用程序,示例应用程序使用传统做法 - 例如使用 XML 作为示例。
  本文的目的旨在通过对 Spring Boot 程序提供逐步的迁移指南来纠正这一点,本文所使用的示例程序是 Spring Pet clinic 。
  使用 Java 9 主要有两个步骤:首先,要兼容,然后使用完整的模块系统。这篇文章目的是实现第一点,后续的文章会考虑后面一点。
  冲突的 Java 版本
  一旦 JDK9 在目标机器上可用,首先在 POM 中就要解决冲突,把 java.version 的值从 8 修改为 9:
  9
  现在,可以进行 mvn clean 编译。
  冲突的 Java 版本
  发现的第一个错误是这样的:
  [ERROR] Failed to execute goal org.codehaus.mojo:cobertura-maven-plugin:2.7:clean (default) on project spring-petclinic:
  Execution default of goal org.codehaus.mojo:cobertura-maven-plugin:2.7:clean failed:
  Plugin org.codehaus.mojo:cobertura-maven-plugin:2.7 or one of its dependencies could not be resolved:
  Could not find artifact com.sun:tools:jar:0 at
  specified path /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/../lib/tools.jar -> [Help 1]
  Cobertura 是一款免费的Java代码覆盖率报告工具。
  — https://github.com/cobertura/cobertura
  它需要访问 tools.jar,而这一部分是 JDK8(或更早的)。Java 9 的一个改变就是移除了这个库。因此,就不能编译了。这已经是一个被记录了的问题。
  Cobertura 库的最近一次提交是一年前了,只是对 Cobertura Maven 插件进行了注释。想想还是让 JaCoCo 代替 Cobertura 吧。
  Wro4J 错误
  下一个错误是:
  [ERROR] Failed to execute goal ro.isdc.wro4j:wro4j-maven-plugin:1.8.0:run (default) on project spring-petclinic:
  Execution default of goal ro.isdc.wro4j:wro4j-maven-plugin:1.8.0:run failed:
  An API incompatibility was encountered while executing ro.isdc.wro4j:wro4j-maven-plugin:1.8.0:run:
  java.lang.ExceptionInInitializerError: null
  wro4j 是一个免费开源的 Java 项目,可以有效减少项目页面的加载时间. 它能很好地组织 (js & css) 静态资源, 在运行期(使用简单的过滤器) 或者编译器 (使用 maven 插件)合并或最小化这些资源。
  此外在处理 web 资源时,有很多有用的的特性可以使用.
  — https://github.com/wro4j/wro4j
  这个问题引用自 Github issue(https://github.com/wro4j/wro4j/issues/1039)。改变已经提交并合并, 但是这个问题仍未解决,因为 Java 9 的兼容应该是2.0 版的一部分。
  现在我们给 Wro4J 加上注释 。
  编译失败
  此时编译项目显示下面的错误信息:
  /Users/i303869/projects/private/spring-petclinic/src/main/java/org/springframework/samples/petclinic/vet/Vet.java
  Error:(30, 22) java: package javax.xml.bind.annotation is not visible
  (package javax.xml.bind.annotation is declared in module java.xml.bind, which is not in the module graph)
  /Users/i303869/projects/private/spring-petclinic/src/main/java/org/springframework/samples/petclinic/vet/Vets.java
  Error:(21, 22) java: package javax.xml.bind.annotation is not visible
  (package javax.xml.bind.annotation is declared in module java.xml.bind, which is not in the module graph)
  Error:(22, 22) java: package javax.xml.bind.annotation is not visible
  (package javax.xml.bind.annotation is declared in module java.xml.bind, which is not in the module graph)
  这意味着,在默认情况下,类路径下的代码无法访问模块。这个问题需要用 Java 9 的 javac 编译指令加上选项-- add-modules 手动添加。在 Maven 里, 可以用 maven-compiler-plugin 设置:
  maven-compiler-plugin
  3.7.0
  --add-modules
  java.xml.bind
  现在项目可以编译了。
  测试故障
  接下来的步骤是使用 mvn 测试进行的单元测试失败的过程。
  导致的原因是一样的,但更难找到。它需要检查那些万无一失的报告。有些包含以下行中的异常:
  Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
  又一次,测试代码不能访问模块。然而,这一次,需要配置 maven-surefire-plugin 插件:
  maven-surefire-plugin
  2.20.1
  --add-modules java.xml.bind
  这样才能使得测试工作有效。
  包故障
  如果有人认为这是路的尽头,那就再想想。打包阶段也会出现一个相当神秘的错误:
  [ERROR] Failed to execute goal org.apache.maven.plugins:maven-jar-plugin:2.6:jar (default-jar) on project spring-petclinic:
  Execution default-jar of goal org.apache.maven.plugins:maven-jar-plugin:2.6:jar failed:
  An API incompatibility was encountered while executing org.apache.maven.plugins:maven-jar-plugin:2.6:jar:
  java.lang.ExceptionInInitializerError: null
  ...
  Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
  at org.codehaus.plexus.archiver.zip.AbstractZipArchiver.(AbstractZipArchiver.java:116)
  这一项更难找到: 它需要谷歌搜索才能找到解决方案。这被归咎于 plexus-archiver。maven-jar-plugin 与最新版本冲突,而本文编写时使用 Java 9 兼容版本的 archiver 版本,解决了这个问题:
  maven-jar-plugin
  3.0.2
  Spring Boot 插件错误
  走到这一步, 项目最终可以正常编译、测试、打包。下一步是使用 Spring Boot 的 Maven 插件运行应用,即 mvn spring-boot:run。但是再次显示运行失败…:
  [INFO] --- spring-boot-maven-plugin:1.5.1.RELEASE:run (default-cli) @ spring-petclinic ---
  [INFO] Attaching agents: []
  Exception in thread "main" java.lang.ClassCastException:
  java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to java.base/java.net.URLClassLoader
  at o.s.b.devtools.restart.DefaultRestartInitializer.getUrls(DefaultRestartInitializer.java:93)
  at o.s.b.devtools.restart.DefaultRestartInitializer.getInitialUrls(DefaultRestartInitializer.java:56)
  at o.s.b.devtools.restart.Restarter.(Restarter.java:140)
  at o.s.b.devtools.restart.Restarter.initialize(Restarter.java:546)
  at o.s.b.devtools.restart.RestartApplicationListener.onApplicationStartingEvent(RestartApplicationListener.java:67)
  at o.s.b.devtools.restart.RestartApplicationListener.onApplicationEvent(RestartApplicationListener.java:45)
  at o.s.c.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
  at o.s.c.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
  at o.s.c.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:122)
  at o.s.b.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:68)
  at o.s.b.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:48)
  at o.s.b.SpringApplication.run(SpringApplication.java:303)
  at o.s.b.SpringApplication.run(SpringApplication.java:1162)
  at o.s.b.SpringApplication.run(SpringApplication.java:1151)
  at org.springframework.samples.petclinic.PetClinicApplication.main(PetClinicApplication.java:32)
  这是因为 Spring Boot v1.5 开发者工具和 Java 9 不兼容,可以在 documented issue 里找到。
  好在这个 bug 在 Spring Boot 2.0.0.M5 里已经修复。但不幸的是, 在写这篇文章的时候,特定的版本仍然无法使用。现在, 移除开发者工具,再次尝试运行。又失败了, 但是这次显示的是一个熟悉的异常:
  Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
  在 spring-boot-maven-plugin 里面加上必要的参数:
  org.springframework.boot
  spring-boot-maven-plugin
  --add-modules java.xml.bind
  ...
  应用终于启动成功并可以访问了!
  结论
  在 JDK 9 运行重要的遗留项目需要费点功夫。更糟糕的是, 必须放弃一些重要特性: 代码覆盖和 web 性能提升。反过来, 唯一得到的微不足道的好处是 Stirng 内存空间改善。
  成都java培训哪家好,当然是成都达内培训,成都达内是一家专业的程序员培训机构,专注于网络营销课程,成都web前端培训,成都软件测试培训,成都php培训,成都java培训,成都安卓培训,成都会计实操培训,web前端开发,成都网络营销培训,成都it培训,成都编程培训,成都程序员培训等IT培训,专业的成都软件培训机构,专业师资授课,真实项目实战、零首付、低押金、名企就业,达内培训怎么样,成都java培训机构www.cdtedu.com/pxkc/java/

将Spring Boot应用程序迁移到Java9:兼容性的更多相关文章

  1. Spring Boot 2.0 迁移指南

    ![img](https://mmbiz.qpic.cn/mmbiz_jpg/1flHOHZw6Rs7yEJ6ItV43JZMS7AJWoMSZtxicnG0iaE0AvpUHI8oM7lxz1rRs ...

  2. 使用Maven插件构建Spring Boot应用程序镜像

    使用Maven插件构建Spring Boot应用程序的Docker镜像. 环境准备 1.Linux系统 2.安装JDK,Maven 3.安装Docker 应用实践 1.在应用程序根目录下添加Docke ...

  3. docker 部署Spring Boot:Docker化Spring Boot应用程序

    第一章 1.创建项目存放目录 mkdir /root/sproot -p 2.准备好Spring Boot应用程序 jar 包 testrest.jar 第二章 1. 安装docker 在所有节点执行 ...

  4. SpringBoot之二:部署Spring Boot应用程序方式

    衡量多种部署方式 Spring Boot应用程序有多种构建和运行方式,其中一些你已经使用过了. 在IDE中运行应用程序(涉及Spring ToolSuite或IntelliJ IDEA). 使用Mav ...

  5. Spring Boot入门程序-STS

    使用Eclipse EE 中的 Spring Tool插件,完成 第一个Spring Boot应用程序的创建. 一.安装Spirng Tool插件 在 Eclipse EE Oxygen版本,安装“S ...

  6. Spring Boot入门程序

    创建第一个Spring Boot的入门程序. 带你一步一步的,搭建第一个Spring Boot 的入门程序,并成功运行,通过实践过程,初步认识和了解如何使用Spring Boot 创建应用程序. 一. ...

  7. 如何为Spring Boot应用程序配置端口

    [转]https://www.javaroad.cn/questions/11162 1 个月前 1.1通过属性文件更新 . /src/main/resources/application.prope ...

  8. 阿里P7级教你如何在Spring Boot应用程序中使用Redis

    在Spring Boot应用程序中使用Redis缓存的步骤: 1.要获得Redis连接,我们可以使用Lettuce或Jedis客户端库,Spring Boot 2.0启动程序spring-boot-s ...

  9. 峰哥说技术:02-第一个Spring Boot应用程序

    Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 02第一个Spring Boot应用程序 1.版本要求 集成开发环境:IntelliJ IDEA 2017 ...

随机推荐

  1. Kubuntu 使用YaH3C进行中大校园网认证

    之前都是用路由器连网线上网,我也没注意到inode校园网客户端在linux上的问题.直到前两天把路由器给搞残废了,只能默默的找办法装inode.根据学校网络中心给的教程,在kubuntu上尝试安装in ...

  2. Linux 信号概念

    程序在执行的时候,几乎任何时刻都会反生事件. 信号通常用来向一个进程通知事件. 信号是不可提前预知的,所以信号是异步的. 信号随时都可能发生,接收信号的进程也可以没有控制权. 每个信号名都以SIG开头 ...

  3. 博客搬到blog.csgrandeur.com

    博客已搬到blog.csgrandeur.com. cnblogs停止更新. wordpress太臃肿,难刷. hexo对windows似乎不太友好,迁移的时候建了十几层文件夹,导致目录过深无法移动无 ...

  4. 操作系统—Systemd

    操作系统-Systemd 时间 2016-09-24 22:34:49  运维部落 原文  http://www.178linux.com/48990 主题 systemd Systemd 概述: C ...

  5. 【个人使用.Net类库】(2)Log日志记录类

    开发接口程序时,要保证程序稳定运行就要时刻监控接口程序发送和接收的数据,这就需要一个日志记录的类将需要的信息记录在日志文件中,便于自己维护接口程序.(Web系统也是如此,只是对应的日志实现比这个要复杂 ...

  6. React模板

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. js选中下拉框的默认选项

    //这是修改时选中 $("#type").find("option[value='"+factory+"']").attr("se ...

  8. SAP:建表时如果有QUAN、CURR类型的字段不能激活的问题

    建表时如有一个QUAN类型的字段,那么就要给字段设置Reference field,参考的字段的Data Type要是UNIT, 并设置对应的Reference table,也就是参考字段所在的tab ...

  9. photoshop中rgb与索引模式的区别

    RGB: 是色域最宽广的颜色模式它是一种光色模式不难理解  你的显示器 就是根据这个模式来显示图像的同样 我们在自然界中 看到的所有五颜六色的东西都是吸收了不同颜色的光 而得到的所以这一颜色模式 与我 ...

  10. javascript (六) 引用外部js文件

    外部的 JavaScript 也可以把脚本保存到外部文件中.外部文件通常包含被多个网页使用的代码. 外部 JavaScript 文件的文件扩展名是 .js. 如需使用外部文件,请在 <scrip ...