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

2.5 模块化迁移策略:从传统项目到模块化系统


模块化迁移策略:从传统项目到模块化系统

将传统 Java 项目迁移至 JDK 9 模块化系统是一项系统性工程,需分阶段实施以降低风险。以下是详细的迁移策略、工具使用和实战示例。


1. 迁移阶段划分
阶段目标关键操作
阶段1:兼容性验证确保项目能在 JDK 9 上无模块化运行使用类路径运行,处理废弃 API 和依赖冲突
阶段2:模块化试点部分代码转为模块,依赖自动模块(非模块化 JAR)创建 module-info.java,逐步迁移核心模块
阶段3:完整模块化全项目模块化,显式管理所有依赖重构模块结构,移除自动模块依赖

2. 阶段1:兼容性验证
目标

在不修改代码的情况下,验证项目在 JDK 9 上的运行能力。

关键步骤
  1. 编译与运行测试

    javac -d out -classpath lib/*.jar src/**/*.java  
    java -classpath out:lib/*.jar com.example.Main  
    
  2. 处理兼容性问题

    • 废弃 API 检测
      jdeprscan --release 9 myapp.jar  
      
    • 内部 API 访问
      • 错误示例sun.misc.BASE64Encoder 不可访问。
      • 修复方案:替换为标准 API(java.util.Base64)。
  3. 依赖冲突排查

    • 工具:使用 jdeps 分析依赖树:
      jdeps --class-path lib/*.jar -recursive myapp.jar  
      

3. 阶段2:模块化试点
目标

将部分代码转换为模块,依赖未模块化的第三方库作为自动模块。

关键步骤
  1. 创建初始模块

    • 选择核心模块(如 com.utils),添加 module-info.java
      module com.utils {  exports com.utils;  requires transitive org.apache.commons.lang3; // 自动模块名:commons.lang3  
      }  
      
  2. 模块化编译与运行

    javac -d out --module-source-path src --module com.utils  
    java --module-path out:lib -m com.utils/com.example.Main  
    
  3. 处理自动模块依赖

    • 自动模块命名规则
      • JAR 文件名 log4j-api-2.17.1.jar → 模块名 log4j.api
    • 依赖传递:自动模块默认依赖所有模块,但需显式声明核心 JDK 模块。

4. 阶段3:完整模块化
目标

全项目模块化,显式管理所有依赖(包括第三方库)。

关键步骤
  1. 重构模块结构

    • 模块拆分:按功能拆分模块(如 com.usercom.order)。
    • 模块描述符:为每个模块编写 module-info.java
  2. 处理第三方库

    • 方案1:等待库官方提供模块化版本(如 Log4j 2.17+)。
    • 方案2:手动为库添加模块描述符(生成 module-info.java)。
  3. 显式依赖管理

    module com.myapp {  requires java.sql;  requires com.utils;  requires org.apache.logging.log4j; // 显式声明 Log4j 模块  
    }  
    
  4. 生成定制化 JRE

    jlink --module-path $JAVA_HOME/jmods:mods \  --add-modules com.myapp,java.sql \  --output myapp-runtime  
    

5. 迁移工具链
工具用途示例命令
jdeps分析依赖关系和模块兼容性jdeps --generate-module-info ./out myapp.jar
jdeprscan检测废弃 API 使用jdeprscan --release 9 myapp.jar
jlink生成最小化 JREjlink --add-modules java.base...
jmod创建 JMOD 文件(可选)jmod create --class-path ...

6. 常见问题与解决方案
问题解决方案
模块依赖未找到检查 requires 声明,确保依赖模块在模块路径中,或添加 --add-modules <模块名>
反射访问失败(如 Hibernate)使用 opens 开放包权限:opens com.myapp.model to org.hibernate
自动模块名冲突重命名 JAR 文件(如 my-lib-1.0.jarmylib.jar)以生成唯一模块名。
性能下降检查垃圾回收配置(如 -XX:+UseG1GC),优化模块依赖减少加载时间。

7. 迁移最佳实践
  1. 分阶段实施
    • 先迁移底层工具模块,再逐步向上层业务模块推进。
  2. 自动化测试
    • 在每个阶段运行单元测试和集成测试(如 JUnit + CI/CD)。
  3. 依赖管理
    • 优先选择已适配 JDK 9 的第三方库(如 Spring 5、Hibernate 5.3+)。
  4. 文档与协作
    • 维护模块依赖图和迁移日志,与团队共享知识。

8. 实战示例:迁移 Spring Boot 应用
步骤1:兼容性验证
  • 处理问题
    • 替换 javax.xml.bind(JDK 9 中已移除)为第三方实现(如 org.glassfish.jaxb)。
    • 添加 --add-opens 参数开放反射权限:
      java --add-opens java.base/java.lang=ALL-UNNAMED -jar myapp.jar  
      
步骤2:模块化核心组件
  • 模块描述符
    module com.myapp.core {  requires spring.boot;  requires spring.context;  opens com.myapp.model to spring.core; // 允许 Spring 反射扫描  
    }  
    
步骤3:生成定制化 JRE
jlink --module-path $JAVA_HOME/jmods:mods \  --add-modules com.myapp.core,java.sql \  --output springboot-runtime  

9. 总结

模块化迁移需结合工具链、分阶段策略和严格测试,核心在于渐进式重构显式依赖管理。通过模块化,项目将获得更强的封装性、更清晰的架构和更高效的运行时,为后续技术演进(如云原生、微服务)奠定基础。

相关文章:

2.5 模块化迁移策略:从传统项目到模块化系统

模块化迁移策略&#xff1a;从传统项目到模块化系统 将传统 Java 项目迁移至 JDK 9 模块化系统是一项系统性工程&#xff0c;需分阶段实施以降低风险。以下是详细的迁移策略、工具使用和实战示例。 1. 迁移阶段划分 阶段目标关键操作阶段1&#xff1a;兼容性验证确保项目能在…...

java商城解决方案

数字化时代&#xff0c;电子商务已成为企业拓展市场的重要渠道。对于想要建立在线商店的企业来说&#xff0c;选择正确的技术堆栈至关重要。 Java作为一种成熟且广泛使用的编程语言&#xff0c;为构建购物中心提供了强大的功能和灵活性。 商城Java源码&#xff1a;商城开发的核…...

算法-哈希表篇05-四数相加II

四数相加II 力扣题目链接 题目描述 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 < i, j, k, l < n nums1[i] nums2[j] nums3[k] nums4[l] 0 解题思路 把数…...

WPS或word接入智能AI

DeepSeek接入WPS 配置WPS &#xff08;1&#xff09;下载 OfficeAl助手插件: 插件下载地址:https://www.office-ai.cn/。 安装插件后&#xff0c;打开WPS&#xff0c;菜单栏会新增"OfficeAl助手”选项卡。 如果没有出现&#xff0c; 左上找到文件菜单 -> 选项 ,在…...

Leetcode:学习记录

一、滑动窗口 1. 找出数组中元素和大于给定值的子数组的最小长度 右指针从左到右遍历&#xff0c;在每个右指针下&#xff0c;如果去掉左边元素的元素和大于等于给定值则左指针右移一次&#xff0c;直到小于给定值&#xff0c;右指针右移一个。 2.找到乘积小于给定值的子数组…...

86.在 Vue 3 中使用 OpenLayers 自定义组件(放大、缩小、长度测量、面积测量)

摘要 在 WebGIS 开发中&#xff0c;OpenLayers 是一个非常强大的开源地图库&#xff0c;它可以在 Web 应用中渲染高效的地图。本篇文章将介绍如何在 Vue 3 中使用 OpenLayers&#xff0c;并封装一个自定义地图控件组件&#xff0c;实现地图的放大、缩小、长度测量和面积测量功能…...

http 与 https 的区别?

HTTP(超文本传输协议)和 HTTPS(安全超文本传输协议)是互联网通信的基础协议。随着网络技术的发展和安全需求的提升,HTTPS变得越来越重要。本文将深入探讨HTTP与HTTPS之间的区别,包括其工作原理、安全性、性能、应用场景及未来发展等。 1. HTTP与HTTPS的基本概念 1.1 HT…...

SAIL-RK3576单板运行7b的deepseek对话模型

大概流程&#xff1a; 使用ollama工具进行deepseek的模型部署和使用&#xff0c;先安装ollama工具&#xff0c;在使用ollama工具拉去deepseek模型&#xff0c;最后使用ollama工具加载deepseek模型进行对话...

独立C++ asio库实现的UDP Server

以下是一个使用独立的 C Asio 库实现的 UDP 服务器的示例代码。这个 UDP 服务器可以监听指定端口&#xff0c;接收客户端发送的数据&#xff0c;并将接收到的数据原样返回给客户端。 #include <iostream> #include <asio.hpp> #include <array>class UdpSer…...

SQL Server STUFF 函数的用法及应用场景

在 SQL Server 中&#xff0c;STUFF 函数是一种强大的字符串处理工具&#xff0c;常用于删除指定位置的字符并插入新的字符。通过这个函数&#xff0c;开发者能够灵活地修改字符串&#xff0c;从而在数据处理、字符串拼接和格式化等方面大显身手。本文将深入探讨 STUFF 函数的语…...

MongoDB进阶篇-索引

文章目录 1. 索引概述 2. 索引的类型 2.1 单字段索引 2.2 复合索引 2.3 其他索引 2.3.1 地理空间索引(Geospatial Index) 2.3.2 文本索引(Text Indexes) 2.3.3 哈希索引(Hashed Indexes) 3. 索引相关操作 3.1 查看索引 3.2 创建索引 3.3.1 创建单字段索引 3.3.2 创建复合…...

《机器学习数学基础》补充资料:柯西—施瓦茨不等式以及相关证明

《机器学习数学基础》 153 页&#xff0c;针对图 3-4-3&#xff0c;提出了一个问题&#xff1a;“点 A A A 到 W \mathbb{W} W 上的一个点的距离有无穷多个。现在&#xff0c;我们最关心的是其中最短的那个&#xff0c;怎么找&#xff1f;请参阅 3.6 节。”并且&#xff0c;在…...

VisionPro 划痕检测小练习

划痕检测,我这里用到的是Sobel算子和blob斑点匹配以及blob里面的形态学调整 Sobel 是一种在数字图像处理和计算机视觉领域广泛应用的算法&#xff0c;主要用于边缘检测 脚本展示 #region namespace imports using System; using System.Collections; using System.Drawing; …...

解析 2025 工业边缘计算:三大技术风向的影响力

工业数字化转型的加速&#xff0c;工业边缘计算市场正呈现出蓬勃发展的态势。展望 2025 年&#xff0c;以下三大技术将成为引领工业边缘计算发展的重要风向标。 其一&#xff0c;人工智能与边缘计算的深度融合。人工智能技术将更广泛地应用于工业边缘设备&#xff0c;实现更智…...

企语企业管理系iFair(F23.2_a0)在Debian操作系统中的安装

起因&#xff1a;在安装了F24.8版本后&#xff0c;发现生产用环境和测试、开发用环境还是分开的好。 旧版的用来实验、测试&#xff0c;新版的一步一步小心的配置、使用是比较稳妥的操作。因此&#xff0c;决定在KVM虚拟机上搭建一个F23.2版本的企语系统。 一、 存在的问题 而…...

如何在Flask中处理静态文件

哈喽,大家好,我是木头左! 本文将详细介绍如何在Flask中处理静态文件,包括如何配置静态文件夹、如何访问静态文件以及如何处理静态文件的缓存问题。 配置静态文件夹 在Flask中,你可以通过static_folder参数来指定静态文件夹。默认情况下,Flask会在项目的根目录下寻找名为…...

无人机飞行试验大纲

‌无人机飞行试验大纲‌ ‌编制日期‌&#xff1a;2025年02月11日 ‌一、试验目的与背景‌ 本次无人机飞行试验旨在验证无人机的飞行性能、控制系统稳定性、机体结构强度以及各项任务执行能力。随着无人机技术在各个领域的广泛应用&#xff0c;对其性能进行全面、系统的测试显得…...

C语言初阶牛客网刷题——JZ65 不用加减乘除做加法】【难度:简单】

1. 题目描述 牛客网OJ题链接 写一个函数&#xff0c;求两个整数之和&#xff0c;要求在函数体内不得使用、-、*、/四则运算符号。 2. 分析 十进制相加思想&#xff1a; 157 &#xff0c; 先计算不考虑进位的相加结果 12 &#xff08;因为 57 的不考虑进位的结果是 2 &#x…...

git 记录

git 记录 报错warning: unknown value given to http.version: 2 报错 warning: unknown value given to http.version: ‘2’ 删除指定http版本 git config --global --unset http.version...

PyTorch Lightning Trainer介绍

PyTorch Lightning 的 Trainer 是框架的核心类&#xff0c;负责自动化训练流程、分布式训练、日志记录、模型保存等复杂操作。通过配置参数即可快速实现高效训练&#xff0c;无需手动编写循环代码。以下是详细介绍和使用示例&#xff1a; Trainer 的核心功能 自动化训练循环 自…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...