1. 程式人生 > >將Spring Boot應用程序遷移到Java9:兼容性

將Spring Boot應用程序遷移到Java9:兼容性

sam 最新 ive 就業 ont add home index world

將 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:兼容性