将 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/

最新文章

  1. composer "Illegal offset type in isset or empty"报错解决方案
  2. [ios][swift]swift 怎么去除 optional
  3. WPF实现渐变淡入淡出的动画效果
  4. U盘安装Win7 64位
  5. php日期处理
  6. 一些有用的 Emacs 配置(窗口快速切换、一键透明效果、任意位置删除整行等)
  7. git相关的学习资料
  8. 初学mysql 那些记不住的命令
  9. [leetcode]224. Basic Calculator
  10. [Kafka] |FAIL|rdkafka#producer-1 : Receive failed: Disconnected
  11. ORA-12514 TNS:LISTENER DOES NOT CURRENTLY KNOW OF SERVICE REQUESTED IN CONNE
  12. Swift Assert 断言
  13. 用Python下载美国国家气候数据中心(NCDC)的气候数据
  14. python常用模块目录
  15. codevs 2292 图灵机游戏
  16. Python的科学计算包matplotlib setup
  17. SQL操作语句之查询及删除重复记录的方法
  18. Spring常见面试题
  19. mongodb数据库操作之简单查询
  20. VS2013 中使用 CxImage 库时用Unicode编码时出现链接错误

热门文章

  1. BZOJ 2150 部落战争 (二分图匹配)
  2. MVC、RPC、SOA、微服务架构之间的区别
  3. -bash: wget 未找到命令的解决办法
  4. cogs 466. [NOIP2009] 细胞分裂
  5. php获取当前url地址的方法小结
  6. Android自己定义TabActivity(实现仿新浪微博底部菜单更新UI)
  7. Spring表达式语言SpEL简单介绍
  8. 用了一天的时间,linux下expect实现ssh自己主动登录server记,歧视下网上各种抄来抄去残段子
  9. 上传文件 nginx 413错误
  10. NOIP2017提高组模拟赛 7(总结)