实战演练JDK的模块化机制
实战演练JDK的模块化机制
--楼兰带你聊最纯粹的Java
你发任你发,我用Java8。你用的JDK到什么版本了?很多开源框架都已经开始陆续升级JDK版本了。你对于JDK8往后陆陆续续更新的这些版本有什么感觉吗?
很多人会说其实并没有太多的感觉。JDK的新版本不断推出一些不痛不痒的新特性,但是基于JDK向下兼容的设计,只要我不关注这些花里胡哨的新特性,那么不管哪个版本的JDK,我都可以当做JDK8来用。
但是,其实,从JDK8往后,有一个机制,你是不得不了解的。因为这个机制,如果在你的项目中不启用还好。一旦启用了,会让你所有的业务代码必须进行一次脱胎换骨的变化。这个机制,就是自JDK9之后的模块化机制JPMS。
一、什么是模块化?
我们写的Java应用,都是以Jar包的形式发布的,所以对于Jar包,你一定习以为常。但是,如果你有一天打开一下JDK9以后的版本在你本地的安装目录,你会发现,JDK中那些熟悉的jar包,完全不见了。取而代之的是一些jmod文件。

甚至在熟悉的IDEA里,JDK的包下也不再是一个个Jar包,而变成了一个个与这些jmod文件对应的模块。

这些jmod文件是什么呢?
其实这些jmod文件可以认为是一种特殊的jar包。JMOD设计为在编译时间和链接时间使用,但不在运行时使用。你可以简单的理解为,这些jmod文件像jar包一样打包了class文件。但是你不能用java -cp或者java -m等机制使用这些jmod文件。
这就是Java的模块化机制的根基。从JDK8之后,整个JDK就已经用模块化的方式进行了重组。例如,安装JDK 17后,可以使用java --list-modules查看所有的系统模块。

甚至,JDK和JRE的关系,也已经发生了变化。在新版本的JDK中,应用程序可以只选择自己所需要的模块,打造一个自己定制的JRE,而不再需要引入JDK庞大的后台功能。
比如,我们如果只需要使用java.base模块中的一些基本功能,那么随时可以用以下指令打包出一个可以在服务器上运行的JRE:
jlink -p $JAVA_HOME/jmods --add-modules java.base --output basejre
这个basejre就可以像安装JDK一样,部署到服务器上运行。也可以基于这个JRE,运行Java程序。只不过,这个JRE中只包含了java.base模块中的这些类。像JDBC这样的其他模块的功能,就没法使用。
二、实战理解jmod
这种模块化机制既然是从JDK底层开始推出的,那么自然也可以运用到开发过程中。只不过,这种模块化机制对于很多传统的项目来说,还是有很多问题。因此,在应用中并没有严格铺开。
例如,你可以找一个现有的项目,将JDK版本升级到17后,就可以在项目中某个模块的classpath下添加个module-info.java文件。

但是,只要你在一个模块中添加了这个module-info.java文件。那么很多代码的编译过程,大概率就会出问题。这就是因为一旦启用了模块化机制,那么就需要对模块进行一些完整声明,保证所有应用都是一些独立,且边界明显的模块,而不再是一些零散的jar包了。
这个模块化机制怎么玩呢?接下来楼兰就带你简单玩一玩。
1、声明一个module
引入模块化机制后,应用㤇在每个模块的根目录下创建一个module-info.java文件,用来声明一个模块。在这个文件中,用module关键字,声明了一个模块。例如:
module roy.demomodule{
}
这样,当前目录下的所有package下 de代码,都将属于同一个module。module的名字必须全局唯一。至于具体的格式,没有强制要求。不过通常的惯例是类似于包结构,全部用小写,多个单词用.连接。
接下来就需要再roy.module中声明module的一些补充信息。这些补充信息主要包括:
- 对其他module的依赖关系
- 当前module对外开放的API
- 使用和提供的服务
2、require 声明module依赖
在module-info.java中首先要声明当前module需要依赖哪些外部模块。比如,如果你要使用junit,那么除了要在pom.xml中引入junit对应的依赖外,还需要在module-info.java中添加配置,否则项目编译就会报错。
requires requires junit;
这里要注意,对于显式声明了module-info.java的模块来说,模块名是显而易见的。但是对于没有声明module-info.java的非模块化jar包来说,默认就会创建具有jar包名称的模块。而这个名称还去掉版本号之后的标准包名。
比如,在demoModule1中,我引入了如下的junit依赖
<dependency>相关文章:
实战演练JDK的模块化机制
实战演练JDK的模块化机制--楼兰 带你聊最纯粹的Java 你发任你发,我用Java8。你用的JDK到什么版本了?很多开源框架都已经开始陆续升级JDK版本了。你对于JDK8往后陆陆续续更新的这些版本有什么感觉吗? 很多人会说其实并没有太多的感觉。JDK的新版本不断推出一些不痛不痒…...
jdk17+springboot3项目加密部署
最近项目需要在第三方服务器部署,由于没有交付源码。所以需要将项目加密后再部署。 网上找了一圈,发现xjar这个开源项目,可以将代码加密后进行部署。看了下正是我需要的。 于是按照文档打包加密,但启动的时候居然报错。 这个结…...
rm -rf 删除/下bin lib lib64 sbin软链接系统恢复
背景 不小心删除了/bin、/lib、/lib64和/sbin这些目录的软链接,导致系统中的各种命令都无法正常使用。在尝试多种方法后,包括添加环境变量和使用绝对路径执行命令无法恢复,最终不重装完美解决。 [rootcentos-8 /]# ll 总用量 36 drwxr-xr-x …...
并发与竞争
并发与竞争 并发与竞争的产生 Linux是一个多任务操作系统,肯定会存在多个任务共同操作同一段内存或者设备的情况,多个任务甚至中断都能访问的资源叫做共享资源,就和共享单车一样。在驱动开发中要注意对共享资源的保护,也就是要处…...
Java后端开发 ”Bug“ 分享——订单与优惠卷
“优惠券风波”:一段代码引发的线上事故 起因:优惠券功能上线 故事的开始源于公司新上线的一项促销活动——在用户未使用优惠券时,系统会自动赠送一张优惠券。这个功能不仅能提升用户体验,还能拉动平台的销售额。为了赶上活动上…...
Linux系统之tee命令的基本使用
Linux系统之tee命令的基本使用 一、tee命令介绍二、tee命令的使用帮助2.1 tee命令的help帮助2.2 tee命令帮助解释 三、tee命令的基本使用3.1 写入文件3.2 追加文件3.3 结合sudo命令3.4 结合EOF使用 四、注意事项 一、tee命令介绍 tee 是 Linux 和 Unix 系统中的一个命令&#x…...
idea 8年使用整理
文章目录 前言idea 8年使用整理1. 覆盖application配置2. 启动的时候设置编辑空间大小,并忽略最大空间3. 查询类的关系4. 查看这个方法的引用关系5. 查看方法的调用关系5.1. 查看被调用关系5.2. 查看调用关系 6. 方法分隔线7. 选择快捷键类型8. 代码预览插件9. JReb…...
多个微服务 Mybatis 过程中出现了Invalid bound statement (not found)的特殊问题
针对多个微服务的场景,记录一下这个特殊问题: 如果启动类上用了这个MapperScan注解 在resource 目录下必须建相同的 com.demo.biz.mapper 目录结构,否则会加载不到XML资源文件 。 并且切记是com/demo/biz 这样的格式创建,不要使用…...
k8s,service如何找到容器
Kubernetes之所以需要Service,一方面是因为Pod的IP不是固定的,另一方面则是因为一组Pod实例之间总会有负载均衡的需求 被selector选中的Pod,就称为Service的Endpoints,查看方式: kubectl get endpoints hostnames需要…...
观察者模式和发布-订阅模式有什么异同?它们在哪些情况下会被使用?
大家好,我是锋哥。今天分享关于【观察者模式和发布-订阅模式有什么异同?它们在哪些情况下会被使用?】面试题。希望对大家有帮助; 观察者模式和发布-订阅模式有什么异同?它们在哪些情况下会被使用? 1000道 …...
docker compose deploy fate cluster
官方文档 写的不清晰 KubeFATE,用于生成部署脚本,链接 部署机就是下载了 KubeFATE的主机;运行机就是要安装fate容器的主机(部署机和运行机可以相同) 两个主机:并非必须 centos7,Ubuntu也行Doc…...
字节跳动Java开发面试题及参考答案(数据结构算法-手撕面试题)
怎么判断两个链表是否相交?怎么优化? 判断两个链表是否相交可以采用多种方法。 一种方法是使用双指针。首先分别遍历两个链表,得到两个链表的长度。然后让长链表的指针先走两个链表长度差的步数。之后,同时移动两个链表的指针,每次比较两个指针是否指向相同的节点。如果指…...
网工日记:FTP工作模式
FTP 基本概念 FTP(File Transfer Protocol)即文件传输协议,是用于在网络上进行文件传输的标准协议。它运行在 TCP/IP 协议栈之上,采用客户端 - 服务器(C/S)架构,通过在客户端和服务器之间建立控…...
unity使用代码在动画片段中添加event
unity使用代码在动画片段中添加event using UnityEngine;public static class AnimationHelper {/// <summary>/// 获取Animator状态对应的动画片段/// </summary>/// <param name"animator">Animator组件</param>/// <param name"…...
嵌入式轻量级开源操作系统:HeliOS的使用
嵌入式轻量级开源操作系统:HeliOS的使用 📍项目地址:https://github.com/heliosproj/HeliOS HeliOS项目是一个社区交付的开源项目,用于构建和维护HeliOS嵌入式操作系统(OS)。HeliOS是一个功能齐全的操作系统࿰…...
解决VMware的ubuntu22虚拟机没有网络
解决步骤 1.在 Windows 系统中,按 “WinR” 键,输入 “services.msc” 并回车,在服务列表中找到 “VMware DHCP Service” 和 “VMware NAT Service”,确保这两个服务已启动,若未启动则右键点击选择 “启动”…...
金属衬底介质片对平面波的反射-问题的解析求解和FEM求解
金属衬底介质片对平面波的反射-问题的解析求解和FEM求解 参考有限元从零单排系列4 代码参考了上面大佬文章提供的,但是部分计算系数错了,我改了下加了许多注释,便于大家理解。 书籍参考的电磁场有限元方法(金建铭),所用的公式都…...
2023 年 9 月青少年软编等考 C 语言四级真题解析
目录 T1. 酒鬼T2. 大盗T3. 核电站思路分析T4. 盒子与小球之二思路分析T1. 酒鬼 此题为 2021 年 3 月四级第一题原题,见 2021 年 3 月青少年软编等考 C 语言四级真题解析中的 T1。 T2. 大盗 此题为 2021 年 6 月四级第二题原题,见 2021 年 6 月青少年软编等考 C 语言四级真…...
C++的内存四区
文章目录 内存四区1.程序运行前1.1 代码区2.1 全局区2.2 示例 2.程序运行后1.1 栈区1.2 堆区 内存四区 1.程序运行前 在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域。该区域的数据在程序结束后由操作系统释放. 1.1 代码区 存放 CPU …...
Java爬虫技术:按关键字搜索VIP商品详情
在数字化时代,电子商务平台的竞争日益激烈,而精准的数据采集和分析成为了企业获取竞争优势的关键。对于电商平台而言,能够根据用户输入的关键字快速搜索并展示VIP商品的详细信息,不仅能够提升用户体验,还能够增加销售机…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...
