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. 总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/968630.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

cv2小练习

基础概念 帧率是指在单位时间内&#xff0c;显示的图像帧数的数量。它是衡量视频或动画流畅度的一个重要指标。帧率的单位通常是每秒帧数&#xff08;Frames Per Second&#xff0c;简称FPS&#xff09;。在数字视频和计算机图形领域&#xff0c;帧率是决定视频播放质量和流畅度…

在Mac arm架构终端中运行 corepack enable yarn 命令,安装yarn

文章目录 1. 什么是 Corepack&#xff1f;2. 运行 corepack enable yarn 的作用3. 如何运行 corepack enable yarn4. 可能遇到的问题及解决方法问题 1&#xff1a;corepack 命令未找到问题 2&#xff1a;Yarn 未正确安装问题 3&#xff1a;权限问题 5. 验证 Yarn 是否启用成功6…

Spring基于文心一言API使用的大模型

有时做项目我们可能会遇到要在项目中对接AI大模型 本篇文章是对使用文心一言大模型的使用总结 前置任务 在百度智能云开放平台中注册成为开发者 百度智能云开放平台 进入百度智能云官网进行登录&#xff0c;点击立即体验 点击千帆大模型平台 向下滑动&#xff0c;进入到模型…

【Vue中BUG解决】npm error path git

报错内容如下&#xff1a; 从错误信息可知&#xff0c;这是一个 ENOENT&#xff08;No Entry&#xff0c;即找不到文件或目录&#xff09;错误&#xff0c;并且与 git 相关。具体来说&#xff0c;npm 在尝试调用 git 时&#xff0c;无法找到 git 可执行文件&#xff0c;下面为…

(一)Axure制作移动端登录页面

你知道如何利用Axure制作移动端登录页面吗&#xff1f;Axure除了可以制作Web端页面&#xff0c;移动端也是可以的哦&#xff0c;下面我们就一起来看一下Axure制作移动端登录页面的过程吧。 第一步&#xff1a;从元件中拖入一个矩形框&#xff0c;并设置其尺寸为&#xff1a;37…

自动化遇到的问题记录(遇到问题就更)

总结回归下自己这边遇到的一些问题 “EOF错误”&#xff0c;获取不到csv里面的内容 跑多csv文件里的场景&#xff0c;部分场景的请求值为 1、检查csv文件里不能直接是[]开头的参数&#xff0c;把[]改到ms平台的请求参数里 2、有时可能是某个参数值缺了双引号的其中一边 met…

LabVIEW软件需求开发文档参考

在项目开发的工作历程中&#xff0c;精准把握项目需求无疑是成功打造整个项目的首要关键步骤&#xff0c;同时也是一个至关重要且不可忽视的核心环节。明确且详尽的项目需求就如同建筑的基石&#xff0c;为后续的设计、开发、测试等一系列工作提供了坚实的支撑和清晰的指引。倘…

【JVM详解五】JVM性能调优

示例&#xff1a; 配置JVM参数运行 #前台运行 java -XX:MetaspaceSize-128m -XX:MaxMetaspaceSize-128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio8 - XX:UseConcMarkSweepGC -jar /jar包路径 #后台运行 nohup java -XX:MetaspaceSize-128m -XX:MaxMetaspaceS…

android studio下载安装汉化-Flutter安装

1、下载android studio官方地址&#xff1a;&#xff08;这个网址可能直接打不开&#xff0c;需要VPN&#xff09; https://developer.android.com/studio?hlzh-cn mac版本分为X86和arm版本&#xff0c;电脑显示芯片是Inter的就是x86的&#xff0c;显示m1和m2的就是arm的 …

(2025)深度分析DeepSeek-R1开源的6种蒸馏模型之间的逻辑处理和编写代码能力区别以及配置要求,并与ChatGPT进行对比(附本地部署教程)

(2025)通过Ollama光速部署本地DeepSeek-R1模型(支持Windows10/11)_deepseek猫娘咒语-CSDN博客文章浏览阅读1k次&#xff0c;点赞19次&#xff0c;收藏9次。通过Ollama光速部署本地DeepSeek-R1(支持Windows10/11)_deepseek猫娘咒语https://blog.csdn.net/m0_70478643/article/de…

【深度学习入门实战】基于Keras的手写数字识别实战(附完整可视化分析)

​ 本人主页:机器学习司猫白 ok,话不多说,我们进入正题吧 项目概述 本案例使用经典的MNIST手写数字数据集,通过Keras构建全连接神经网络,实现0-9数字的分类识别。文章将包含: 关键概念图解完整实现代码训练过程可视化模型效果深度分析环境准备 import numpy as np impo…

kafka生产端之架构及工作原理

文章目录 整体架构元数据更新 整体架构 消息在真正发往Kafka之前&#xff0c;有可能需要经历拦截器&#xff08;Interceptor&#xff09;、序列化器&#xff08;Serializer&#xff09;和分区器&#xff08;Partitioner&#xff09;等一系列的作用&#xff0c;那么在此之后又会…

docker compose部署flink集群

本次部署2个jobmanager和3个taskmanager 一、部署zookeeper集群 flink使用zookeeper用作高可用 部署集群参考&#xff1a;docker compose部署zookeeper集群-CSDN博客 二、创建目录及配置文件 创建timezone文件&#xff0c;内容填写Asia/Shanghai 手动创建目录&#xff1a…

3dtiles——Cesium ion for Autodesk Revit Add-In插件

一、说明&#xff1a; Cesium已经支持3dtiles的模型格式转换&#xff1b; 可以从Cesium官方Aesset中上传gltf等格式文件转换为3dtiles&#xff1b; 也可以下载插件&#xff08;例如revit-cesium插件&#xff09;转换并自动上传到Cesium官方Aseet中。 Revit转3dtiles插件使用…

html文件怎么转换成pdf文件,2025最新教程

将HTML文件转换成PDF文件&#xff0c;可以采取以下几种方法&#xff1a; 一、使用浏览器内置功能 打开HTML文件&#xff1a;在Chrome、Firefox、IE等浏览器中打开需要转换的HTML文件。打印对话框&#xff1a;按下CtrlP&#xff08;Windows&#xff09;或CommandP&#xff08;M…

Linux(socket网络编程)TCP连接

Linux&#xff08;socket网络编程&#xff09;TCP连接 基础文件目录函数系统进程控制函数fork()exec系列函数void abort(void)void assert(int expression)void exit(int status)void _exit(int status)int atexit(void (*func)(void))int on_exit(void (*function)(int,void*)…

GeekPad智慧屏编程控制(二)

前面已经实现了智慧屏开关的控制了&#xff0c;接下来再继续实现消息的订阅。 先如下图所示增加几个控件&#xff0c;一个按钮&#xff0c;2个文本框&#xff0c;其中右下角的文本框显示的内容会比较多&#xff0c;需要打开多行和右侧滚动条。 然后添加订阅消息的事件&#xf…

Postgresql 开发环境搭建指南(WindowsLinux)

一、Postgresql 简介 PostgreSQL 是一个免费的对象-关系数据库服务器(ORDBMS)&#xff0c;在灵活的BSD许可证下发行。 RDBMS 是关系数据库管理系统&#xff0c;是建立实体之间的联系&#xff0c;最后得到的是关系表。 ORDBMS在原来关系数据库的基础上&#xff0c;增加了一些新…

设备智能化无线通信,ESP32-C2物联网方案,小尺寸芯片实现大功能

在科技飞速发展的当下&#xff0c;我们的生活正被各类智能设备悄然改变&#xff0c;它们如同一位位无声的助手&#xff0c;渗透到我们生活的每一个角落&#xff0c;让生活变得更加便捷和丰富多彩。 智能插座、智能照明和简单家电设备在家居领域的应用&#xff0c;为我们的生活…

Unity 编辑器热更C# FastScriptReload

工具源码&#xff1a;https://github.com/handzlikchris/FastScriptReload 介绍 用于运行时修改C#后能快速重新编译C#并生效&#xff0c;避免每次改C#&#xff0c;unity全部代码重新编译&#xff0c;耗时旧且需要重启游戏。 使用 需要手动调整AssetPipeline自动刷新模式&…