最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JDK從8升級到21的問題集(附案例代碼)

 更新時間:2025年09月08日 09:35:52   作者:京東云開發(fā)者  
JDK 8升級到JDK 21是一個重要的版本遷移,涉及語法、模塊化、API變更等多方面調(diào)整,這篇文章主要介紹了JDK從8升級到21問題的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

一、背景與挑戰(zhàn)

1.升級動因

?Oracle長期支持策略

?現(xiàn)代特性需求:協(xié)程、模式匹配、ZGC等

?安全性與性能的需求

?AI新技術(shù)引入的版本要求

2.項目情況

?100+項目并行升級的協(xié)同作戰(zhàn)

?多技術(shù)棧并存

?持續(xù)集成體系的適配挑戰(zhàn)

二、進度

應用總數(shù)已完成應用下線待升級
100+731310+

三、主要問題域與解決方案

1. 依賴管理的"蝴蝶效應"

•sun.misc.BASE64Encoder等內(nèi)部API廢棄 → 引發(fā)編譯錯誤

•JAXB/JAX-WS從JDK核心剝離 → XML處理鏈斷裂

•Lombok與新版編譯器兼容性問題(尤其record類型)

核心原因在于JEP320提案:https://openjdk.org/jeps/320

案例1:歷史SDK的編譯陷阱

Compilation failure: Compilation failure:
#14 4.173 [ERROR] 不再支持源選項 6。請使用 8 或更高版本。
#14 4.173 [ERROR] 不再支持目標選項 6。請使用 8 或更高版本。
<!-- 舊版本編譯器配置導致構(gòu)建失敗 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5</version>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.13.0</version>
    <configuration>
        <release>8</release><!-- 統(tǒng)一使用release參數(shù) -->
    </configuration>
</plugin>

運行 HTML

案例2:JAXB的模塊化剝離

javax.xml.bind.JAXBException:Implementation of JAXB-API has not been found
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>4.0.5</version>
</dependency>

案例3:Lombok與新版編譯器兼容性問題

java: java.lang.NoSuchFieldError
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.30</version>
</dependency>

案例4:Resource注解找不到

Caused by: java.lang.NoSuchMethodError: 'java.lang.String javax.annotation.Resource.lookup()'
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.<init>(CommonAnnotationBeanPostProcessor.java:664)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.lambda$buildResourceMetadata$0(CommonAnnotationBeanPostProcessor.java:395)
at org.springframework.util.ReflectionUtils.doWithLocalFields(ReflectionUtils.java:669)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.buildResourceMetadata(CommonAnnotationBeanPostProcessor.java:377)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.findResourceMetadata(CommonAnnotationBeanPostProcessor.java:358)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(CommonAnnotationBeanPostProcessor.java:306)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
... 37 more
<dependency>
    <groupId>jakarta.annotation</groupId>
    <artifactId>jakarta.annotation-api</artifactId>
    <version>1.3.5</version>
</dependency>

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

上述兩個依賴代碼基本一樣,推薦使用該版本:

jakarta.annotation:jakarta.annotation-api。

2. 模塊化的破與立

反射訪問的模塊墻

[ERROR] Unable to make field private int java.text.SimpleDateFormat.serialVersionOnStream accessible
# 啟動參數(shù)添加模塊開放配置
--add-opens java.base/java.text=ALL-UNNAMED
--add-opens java.base/java.lang.reflect=ALL-UNNAMED

完整模塊開放配置模板

export JAVA_OPTS="-Djava.library.path=/usr/local/lib -server -Xmx4096m --add-opens java.base/sun.security.action=ALL-UNNAMED
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.math=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/sun.util.calendar=ALL-UNNAMED
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
--add-opens java.base/java.util.concurrent.locks=ALL-UNNAMED
--add-opens java.base/java.security=ALL-UNNAMED
--add-opens java.base/jdk.internal.loader=ALL-UNNAMED
--add-opens java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED
--add-opens java.base/sun.nio.ch=ALL-UNNAMED
--add-opens java.management/java.lang.management=ALL-UNNAMED
--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED
--add-opens java.management/sun.management=ALL-UNNAMED
--add-opens java.base/sun.security.action=ALL-UNNAMED
--add-opens java.base/sun.net.util=ALL-UNNAMED
--add-opens java.base/java.time=ALL-UNNAMED
--add-opens java.base/java.lang.reflect=ALL-UNNAMED
--add-opens java.base/java.io=ALL-UNNAMED"

3. 語法層面的"時空穿越"

案例1:Base64編解碼改造

// JDK8寫法(已廢棄)
BASE64Encoder encoder =newBASE64Encoder();
String encoded = encoder.encode(data);
// JDK21規(guī)范寫法
Base64.Encoder encoder =Base64.getEncoder();
String encoded = encoder.encodeToString(data);

案例2:日期序列化問題

Caused by:java.lang.reflect.InaccessibleObjectException: 
Unable to make field private int java.text.SimpleDateFormat.serialVersionOnStream accessible

解決方案

1.使用DateTimeFormatter替代SimpleDateFormat

2.或添加模塊開放參數(shù):--add-opens java.base/java.text=ALL-UNNAMED

4. 隱秘的"依賴戰(zhàn)爭"

注解包沖突典型案例

[ERROR] javax.annotation.Resource exists in both 
jsr250-api-1.0.jar and jakarta.annotation-api-1.3.5.jar
<!-- 統(tǒng)一使用Jakarta標準 -->
<dependency>
    <groupId>jakarta.annotation</groupId>
    <artifactId>jakarta.annotation-api</artifactId>
    <version>2.1.1</version>
</dependency>
<!-- 排除舊版本依賴 -->
<exclusions>
    <exclusion>
        <groupId>javax.annotation</groupId>
        <artifactId>jsr250-api</artifactId>
    </exclusion>
</exclusions>

5. 構(gòu)建體系的改造

Maven插件兼容性問題

[ERROR] The plugin org.apache.maven.plugins:maven-compiler-plugin:3.13.0 
requires Maven version 3.6.3

升級策略

1.升級Maven版本

2.統(tǒng)一插件版本

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.13.0</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.4.0</version>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

四、最佳實踐總結(jié)

1. 本地編譯

第一步:在本地進行編譯,提前識別出語法錯誤、版本沖突及不兼容問題。

主要有以下幾種場景:

Base64:參照 【Base64編解碼改造】

lombok:升級版本

jsr250、jaxb-runtime、jakarta.annotation-api:參照 【注解包沖突典型案例】

maven-compiler-plugin:升級版本

maven-resources-plugin:升級版本

maven-war-plugin:升級版本

2. 行云構(gòu)建

同【本地編譯】

3. 行云部署

a、鏡像不匹配:自定義鏡像或者使用已申請的jdk21鏡像

b、module權(quán)限不夠:參照【完整模塊開放配置模板

c、JDSecurity加解密

所有數(shù)據(jù)庫操作:important.properties配置文件的處理方式

classpath:important.properties 使用PropertyPlaceholderConfigurer進行處理,不要用JDSecurityPropertyFactoryBean。

<!--    <bean id ="secApplicationProperties" class="com.jd.security.configsec.spring.config.JDSecurityPropertyFactoryBean">-->
<!--       <property name="ignoreResourceNotFound" value="true" />-->
<!--       <property name="secLocation" value="classpath:important.properties"/>-->
<!--    </bean>-->

4. 運行

a、序列化異常

jdk21使用列表視圖作為入?yún)?,導致jsf接口進行反序列化報錯。報錯代碼如下:

List<String> subList = venderCodes.subList(i * batchSize, Math.min(venderCodes.size(), (i + 1) * batchSize));
VendorQueryVo vendorQueryVo = new VendorQueryVo();
vendorQueryVo.setVendorCodes(subList);
// 該接口最多支持100條調(diào)用
List<VendorVo> batchVendorNameByVendorCode = vendorBaseInfoService.getBatchVendorNameByVendorCode(vendorQueryVo, I18NParamFactory.getJDI18nParam());

將 vendorQueryVo.setVendorCodes(subList) 修改為vendorQueryVo.setVendorCodes(new ArrayList<>(subList)) 即可解決問題

b、線程上下文類找不到:使用多線程場景下盡可能使用顯式指定線程池【默認情況下 不同運行環(huán)境的處理機制不同】

5. JVM調(diào)優(yōu)

垃圾回收調(diào)優(yōu)

UseParallelGCUseG1GCUseZGC是 Java 虛擬機(JVM)中三種不同的垃圾回收器(Garbage Collector, GC),它們的設計目標和使用場景有所不同。以下是它們的區(qū)別:

特性UseParallelGCUseG1GCUseZGC
設計目標高吞吐量平衡吞吐量和延遲極低延遲
暫停時間較長較短極短
適用堆大小中小堆(幾 GB 到幾十 GB)大堆(幾十 GB 到幾百 GB)超大堆(TB 級別)
CPU 消耗中等中等較高
適用場景批處理、計算密集型任務對延遲有一定要求的應用對延遲極其敏感的應用

•如果你的應用對吞吐量要求高,且可以接受較長的暫停時間,選擇UseParallelGC。

•如果你的應用對延遲有一定要求,且堆內(nèi)存較大,選擇UseG1GC。

•如果你的應用對延遲極其敏感,且堆內(nèi)存非常大,選擇UseZGC。

僅供參考,具體請按照實際情況來進行調(diào)整。

作者:京東工業(yè) 韋付芝

總結(jié)

到此這篇關(guān)于JDK從8升級到21問題集的文章就介紹到這了,更多相關(guān)JDK8升級到21的問題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • PHP Laravel實現(xiàn)文件下載功能

    PHP Laravel實現(xiàn)文件下載功能

    本文重點給大家介紹Laravel實現(xiàn)文件下載功能的實例代碼,需要的朋友參考下吧
    2017-09-09
  • JUnit5相關(guān)內(nèi)容簡介

    JUnit5相關(guān)內(nèi)容簡介

    這篇文章主要介紹了JUnit5相關(guān)內(nèi)容簡介,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • Java使用GZIP壓縮導致HTTP請求返回亂碼問題解決

    Java使用GZIP壓縮導致HTTP請求返回亂碼問題解決

    這篇文章主要為大家介紹了Java壓縮GZIP導致HTTP請求返回亂碼問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • java?SpringBoot?分布式事務的解決方案(JTA+Atomic+多數(shù)據(jù)源)

    java?SpringBoot?分布式事務的解決方案(JTA+Atomic+多數(shù)據(jù)源)

    這篇文章主要介紹了java?SpringBoot?分布式事務的解決方案(JTA+Atomic+多數(shù)據(jù)源),文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-08-08
  • java.sql.SQLException問題解決以及注意事項

    java.sql.SQLException問題解決以及注意事項

    這篇文章主要給大家介紹了關(guān)于java.sql.SQLException問題解決以及注意事項的相關(guān)資料,這個問題其實很好解決,文中通過圖文將解決的辦法介紹的很詳細,需要的朋友可以參考下
    2023-07-07
  • springSecurity過濾web請求的項目實踐

    springSecurity過濾web請求的項目實踐

    SpringSecurity是一個功能強大的安全框架,提供了全面的 Web 安全功能,它的核心之一是過濾器鏈,用于攔截和處理 Web 請求,本文就來介紹SpringSecurity配置和使用過濾器來管理Web請求的安全性,感興趣的可以了解一下
    2025-09-09
  • 關(guān)于springboot集成阿里云短信的問題

    關(guān)于springboot集成阿里云短信的問題

    這篇文章主要介紹了springboot集成阿里云短信的方法,本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-11-11
  • java?Executors常用線程池

    java?Executors常用線程池

    這篇文章主要為大家介紹了java?Executors中提供的幾種常用的線程池使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • Spring通過三級緩存解決循環(huán)依賴問題的過程詳解

    Spring通過三級緩存解決循環(huán)依賴問題的過程詳解

    循環(huán)依賴指的是在對象之間存在相互依賴關(guān)系,形成一個閉環(huán),導致無法準確地完成對象的創(chuàng)建和初始化,本文主要介紹了Spring通過三級緩存解決循環(huán)依賴的方法,需要的可以參考下
    2023-10-10
  • java 如何使用org.w3c.dom操作XML文件

    java 如何使用org.w3c.dom操作XML文件

    這篇文章主要介紹了java 如何使用org.w3c.dom操作XML文件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論

枣庄市| 五家渠市| 丁青县| 财经| 杭锦旗| 佳木斯市| 尚义县| 鄂尔多斯市| 和田市| 灵台县| 富川| 威海市| 安义县| 枣强县| 沙雅县| 黑山县| 竹北市| 大新县| 泰州市| 德昌县| 兖州市| 普定县| 蒙城县| 怀化市| 堆龙德庆县| 神农架林区| 澳门| 兰州市| 德钦县| 丰宁| 龙江县| 梁山县| 上虞市| 绥中县| 富民县| 南召县| 确山县| 长岛县| 堆龙德庆县| 海口市| 兴城市|