当前位置: 首页 > news >正文

将基于 Oracle JDK 17 开发的 Spring Boot 3.2.12 项目迁移到 OpenJDK 17 环境

将基于 Oracle JDK 17 开发的 Spring Boot 3.2.12 项目迁移到 OpenJDK 17 环境是一个非常直接和常见的过程,因为两者在绝大多数场景下是完全兼容的。Spring Boot 3.2 本身的要求就是 JDK 17+,它并不区分 Oracle JDK 还是 OpenJDK。

你的改造工作主要集中在环境配置、构建工具和依赖管理上,而不是大量的代码修改。

以下是详细的步骤和注意事项:


1. 核心兼容性确认(通常没问题)

首先,最重要的是要明白:OpenJDK 是 Java SE 规范的开源参考实现,而 Oracle JDK 17 及以后版本正是由 OpenJDK 构建而来,并附加了一些非核心的商业功能

从 JDK 11 以后,Oracle JDK 和 OpenJDK 在功能上几乎完全一致,尤其是对于绝大多数应用开发而言。因此,你的代码在编译和运行时几乎不需要任何修改

2. 改造步骤

a. 开发与构建环境 (CI/CD)
  1. 更换 JDK:将你的本地开发机器、测试服务器以及 CI/CD 流水线(如 Jenkins, GitLab CI)上的 JDK 从 Oracle JDK 17 替换为 OpenJDK 17。

    • 下载:可以从多个供应商获取 OpenJDK 17 二进制发行版,推荐选择:

      • Eclipse Temurin (推荐): https://adoptium.net/temurin/releases/

      • Amazon Corretto: https://aws.amazon.com/cn/corretto/

      • Azul Zulu: https://www.azul.com/downloads/

      • Microsoft Build of OpenJDK: https://www.microsoft.com/openjdk

    • 这些发行版都经过了良好的测试,与 Oracle JDK 17 100% 兼容。

  2. 更新构建工具配置

    • Maven:
      确保你的 pom.xml 中的 maven-compiler-plugin 配置的 <source> 和 <target> 都是 17

      xml

      <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><source>17</source><target>17</target><encoding>UTF-8</encoding></configuration>
      </plugin>

      你也可以通过 properties 配置:

      xml

      <properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><maven.compiler.release>17</maven.compiler.release> <!-- 推荐使用 release 参数 -->
      </properties>
    • Gradle:
      在 build.gradle 中确保编译选项正确:

      groovy

      java {sourceCompatibility = '17'targetCompatibility = '17'
      }
b. Docker 化部署(如果适用)

如果你的项目通过 Docker 容器部署,需要将 Dockerfile 中的基础镜像从 Oracle JDK 镜像切换为 OpenJDK 镜像。

  • 之前可能用的 (Oracle JDK):

    dockerfile

    FROM container-registry.oracle.com/java/jdk:17
    ...

    或者一些旧的 oracle/openjdk 镜像(已废弃)。

  • 修改为 (OpenJDK):
    强烈推荐使用 Eclipse Temurin 的镜像

    dockerfile

    FROM eclipse-temurin:17-jdk-jammy
    ...

    或者使用其他供应商的镜像,如:

    dockerfile

    FROM amazoncorretto:17
    ...

    dockerfile

    FROM azul/zulu-openjdk:17
    ...

    对于生产环境,通常建议使用 JRE 而不是完整的 JDK,以减少镜像大小和攻击面:

    dockerfile

    FROM eclipse-temurin:17-jre-jammy
    ...

    注意:从 JDK 17 开始,Oracle 不再提供独立的 JRE 安装包,但大多数 OpenJDK 发行版(如 Temurin)仍然提供基于 JDK 的精简 JRE 镜像。

c. 检查特定依赖和功能

虽然极其罕见,但仍需检查你的项目是否使用了极其小众的、仅限 Oracle JDK 的商业特性

  • Java Flight Recorder (JFR): 在 OpenJDK 17 中,JFR 已经是开源功能!你可以像在 Oracle JDK 中一样使用它。这是最大的一个变化,以前它是商业特性。

  • Java Mission Control (JMC): 虽然 JFR 开源了,但 JMC 工具本身是分开的。你需要从其他渠道获取 compatible 版本的 JMC。

  • 其他商业特性: 如 Jaotc (AOT) 已经被移除,所以基本无需考虑。像 AppCDS 这类功能在 OpenJDK 发行版中通常也是可用的。

如果你的项目没有明确引入这些特性,那么你可以完全忽略这一点。

3. 验证测试

完成上述配置更改后,进行全面的测试是至关重要的。

  1. 本地测试:在安装好 OpenJDK 17 的本地环境中,运行 mvn clean compile 或 gradle compileJava 确保编译通过。

  2. 单元测试:运行 mvn test 或 gradle test,确保所有单元测试通过。

  3. 集成测试/功能测试:启动应用,进行完整的端到端测试,确保所有核心功能正常。

  4. 性能测试(可选):如果你对性能有极致要求,可以进行简单的压测,对比在 OpenJDK 和 Oracle JDK 下的表现。但对于绝大多数应用,性能差异可以忽略不计。

总结

方面改造动作
JDK 安装包将 Oracle JDK 17 替换为 OpenJDK 17 发行版(如 Eclipse Temurin 17)
构建配置确认 Maven/Gradle 的编译级别为 17
Docker 镜像将基础镜像从 Oracle JDK 镜像改为 eclipse-temurin:17-jdk-jammy 或 eclipse-temurin:17-jre-jammy
特性依赖(基本无需操作) 检查是否依赖极少数已不再受限的商业功能(大概率没有)
测试进行全面测试:编译、单元测试、功能测试

总而言之,这个迁移过程非常平滑,90% 的工作就是更换 JDK 安装包和 Docker 镜像,剩下的 10% 是充分的测试。 你可以自信地进行操作。

1. 核心 javax 包 vs. Java EE javax 包

首先要区分两种 javax 包:

  • 核心 javax 包:例如 javax.swing (GUI工具包), javax.sql (数据库连接), javax.security (安全相关) 等。这些是 Java SE 平台的一部分,在 OpenJDK 17 中仍然存在

  • Java EE / Jakarta EE javax 包:例如 javax.servletjavax.persistence (JPA), javax.annotation (如 @PostConstruct), javax.ejbjavax.xml.bind (JAXB) 等。这些原本是 Java 企业版平台的一部分。

2. 关键变化:JDK 9 的模块化 (JEP 320)

从 JDK 9 开始,Oracle 和 OpenJDK 社区通过 JEP 320 决定了一项重要变更:将 Java EE 和 CORBA 模块从 JDK 中移除

这意味着:

  • 在 JDK 8 中:这些 Java EE 的 javax 包是 随 JDK 一起分发 的。

  • 在 JDK 9+(包括 JDK 17)中:这些 Java EE 的 javax 包 不再随 JDK 一起分发。如果你需要使用这些功能,你必须像添加其他第三方库一样,手动地将它们作为依赖项添加到你的项目中

3. 这对 Spring Boot 3.2.12 项目意味着什么?

Spring Boot 3 是基于 Jakarta EE 9+ 的,这是一个关键信息!

  • 命名空间迁移:Jakarta EE 9 进行了一个重大的更名,将所有 javax.* 包名都改为了 jakarta.*

    • 例如:javax.servlet -> jakarta.servlet

    • javax.persistence -> jakarta.persistence

  • Spring Boot 自动配置:Spring Boot starter(如 spring-boot-starter-web)已经为你自动处理了这些依赖。当你引入 spring-boot-starter-web 时,它会自动拉取正确版本的 Jakarta Servlet API (jakarta.servlet:jakarta.servlet-api),你不需要再手动担心 javax.servlet 的问题。

结论与操作指南

  1. OpenJDK 17 有 javax 包吗?

    • :核心的 javax 包(如 javax.swingjavax.sql)是存在的。

    • 没有:企业级的 javax 包(如 javax.servlet)已从 JDK 中移除。

  2. 你的 Spring Boot 3.2.12 项目需要做什么?

    • 代码中的 import 语句:检查你的代码。由于你使用的是 Spring Boot 3,所有之前对 javax.* (EE) 的导入都应该已经被改为 jakarta.* 了。这是升级到 Spring Boot 3 的必要步骤。如果你的代码里还有 import javax.servlet...,那说明项目没有正确升级,需要改为 import jakarta.servlet...

    • 项目依赖:确保你的 pom.xml 或 build.gradle 中的依赖都是正确的 Spring Boot 3 starters。Spring Boot 会帮你管理所有 Jakarta EE 依赖。你不需要也不应该手动添加旧的 javax 依赖(如 javax.servlet:javax.servlet-api)。

  3. 如果遇到 ClassNotFoundException 或 NoClassDefFoundError 怎么办?
    这通常意味着你的某个依赖项还在尝试使用旧的 javax EE 包。你需要:

    • 升级这个依赖到与 Jakarta EE 9+ 兼容的版本。

    • 或者,如果这个依赖没有新版本,你可以尝试添加一个适配器库(例如 org.eclipse.ee4j:jakartaee-api),但这是一个临时方案,最好还是寻找替代依赖。

总结表格:

包类型示例OpenJDK 17 中是否存在?在 Spring Boot 3 中如何获取?
核心 javaxjavax.swingjavax.sql (JDK 内置)JDK 自带,无需处理
Java EE javaxjavax.servletjavax.persistence (已从 JDK 移除)已过时,应使用对应的 jakarta.* 包
Jakarta EEjakarta.servletjakarta.persistence (独立规范)通过 Spring Boot Starters 自动引入

因此,对于你的迁移,无需担心 javax 包的问题。你只需要确保项目正确使用了 jakarta.* 命名空间,并且依赖管理正确,OpenJDK 17 就能完美运行。

📦 javax.sql 包的核心成员

javax.sql 包从 JDK 1.4 开始就成为了 Java SE 平台的一部分,提供了许多用于访问和处理服务器端数据源的关键 API。

为了让你快速了解 javax.sql 包的核心内容,我整理了下面的表格:

类别主要接口/类说明
核心接口DataSource替代 DriverManager 建立连接的工厂,是获取连接的首选方式。
连接池ConnectionPoolDataSourcePooledConnection支持连接池和语句池,可以显著提升性能。
分布式事务XADataSourceXAConnection支持分布式事务,允许在单个事务中涉及多个服务器上的数据源。
行集 (Rowsets)RowSetRowSetMetaData提供更灵活的方式来处理结果集,尤其适用于断开连接的环境。

🔄 与 Oracle JDK 的兼容性

在 javax.sql.DataSource 这个问题上,OpenJDK 17 和 Oracle JDK 17 的行为是完全一致的。两者都包含了标准的 javax.sql 包。
![[Pasted image 20240909092144.png]]
这意味着:

  • 你的代码无需修改:所有依赖于 javax.sql.DataSource 的代码在 OpenJDK 17 上都能正常运行。

  • 依赖关系不变:你不需要额外引入任何 JAR 包来弥补 JDK 本身的缺失。

⚠️ 注意事项:实现与使用

虽然接口是标准化的,但需要注意以下几点:

  1. JDK 提供接口,而非实现:JDK 自带的 javax.sql.DataSource 只是一个接口,不是具体的实现。你需要通过第三方库(如 HikariCPApache Commons DBCPTomcat JDBC Pool 等)来获得实际的、功能完备的数据源和连接池实现。应用服务器(如 Tomcat, WildFly 等)通常会为你集成这些实现。

  2. Spring Boot 的自动配置:如果你在使用 Spring Boot,它通常会自动配置一个高性能的连接池(如 HikariCP)。你只需要在 application.properties 或 application.yml 中配置数据库连接字符串、用户名、密码等属性即可,Spring Boot 会帮你创建和管理实际的 DataSource 实例。

💡 总结

  • 你可以放心地在 OpenJDK 17 中使用 javax.sql.DataSource,其行为与 Oracle JDK 17 无任何差异。

  • 你看到的这个接口是 Java SE 的标准 API,并非来自 Java EE/Jakarta EE。

  • 在实际项目中,你通常会通过配置第三方连接池库(或由 Spring Boot 等框架自动配置)来获得这个接口的具体实现。


文章转载自:

http://EXLOEtsA.jfbgn.cn
http://bhANYshP.jfbgn.cn
http://kpSZuD9b.jfbgn.cn
http://Hw4GqQEW.jfbgn.cn
http://Ngf3KvRX.jfbgn.cn
http://pmmifUhT.jfbgn.cn
http://E4AMPUCV.jfbgn.cn
http://aUfSWHq3.jfbgn.cn
http://BpjsTUUU.jfbgn.cn
http://LDXzTOa6.jfbgn.cn
http://SyGJ0BLG.jfbgn.cn
http://qGDIGZZw.jfbgn.cn
http://GCp7TVUJ.jfbgn.cn
http://9nW5vB43.jfbgn.cn
http://378BCJQV.jfbgn.cn
http://u9Nd4V9E.jfbgn.cn
http://RFOiV0c0.jfbgn.cn
http://D9ciufzh.jfbgn.cn
http://QWheCsj4.jfbgn.cn
http://cc6boEIw.jfbgn.cn
http://GfkZhyEU.jfbgn.cn
http://k1yHVc9M.jfbgn.cn
http://GCwqh4en.jfbgn.cn
http://Uu1EXJtn.jfbgn.cn
http://jrQWKpRq.jfbgn.cn
http://X4BXQ367.jfbgn.cn
http://YshVfBJo.jfbgn.cn
http://PtZqpzCp.jfbgn.cn
http://GCVsVy6V.jfbgn.cn
http://6i39SXAj.jfbgn.cn
http://www.dtcms.com/a/372860.html

相关文章:

  • Vue的计算属性
  • Redis 非缓存核心场景及实例说明
  • 食品罐头(铝罐)表面缺陷数据集:8k+图像,4类,yolo标注
  • 云计算系统安全
  • 微信群机器人-备份文件发送通知
  • Linux-条件变量
  • 6.python——字符串
  • 懒汉式——LazyMan(任务队列应用)
  • Nginx 实战系列(四)—— Nginx反向代理与负载均衡实战指南
  • Nginx 反向代理 + Tomcat 集群:负载均衡配置步骤与核心原理
  • 【Linux】匿名管道和进程池
  • PWA:打造媲美 Native Apps 的 Web 应用体验
  • # 小程序 Web 登录流程完整解析
  • 2025中国AI HR市场深度洞察:趋势、厂商与未来展望
  • 并发编程的守护者:信号量与日志策略模式解析
  • Flink Task线程处理模型:Mailbox
  • ActiveMQ classic ,artemis ,artemis console ,nms clients,cms client详解
  • 【论文阅读】Far3D: Expanding the Horizon for Surround-view 3D Object Detection
  • Three.js使用outlinePass描边后,描边颜色和背景叠加变淡
  • GPT系列--类GPT2源码剖析
  • 反编译分析C#闭包
  • DTO与POJO:核心差异与最佳实践
  • #C语言——刷题攻略:牛客编程入门训练(九):攻克 分支控制(三)、循环控制(一),轻松拿捏!
  • Android 中 自定义 RecyclerView 控件限制显示高度
  • Codesy中的UDP发送信息
  • Hadoop进程:深入理解分布式计算引擎的核心机制
  • SQL Server死锁排查实战指南
  • 自学嵌入式第三十八天:数据库
  • 【开题答辩全过程】以 基于springboot的酒店管理系统设计与实现为例,包含答辩的问题和答案
  • SpringBoot控制层接收参数处理、Logback日志入门和使用