深入解析Java模块系统:Root Modules与Java EE的融合之道

时间:2025-03-31 07:06:35

深入解析Java模块系统:Root Modules与Java EE的融合之道

在Java 9中,模块系统引入了一种新的编程范式,使得代码的组织和依赖管理更加清晰。本文将详细探讨Root Modules的概念,以及如何在Java 9中继续使用Java EE库,例如JAXB。

Root Modules概述

Root Modules是JDK 9中引入的一个概念,它们只包含文件,不包含任何包或Java代码。这些模块的主要作用是依赖其他模块,并使它们对外可见。就是这样一个模块,下面我们看看它的声明方式:

module java.se {
    requires transitive java.compiler;
    requires transitive java.datatransfer;
    // 其他依赖省略...
}
  • 1
  • 2
  • 3
  • 4
  • 5

'requires transitive’子句解析

transitive关键字的效果是,目标模块不仅被当前模块(例如)所依赖,而且对依赖当前模块的其他模块也是可见的。例如requires transitive 将使得对依赖模块的模块可见。这与exports不同,exports用于使包可见,而requires transitive用于使导入的模块对外可见。

Root Modules的使用

当编译或加载未命名模块时,应该能够访问一组Root Modules中的一个,以便非模块化应用程序能够继续工作。默认的Root Modules集合是实现特定的。在JDK实现中,它是模块。如果我们使用一个不在默认Root Modules集合中的模块中的类会怎样呢?让我们通过一个例子来了解。

实例分析

以下示例使用JAXB API将字符串反序列化为对象:

public class MsgUnMarshaller {
    public static void main(String... st) throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(MsgObj.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        StringReader reader = new StringReader("<msgObj><msg>test msg</msg></msgObj>");
        MsgObj msgObj = (MsgObj) unmarshaller.unmarshal(reader);
        System.out.println(msgObj);
    }
}

@XmlRootElement
public class MsgObj {
    private String msg;
    // getter和setter方法省略...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在尝试编译上述代码时,我们遇到了错误,因为JAXB相关的类对我们的未命名模块不可见。原因是中的默认Root Modules没有包含requires transitive 。为了解决异常,我们需要使用--add-modules 来添加模块。

编译与运行

使用以下命令编译和运行程序:

javac --add-modules  -d out src/com/logicbig/ src/com/logicbig/
java --add-modules  -cp out 
  • 1
  • 2

Java 9之前的情况

在Java 9之前,JAXB API和其他Java EE API自Java SE 6以来就捆绑在Java SE中,无需额外配置即可工作。Java 9决定通过新的模块系统将这些Java EE API从Java SE中分离出来,以减小JRE的大小,使其能够在更小的设备上运行。

模块

如果你的应用程序使用了大量的Java EE API,它在Java 9中运行时可能会失败。例如,如果你在应用程序中使用了JPA/Hibernate,它在编译和运行时可能会失败。与其逐个找出所需的模块,不如使用 module中声明的Java SE和Java EE模块的混合集。我们可以通过--add-modules选项启用这组Root Modules。

在IDE中设置–add-modules选项

所有IDE都有设置编译器和JVM运行时选项的功能。例如,在IntelliJ中,我们可以如下设置它们:

示例项目

使用的技术与依赖:

  • JDK 9