Java Platform Module System
,JPMS,JDK 9 引入的 Java 模块化系统,可配置的封装隔离机制;
- 通过模块间的显示依赖,支持 JVM 在启动时验证应用程序的运行期依赖是否完备,可以避免在运行期间因类加载、连接失败而抛异常;
- 模块提供了更精细的可访问性控制(可以声明哪些 public 类可被其他哪些模块访问),不再意味着程序的所有地方都能访问 public 类型;
模块化定义
- 依赖其他模块的列表;
- 导出的包列表,即可被其他模块引用的列表;
- 开放的包列表,即其他模块通过反射可访问的模块列表;
- 使用的服务列表;
- 提供服务的实现列表;
文章目录
- 1. 模块的兼容性
- 2. 模块化下的类加载器
1. 模块的兼容性
JDK 9 引入了与类路径
(ClassPath)相对应的模块路径
(ModulePath)的概念,用于兼容传统类路径查找机制;
- 只要是放在类路径上的 JAR 文件,即使包含模块化信息,包含了
module-info.class
文件,也会被当作传统的 JAR 包来对待; - 只要是放在模块路径上的 JAR 文件,即使没有使用 JMOD 后缀,即使不包含
module-info.class
文件,它也会被当作一个模块来对待;
访问规则
-
匿名模块
(Unnamed Module
),即传统类路径上的所有传统 JAR 文件;它可以看到和使用类路径上所有的包、JDK 系统模块中所有导出的包、模块路径上所有模块导出的包; -
具名模块
(Named Module
),即模块路径上的模块;只能访问它明确依赖的模块和包,匿名模块的所有内容(传统 JAR 包的内容)对具名模块不可见; -
自动模块
(Automatic Module
),即模块路径上不包含模块定义的传统 JAR 文件; 虽然不包含module-info.class
,但它默认导出自己所有的包,并可以访问所有模块导出的包;
不经任何修改的传统类依赖版 Java 程序在 JDK 9 以上版本运行几乎不会受到模块化影响;
JPMS 目前不支持在模块定义中管理和约束版本号,不支持版本号概念和版本选择功能;
JPMS 不支持运行时热替换、模块热部署能力,仍需通过类加载器去实现;JVMTI 接口(java.lang.instrument.Instrumentation
)也只提供了运行时修改类的能力(RedefineClass、RetransformClass),不能添加新成员、删除已有成员、修改已有成员的签名等;
2. 模块化下的类加载器
扩展类加载器
(Extension Class Loader
)被平台类加载器
(Platform Class Loader
)取代;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LzT9eOpy-1675990882394)(./images/ClassLoader-Module.png)]
平台类加载器,以及原有的启动类加载器、应用类加载器都不再继承自 java.net.URLClassLoader
,而是继承自 jdk.internal.loader.BuiltinClassLoader
,该类实现了新的模块化架构下的类如何从模块中加载、模块资源可访问性控制等功能;
JPMS 下的委派关系
当平台类加载器和应用程序类加载器收到类加载请求,会先判断该类是否能归属到某个系统模块中,若找到其归属关系,就优先委派给负责这个模块的加载器进行加载,否则才会委派给父类加载器;
- 启动类加载器负责的模块
java.base java.security.sasl
java.datatransfer java.xml
java.desktop jdk.httpserver
java.instrument jdk.internal.vm.ci
java.logging jdk.management
java.management jdk.management.agent
java.management.rmi jdk.naming.rmi
java.naming jdk.net
java.prefs jdk.sctp
java.rmi jdk.unsupported
- 平台类加载器负责的模块
java.activation* jdk.accessibility
java.compiler* jdk.charsets
java.corba* jdk.crypto.cryptoki
java.scripting jdk.crypto.ec
java.se jdk.dynalink
java.se.ee jdk.incubator.httpclient
java.security.jgss jdk.internal.vm.compiler*
java.smartcardio jdk.jsobject
java.sql jdk.localedata
java.sql.rowset jdk.naming.dns
java.transaction* jdk.scripting.nashorn
java.xml.bind* jdk.security.auth
java.xml.crypto jdk.security.jgss
java.xml.ws* jdk.xml.dom
java.xml.ws.annotation* jdk.zipfs
- 应用程序类加载器负责的模块
jdk.aot jdk.jdeps
jdk.attach jdk.jdi
jdk.compiler jdk.jdwp.agent
jdk.editpad jdk.jlink
jdk.hotspot.agent jdk.jshell
jdk.internal.ed jdk.jstatd
jdk.internal.jvmstat jdk.pack
jdk.internal.le jdk.policytool
jdk.internal.opt jdk.rmic
jdk.jartool jdk.scripting.nashorn.shell
jdk.javadoc jdk.xml.bind*
jdk.jcmd jdk.xml.ws*
jdk.jconsole
上一篇:「JVM 执行子系统」类加载器与双亲委派模型 下一篇:「JVM 执行引擎」 虚拟机栈的栈帧结构
PS:感谢每一位志同道合者的阅读,欢迎关注、评论、赞!
参考资料:
- [1]《深入理解 Java 虚拟机》