出現問題:
今天在pom.xml中引入了最新版本guava工具包,編譯時報了如下錯誤:
[ERROR] E:\workspace\report\src\main\java\indi\johnny\report\template\excel\ExcelXSSFStyle.java:[16,-1] 無法訪問 com.google.common.base.Strings
錯誤的類文件: com\google\common\base\Strings.class(com\google\common\base:Strings.class)
類文件具有錯誤的版本 52.0,應為 50.0
如圖:
圖1
概念引進:
major.minor 版本號:每個版本的 JDK 編譯器編譯出的 class 文件中都帶有一個版本號。
上面截圖中出現的52.0 50.0 就是我們所說的major版本號。
問題排查:
將出現問題的guava-21.0.jar 通過[ jar –xvf guava-21.0.jar ]解壓后,進入目錄,找到報出異常的類"Strings"
圖2
通過找到報出異常的類"Strings" ,使用 命令:[ javap -verbose Strings ] ,能顯示出類的 major.minor 版本,major版本確實為52。
圖3
解決方案:
降低guava的版本,如下圖所示,將版本21.0換成19.0:
圖4
再次編譯項目,則編譯成功。
解壓 guava-19.0.jar后,找到報出異常的類"Strings" ,使用 命令:[ javap -verbose Strings ] ,能顯示出類的 major.minor 版本,為50。
圖5
jdk版本與major版本對應的關系如下,參考博客:http://smilejay.com/2014/02/java-unsupported-major-minor-version-51-0/
圖6
我本地的jdk版本為1.6(等同6.0),對應的major版本為50,所以異常提示的信息為 "應為 50.0"
查看guava-21.0.jar解壓后目錄META-INF下的文件MANIFEST.MF,如圖所示,jdk編譯版本為1.8:
圖7
但是查看guava-19.0.jar解壓后目錄META-INF下的文件MANIFEST.MF,如圖所示,jdk編譯版本不是1.6,而是1.7:
圖8
個人理解:class文件加載至jvm並不是完全按照圖6一 一對應的關系,而是按照major.minor版本號范圍來加載至JVM,超出范圍則要出錯。
本地1.6的環境能夠識別並運行1.7編譯的guava-19.0.jar包,是因為guava-19.0.jar中的"Strings"類的major版本號為50。
參考博客:http://sheng.iteye.com/blog/690035
結論:加載至jvm中的class文件,class文件的major版本號必須等於或小於當前jvm環境要求的最大major版本號。
通俗講:假設Student.class的major版本號為50,既可以放在1.6的jvm中運行,也可以放在1.8的jvm中運行。若Student.class的major版本號為52,則只能在1.8或更高版本的jvm中運行。
歡迎拍磚!