JDK的模块化之Overview

Posted 顧棟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK的模块化之Overview相关的知识,希望对你有一定的参考价值。

JDK的模块化一之Overview

文章目录


最近 Spring官宣 Spring Boot 3.0开始不再支持jdk1.8,最低要求JDK17,随打算对JDK之间的主要变化特性中的JDK的模块化,系统的学习一下。

Spring-Boot-3.0.0-M1-Release-Notes

背景

在JDK9开始发布的一个关键特性Java平台模块系统,代号为Project Jigsaw——为Java SE 9引入了一个全新的概念。

截止JDK9之前,JDK有以下的几个问题

  1. 源文件过大

    对于一些小型设备来说,jdk中的jar文件太大了,比如rt.jar,还有src.ziptools.jar等等。

  2. JDK过大

    JDK太大了,众多的功能都糅合在一起,就不利于这使得缩小到小型设备有点困难。

  3. 缺乏强封装性

    在当前的Java系统中没有真正强大的封装,因为公共访问修饰符太开放了——每个人都可以访问它。因为公众太开放了,所以在访问一些像sun这样的内部关键api时没有任何限制。例如*,.internal.,因为用户也可以访问内部api。这使得安全性成为一个大问题。

  4. 难以支持最小耦合

    众多的功能都糅合在一起,对于不使用的功能无法分离出去。

目标

为了解决上述的问题,为JPMS的设定了下列主要目标

  • Reliable configuration

    通过配置更显式地声明模块之间的依赖关系,以便在编译代码和执行代码时都能识别它们。系统读取依赖项列表,以便决定应用程序需要哪些模块。

  • Strong encapsulation

    强封装性可以提高安全性,显示导出的包才能被其他模块使用。只有当您的模块显式导出包时,其他模块才可以使用这些包。其他模块要使用原始模块的包,必须显式声明它需要原始模块的功能。

  • A scalable Java platform

    采用模块化后,将平台拆分为多个模块,一些不使用的模块可以不引用,可以自定义构建需要的模块。

  • Greater platform integrity

    更好的平台完整性。与Java 8及更早的版本不同,Java 9中的强封装使封装的内部api对使用该平台的应用程序隐藏。这很好,因为它增加了安全性,但它可能使将遗留代码迁移到Java 9成为一项困难的任务。

  • Improved performance

    通过在特定模块中定位所需的类型并允许知道这一点,JVM优化技术可以更有效地提高应用程序的性能。更多查询官网说明:JSR 376: Java Platform Module System

JDK引入模块化方案

正如您所知,Java 8中的JDK系统太大了,因此语言开发人员决定将JDK划分为一组模块,这些模块可以在编译、构建或运行时组合成各种配置,包括但不限于:

  • Java SE全平台、JRE、JDK对应的配置
  • 配置的内容大致相当于Java SE 8中定义的每个紧凑概要文件
  • 自定义配置,其中只包含一组指定的模块以及这些模块偶尔需要的模块

模块化结构的定义应该明确区分标准模块(其规范受Java Community Process控制)和特定于JDK的模块。它还应该将Java SE平台规范中包含的模块(因此在每个平台实现中都是强制性的)与所有其他模块区分开来。

设计原则

  1. "java.".标准模块的规范由JCP控制,其名称以字符串’ “java.” '开头。
  2. 所有其他模块都只是JDK的一部分,名称以字符串" JDK ." 开头。
  3. 如果一个模块导出的包包含一个类型,而该类型又包含一个公共或受保护成员,而这些成员又引用了来自其他模块的类型,那么第一个模块必须通过requires transitive向第二个模块授予隐含的可读性。(这确保了方法调用链接以明显的方式工作。)
  4. 标准模块可以包含标准API包和非标准API包。如果一个标准模块导出一个标准API包,那么该导出可能是合格的;如果一个标准模块导出一个非标准API包,那么该导出必须是合格的。在任何一种情况下,如果一个标准模块导出一个带有限定的包,那么该导出必须是到JDK中模块的某个子集。如果一个标准模块是Java SE模块,即。,被包含在Java SE平台规范中,那么它必须不能导出任何非SE API包,至少不能没有资格。
  5. 一个标准模块可能依赖于一个或多个非标准模块。它不能赋予任何非标准模块隐含的可读性。如果它是一个Java SE模块,那么它不能授予任何非SE模块隐含的可读性。
  6. 非标模块不能导出任何标准API包。非标准模块可以赋予标准模块隐含的可读性。
  7. 原则4和5的一个重要结果是代码,只依赖于Java SE模块将只取决于标准Java SE类型,从而可以移植到所有Java SE平台的实现。

模块化源代码

JEP 201: Modular Source Code:为JDK提出了一种新的源代码布局,在这种布局中,运行时被重新组织为模块,这些模块将增强构建系统,以编译模块并在构建时强制执行模块边界。

模块化运行时映像

JEP 220: Modular Run-Time Images:该特性的主要目标是“重构JDK和JRE运行时映像,以适应模块,并提高性能、安全性和可维护性。

  1. 为存储的类和资源文件采用以下运行时格式:
    • 比传统的JAR格式更节省时间和空间,而传统的JAR格式基于古老的ZIP格式;
    • 可以在每个模块的基础上定位和加载类和资源文件;
    • 可以存储来自存储来自JDK、库和应用程序模块的类/资源文件;
    • 可以进行扩展以适应新的数据类型,例如预计算的JVM数据结构和预编译的Java本地类代码(native classes)。
  2. 重新构造JDK和JRE运行时映像,明确区分开发人员、部署人员和最终用户可以依赖和在适当时修改的文件,而不是实现内部的文件,这些文件可以在不通知的情况下进行更改。
  3. 提供受支持的方法来执行常见操作,例如枚举映像中出现的所有类,这些操作目前需要检查运行时映像的内部结构。
  4. 启用JDK类的选择性“去特权化”,这些类目前被授予了所有的安全权限,但实际上并不需要这些权限。
  5. 保留行为良好的应用程序的现有行为,即不依赖于JRE和JDK运行时映像的内部方面的应用程序。

封装大多数内部api

JEP 260: Encapsulate Most Internal APIs:该特性的目标是使大多数JDK内部api在默认情况下不可访问,但保留一些关键的、广泛使用的内部api,直到它们的所有或大部分功能都有支持的替换存在为止。

默认情况下封装大多数JDK内部api,使它们在编译时不可访问,并为将来的发行版做好准备,在将来的发行版中,它们在运行时不可访问。确保关键的、广泛使用的内部api没有被封装,这样在它们的所有或大部分功能存在支持的替换之前,它们都是可访问的。

Java平台模块系统

JEP 261: Module System:该特性允许用户创建自己的模块来开发应用程序。

jlink: The Java Linker JAVA链接器

JEP 282: Jlink: The Java Linker:该特性的主要目标是创建一个工具,该工具可以将一组模块及其依赖项组装和优化到JEP 220中定义的自定义运行时映像中;换句话说,构建一个允许用户生成定制的、模块化的运行时映像的工具。

JDK 9 文件夹结构变化

安装JDK 8软件后,您会在Java Home文件夹中看到几个目录,如bin、jre、lib、db等,以及像src.zip和javafx-src.zip这样的文件。

首先要注意的是,JDK 9中的文件夹结构发生了一些变化。

JDK 9文件夹中不包含JRE。在JDK 9中,JRE被集中到一个单独的分发文件夹中,这是多余的,并且包含bin文件夹中已经存在的相同工具;这不必要地增加了JDK的大小。

其他文件和文件夹已被删除并转换为模块。JDK 9软件包含一个名为jmods的新文件夹。此文件夹包含一组Java 9编译模块定义。

根据JEP 261,新的JMOD格式超越了JAR文件,还包括本机代码、配置文件和其他类型的数据,这些数据不自然地(如果根本不适合的话)适合JAR文件。JMOD文件的最终格式是一个悬而未决的问题,但目前它是基于zip文件的。

JDK 模块列表以及版本变化

正如您在前面的图片中看到的,整个JDK被划分为一组模块。因此,您可以在编译、构建或运行时期间根据您的需求将一个集合组装到各种配置中。以下资源提供了模块的完整列表及其描述:

随着Java的发展,您会注意到不同版本之间模块的变化;一些新模块将被添加,一些已弃用以备将来删除,而另一些模块将被完全删除。

总结

在本文中,您了解了JPMS是什么,包括将模块系统引入Java背后的动机。我已经解释了Java 8和以前版本中设计模块化来解决的问题,并向您展示了可以解决这些问题的工具和特性。最后,强调了Java 8的JDK结构与早期JDK和新的JDK 9配置之间的区别。

附录

Java modularity JEPs and JSRs

Java生态系统中JPMS和模块化的发展,以下是处理Java中该技术开发的jep和jsr:

以上是关于JDK的模块化之Overview的主要内容,如果未能解决你的问题,请参考以下文章

模块化组合夹具 —— 将非标标准化

非标设计之自动机与自动线

什么是非标业务?

Kata Container — Overview

Kata Container — Overview

JDK模块化之模块的基础概念