當前位置:首頁 » 編程語言 » java17jdk

java17jdk

發布時間: 2024-01-17 16:58:22

java17安裝問題不知道怎麼回事

於是打開C盤,查看處設置為「顯示隱藏的項目」,查找並刪除JAVA安裝失敗留下的文件。

供找到了3處,將3處文件刪除即可重新安裝JDK17了。
1. C:\ProgramData\Oracle,刪除
2. C:\Users\LordY\AppData\LocalLow下有兩個JAVA安裝相關文件,刪除
3. C:\Users\LordY\AppData\Local\Temp下的JAVA_MSIUI_FLAG文件,刪除
然後重新安裝,大功告成!
若還不能安裝,則建議在C盤下的搜索輸入框內輸入「JAVA」關鍵字進行查找,刪除與JAVA相關文件即可。

Ⅱ java選的jdk11為什麼變成了17

Java11升級Java17備忘錄

下塘燒餅
白頭不厭窮編碼,隻影孤燈兩卷書。
來自專欄一隻老程序猿
一、概述
Java17是目前Java最新的LTS版本,SpringBoot從2.5.5開始正式支持Java17,並且計劃從3.0版本開始,Java版本要求最低是Java17。

為了順應Java及其生態的發展,最近對一套JavaWeb開發框架做了版本升級,主要是Java版本和Springboot版本的升級,包括:

Java版本從openJDK11升級到openJDK17
springboot版本從2.1.11升級到2.7.4
本次升級相比從Java8升級到Java11要簡單很多,基本沒遇到什麼問題。

Java8到Java11之間有Java9這個變化很大的攔路虎,包括但不限於:移除了一些以前集成在jdk的lib中的依賴包,引入模塊化導致某些內部API不可用,類載入機制變化導致一些第三方依賴包版本不兼容,等等。
而從Java11到Java17,中間並沒有Java9那樣巨大的變化,只有Java16和Java17中有一些增強Java內部封裝的新特性,可能會導致底層類庫依賴包的老版本不能兼容Java17。
關於Java8升級Java11的工作,可以參考我以前的文章:

java - Java8升級Java11備忘錄_個人文章 - SegmentFault 思否
另外,本篇文章主要講如何從Java11升級到Java17,以及升級過程中遇到的一些問題。如果想看Java11到Java17有哪些新特性,可以參考我以前的另一片文章:

下塘燒餅:java17相對java11的新特性
二、升級工作內容
升級工作內容大致如下:

2.1 安裝openJDK17及其對應的IDEA
這里選擇的是eclipse的Adoptium社區版本:

OpenJDK17U-jdk_x64_linux_hotspot_17.0.3_7.tar.gz
下載地址:

https://adoptium.net/zh-CN/temurin/archive
更多版本與下載地址請參考文章:

下塘燒餅:java17相對java11的新特性
安裝很簡單,解壓縮到指定目錄即可。

只是開發的話,JAVA_HOME與PATH等環境變數不是一定要設置的,比如我這里的環境有多個JDK版本,只要在IDE中添加新的JDK即可。

IDEA的話,使用2021.2.4以上版本即可支持Java17,在其sdk中加入剛剛安裝好的JDK目錄:

用IDEA任意打開一個java工程,在其Project Structrue -> Platform settings -> SDKs中添加JDK17目錄。

2.2 配置本地Maven
在本地Maven的配置文件中添加新的JDK17的profile,比如我這里的配置文件是/opt/apache-maven-3.5.0/conf/settings.xml,打開並在其中添加:

<profiles> ... <profile> <id>openJDK17</id> <activation> <jdk>17</jdk> </activation> <properties> <JAVA_HOME>/usr/java/jdk-17.0.3+7/</JAVA_HOME> <JAVA_VERSION>17</JAVA_VERSION> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <maven.compiler.compilerVersion>17</maven.compiler.compilerVersion> </properties> <repositories> <repository> <id>XXX-Repository</id> <name>XXX Maven Repository</name> <url>http://maven.xxx/content/groups/public/</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>XXX-Repository</id> <name>XXX Maven Repository</name> <url>http://maven.xxx/content/groups/public/</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> </profile> </profiles>
JAVA_HOME是本地JDK安裝目錄。
repository與pluginRepository用來配置maven倉庫地址,之後在IDE中啟用這里配置的profile。這樣maven拉取jar包時,會優先從這里配置的maven倉庫拉取,拉取不到時再去中央倉庫拉。

配置好settings.xml後,在各個java工程中啟用新的profile:

首先在File -> Settings -> Maven中確定maven及其配置文件目錄:

然後在IDEA的maven插件中選擇jdk17的profile:

2.3 修改父工程的pom版本控制
升級對象是一套JavaWeb開發框架,有自己的父工程來控制依賴包的版本,在決定升級Java版本與Springboot版本後,父工程的pom文件中的相關依賴包版本需要更新。

首先是父工程自己的版本需要升級,這樣仍然依賴老版本父工程的java工程就不會升級相關版本,只有依賴了新版本父工程的java工程才會升級相關版本。

<artifactId>parent-xxx</artifactId> <version>2.0.0</version>
這里假定老版本是1.x.x,新版本是2.0.0。
實際上父工程的pom是在升級過程中不斷修改的,為了不影響使用該父工程的項目開發,你需要與相關開發人員約定好在升級完成後再嘗試使用新版本的父工程。

然後修改基本屬性與spring相關依賴包的版本,篇幅原因這里只給出版本發生變化的依賴包的修改後版本號,dependency配置略過:

<properties> <!-- 基本屬性 --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>17</java.version> <!-- spring相關版本 --> <spring-boot.version>2.7.4</spring-boot.version> <spring-boot-admin.version>2.7.4</spring-boot-admin.version> <spring-cloud.version>2021.0.4</spring-cloud.version> <spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version> <mybatis-spring-boot-starter.version>2.2.2</mybatis-spring-boot-starter.version> <pagehelper-spring-boot-starter.version>1.4.5</pagehelper-spring-boot-starter.version> <!-- 插件版本 --> <spring-boot-maven-plugin.version>2.7.4</spring-boot-maven-plugin.version> <mybatis-generator-maven-plugin.version>1.4.1</mybatis-generator-maven-plugin.version> <!-- 其他依賴包版本 --> <lombok.version>1.18.24</lombok.version> </properties>
升級後的測試並不充分,這里列出的發生版本變化的依賴包可能並不全面。
如果在編譯或運行時發現有某個依賴包報錯,說某個jdk的mole因為沒有導出而無法訪問的錯誤: cannot access class xxx (in mole jdk.xxx) because mole jdk.xxx does not export xxx to xxx,那麼就基本可以確定這個依賴包版本較老不兼容Java17。
解決方法很簡單,在當前這個時間點,基本上所有的第三方依賴包都已經有兼容Java17的較新的版本,直接去maven中央倉庫找一個新版本下載,就能解決問題。
比如上面的lombok版本升級到了1.18.24,就是為了解決編譯時發生的上述不兼容的錯誤。
另外,如果父工程中還約定了很多自用的通用工程的版本,那麼這里需要確保這些通用工程的版本范圍在新老版本中的定義沒有沖突。

例如老版本的父工程中定義了一些通用工程的版本:

<lib-xxx.version>[1.0.0-RELEASE,2.0.0-RELEASE)</lib-xxx.version>
這里的lib-xxx是這套JavaWeb開發框架中的一個通用庫,在老版本的父工程中約定它的版本范圍是[1.0.0-RELEASE,2.0.0-RELEASE),即從1.0.0-RELEASE(包含)到2.0.0-RELEASE(不包含)。那麼新版本的父工程,對它的版本范圍約定就是[2.0.0-RELEASE,3.0.0-RELEASE)。

這樣約定的目的是,如果有一些java工程仍然要使用老版本的父工程(假定由於種種原因,只能用Java11與Springboot2.1.x 。。。),那麼它就不會依賴2.0.0-RELEASE及其以上版本的lib-xxx;而一旦依賴了新版本的父工程,就只會依賴2.0.0-RELEASE及其以上版本的lib-xxx。

最後要注意,如果在老版本(這里就是Java11和Springboot2.1.11)上還有新的應用或需求變更要開發,那麼需要在代碼管理庫中切出一個新的分支來做升級的工作,並約定好各自的版本范圍,比如採用不同的主版本號。
2.4 單個Java工程的版本升級
在前面的2.1到2.3准備工作完成之後,就可以對java應用工程做版本升級了。

首先打開一個java工程,確認maven的目錄與配置文件是否正確,並將maven插件的profile選擇到jdk17,這一步已在步驟2.2中示意。

然後修改工程依賴的父工程版本為2.3中修改後的父工程版本。

<parent> <groupId>xxx</groupId> <artifactId>parent-xxx</artifactId> <version>2.0.0</version> </parent>
然後先使用maven插件刷新pom依賴,順利的話,可以在maven插件中看到新的依賴包版本:

pom依賴刷新之後,再來修改工程的idea配置中的java版本,打開Project Structrue,依次修改或確認java版本:

然後我們就可以對工程進行編譯,檢查有沒有編譯錯誤或警告。

考慮到devops的需要,你可能需要一個maven編譯腳本,要注意java版本,如下所示:

#!/bin/bash export JAVA_HOME=/usr/java/jdk-17.0.3+7 mvn -version mvn clean install package
注意這里指定了JAVA_HOME,maven編譯時會用到這個環境變數,因此指定為JDK17的安裝目錄。本地環境安裝有多個JDK版本時要特別注意這一點。
如果是springboot工程,編譯成功之後就可以啟動服務:

#!/bin/bash JAVA_HOME=/usr/java/jdk-17.0.3+7 JAR_PATH=$(find target -name "*.jar") ${JAVA_HOME}/bin/java -jar "${JAR_PATH}"
2.5 編譯與運行時遇到的問題
在編譯工程以及啟動springboot服務時,可能會遇到以下問題。

2.5.1 JDK模塊內API未導出問題
前面說過,Java16和Java17中有一些增強Java內部封裝的新特性,該特性加強了對一些以前暴露出來但其實很不安全的關鍵API的封裝,即你不再能從外部訪問這些內部API。而java的生態圈中有很多底層的類庫比如lombok在以前的版本中會調用到這些內部API。那麼在Java17以後將不再能調用它們,所以會有不兼容的問題。

這種問題的典型錯誤信息:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project api-brood-base: Fatal error compiling: java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor (in unnamed mole @0x5740ff5e) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in mole jdk.compiler) because mole jdk.compiler does not export com.sun.tools.javac.processing to unnamed mole @0x5740ff5e -> [Help 1]
這里的關鍵信息就是cannot access class xxx (in mole jdk.xxx) because mole jdk.xxx does not export xxx to xxx,一旦看到這句錯誤信息,就知道這是由於JDK加強了內部API的封裝所導致的不兼容問題。

解決起來很簡單,找個新版本就行了。以lombok為例,升級到版本1.18.24即可。

其他類庫的包也有可能出現類似的問題,解決方法一樣,換用更新的兼容Java17的版本即可。

2.5.2 redisTemplate版本不兼容
如果使用了spring的redisTemplate,那麼有可能出現版本不兼容,包括:

redisTemplate.delete方法編譯錯誤,方法參數的泛型發生了變化。
// 版本升級前編譯OK,升級後編譯錯誤 redisTemplate.delete(CollectionUtils.arrayToList(key)); // 版本升級後修改如下 redisTemplate.delete(Arrays.asList(key));
GenericObjectPoolConfig的setMaxWaitMillis被廢棄不再推薦使用,用setMaxWait代替:
GenericObjectPoolConfig<?> genericObjectPoolConfig = new GenericObjectPoolConfig<>(); ... // genericObjectPoolConfig.setMaxWaitMillis(redisProps.getPool().getMaxWait()); genericObjectPoolConfig.setMaxWait(Duration.ofMillis(redisProps.getPool().getMaxWait()));
2.5.3 jackson版本不兼容
spring默認使用的json工具類庫jackson,它的ObjectMapper的enableDefaultTyping被廢棄不再推薦使用,使用activateDefaultTyping代替

具體代碼如下所示:

ObjectMapper om = new ObjectMapper(); // om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
2.5.4 循環依賴問題
springboot的新版本默認不再支持bean的循環依賴,因此項目中有循環依賴的bean的話,會報錯,例如:

The dependencies of some of the beans in the application context form a cycle: xxxxxxxxx ┌─────┐ | xxxService1 (field private com.gcsoft.brood.sentry.service.XxxService2 com.gcsoft.brood.sentry.service.xxxService1.xxxService2) ↑ ↓ | xxxService2 (field private com.gcsoft.brood.sentry.service.XxxService1 com.gcsoft.brood.sentry.service.XxxService2.xxxService1) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
最好的對應方式是消去bean之間的循環依賴,否則就需要顯式聲明允許bean的循環依賴,在application.yml中加入屬性:

spring: main: allow-circular-references: true
2.5.5 缺少spring.config.import配置
如果在pom工程中依賴了springcloud的相關jar,但並沒有使用springcloud相關的config配置,那麼在啟動springboot服務時可能會失敗:

No spring.config.import property has been defined Action: Add a spring.config.import=configserver: property to your configuration. If configuration is not required add spring.config.import=optional:configserver: instead. To disable this check, set spring.cloud.config.enabled=false or spring.cloud.config.import-check.enabled=false.
按照提示,在application.yml中加入屬性:

spring: cloud: config: enabled: false
2.5.6 jetty版本沖突
springboot版本升級後,內嵌的jetty版本也升級了。由於某些第三方jar使用了低版本的jetty的某些包,即使springboot沒有使用jetty,也依然會在運行時發生jetty的不兼容問題:

java.lang.ClassNotFoundException: org.eclipse.jetty.server.RequestLog$Writer
這里可以選擇升級第三方jar。

或者直接去除第三方jar對jetty的依賴:

<dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-jdbc</artifactId> <version>${hive.version}-${cdh.version}</version> <exclusions> <exclusion> <artifactId>jetty-all</artifactId> <groupId>org.eclipse.jetty.aggregate</groupId> </exclusion> </exclusions> </dependency>
2.6 docker鏡像
在各個工程完成升級,編譯成功,並簡單運行OK之後,開始做docker鏡像的升級工作。

畢竟現在都在雲端跑服務了。。。
這里從Docker Hub上找了與開發使用的openJDK版本一致的docker鏡像,也是由eclipse的Adoptium社區提供的。

其實沒有必要,其他openJDK17版本的docker鏡像也是一樣的,單純的強迫症而已。。。
docker pull eclipse-temurin:17.0.3_7-jdk-alpine
對應docker hub地址:

Docker Hub
在這個openJDK17鏡像的基礎上,修改了時區與語言等信息,安裝了bash與telnet,DockerFile如下:

# 指定基礎鏡像,在其上進行定製(這里是 eclipse-temurin:17.0.3_7-jdk-alpine 的鏡像) FROM eclipse-temurin:17.0.3_7-jdk-alpine # 定製環境變數 ENV TIME_ZONE=Asia/Shanghai \ LANG=en_US.UTF-8 \ LANGUAGE=en_US.UTF-8 \ LC_ALL=en_US.UTF-8 # RUN在build鏡像時執行,每RUN一次就會構成一層新的鏡像。 # 因此有多個命令要執行時,用"&&"連接寫在一起。 RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.e.cn/g' /etc/apk/repositories \ && apk add --no-cache tzdata \ && echo "${TIME_ZONE}" > /etc/timezone \ && ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime \ && apk add --no-cache bash bash-doc bash-completion busybox-extras
原始的eclipse-temurin:17.0.3_7-jdk-alpine有335M,添加了tzdata,bash,busybox-extras(telnet)之後,大小是340.8M。。。完整的JDK鏡像就是這么大。。。如果生產環境不需要JDK,那麼可以用JRE作成的鏡像,會小不少,但是缺失了很多JDK工具。
用這個DockerFile做成一個新的openJDK17鏡像,命名為xxx/base-openjdk17:jdk-17.0.3_001,而各個springboot工程的DockerFile如下所示:

# 指定基礎鏡像 FROM xxx/base-openjdk17:jdk-17.0.3_001 # JDK11開始支持: -XX:+UseContainerSupport 使JVM能夠感知容器資源, -XX:InitialRAMPercentage 初期容器內存佔比, -XX:MaxRAMPercentage 最大容器內存佔比 ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:InitialRAMPercentage=50 -XX:MaxRAMPercentage=80" # 復制上下文目錄下的target/*.jar 到容器里 ADD target/*.jar app.jar # 指定容器啟動程序及參數 <ENTRYPOINT> "<CMD>" ENTRYPOINT java ${JAVA_OPTS} -jar /app.jar
該DockerFile位於springboot工程根目錄下。
打進了springboot fat jar的鏡像會變得更大,一般都會有400M以上。。。
三、小結
總的來說,Java11到Java17的升級比較順利,只有少數依賴包對應版本需要升級。另外就是springboot的升級可能導致需要添加少量配置,比如顯式允許bean的循環依賴

Ⅲ java17解壓完成之後呢

解壓完了,解壓文件里有安裝程序,一般就是.exe文件類型,安裝到指定文件夾就可以打開了。java17解壓完怎麼用:
1、第一種方式,打開到bin目錄,下面有java.exe可執行文件,然後打開cmd黑窗口,執行cdjdk/bin文件夾路徑,即可使用java指令。
2、在eclipse或者idea工具中添加jdk路徑可以直接使用。

熱點內容
不支持的壓縮演算法 發布:2024-11-30 00:44:54 瀏覽:901
機加工的編程 發布:2024-11-30 00:31:19 瀏覽:727
坦克世界電腦什麼配置 發布:2024-11-30 00:30:41 瀏覽:317
如何在手機設置上找到網路的密碼 發布:2024-11-30 00:18:29 瀏覽:414
和鷹加密鎖 發布:2024-11-30 00:17:17 瀏覽:556
C語言舞會 發布:2024-11-30 00:15:44 瀏覽:377
java下載我的世界 發布:2024-11-30 00:11:08 瀏覽:12
華三配置器升級失敗怎麼回事 發布:2024-11-30 00:09:23 瀏覽:842
汽車空調壓縮機壽命 發布:2024-11-30 00:06:04 瀏覽:567
電腦網路波動異常與伺服器失去連接 發布:2024-11-29 23:43:19 瀏覽:247