在Java 9中,我们如何显示所有具有类加载器的模块呢?

Java 9中的模块系统

自从Java 1.2引入了jar文件作为Java程序库的一种方式以来,Java就一直采用了基于类路径(classpath)的类加载机制。然而,由于各种原因,例如对于大型应用程序的复杂性、对于依赖性的无控制和对于潜在的二进制兼容性问题的恐惧,Java SE 9发布之前加入了一种称为"模块系统"的特性。

Java SE 9中的模块系统是在类装载器之上建立的,它为Java类提供了明确的依赖性和版本选择规则,并在编译时和运行时验证这些限制。模块是基于源代码文件的,并包含一个模块描述符(模块元数据),该模块元数据表明了它的名称、依赖关系及其所包含的包。模块描述符是以module-info.java文件的形式呈现的,其中包含了模块的元数据信息。

模块加载器

Java SE 9中引入的模块系统与Java平台自带的其他类加载机制一样,在Java虚拟机中实现了一个模块化加载器架构。Java 9中引入了三种不同类型的模块加载器,分别代表了不同的类加载上下文和不同的加载行为。

启动模块加载器

Java虚拟机启动时,部分核心模块被以显式的方式加载,并由启动模块加载器(load-time bootstrap),这些核心模块被归为"启动模块"。启动模块加载器是VM实现的一部分,它是一个特殊的模块加载器,它的任务是加载所有的启动模块,并将它们提交到Java平台以供所有其他其他模块使用。

平台类加载器

平台类加载器(platform class loader)通过Java API的ClassLoader API(java.lang.ClassLoader)提供。它负责在平台级别上的加载,这个平台级别可能是由应用程序代码或将自己打包的模块组成的。在一个模块需要其他模块来实现其功能时,平台类加载器会被调用,以便使用其他依赖模块的代码可以被放置在类路径中并被使用。

应用程序类加载器

应用程序类加载器(application class loader),也称为系统类加载器,通过Java API的ClassLoader API提供。这个ClassLoader用来加载所有的应用程序类,它会在默认的classloader搜索路径上(通常是classpath)查找一个类,并将其转换为二进制代码,从而使其可以被Java虚拟机(JVM)使用。应用程序类加载器的主要任务是构建Java应用程序模块,这个模块由多个彼此独立的类库和其他模块组成。

显示具有类加载器的模块

在Java SE 9中,我们可以使用java.lang.module模块中的ModuleFinder和ModuleReference类,以及java.util.ServiceLoader模块中的ClassLoaderProvider类,来显示具有类加载器的模块。ClassLoaderProvider类是模块化的类加载器提供程序的服务提供方。以下是显示所有具有类加载器的模块的代码示例:

ModuleFinder finder = ModuleFinder.ofSystem();

Set<ModuleReference> moduleReferences = finder.findAll();

moduleReferences.stream()

.map(ModuleReference::descriptor)

.sorted(Comparator.comparing(ModuleDescriptor::name))

.forEach(descriptor -> {

String moduleName = descriptor.name();

ClassLoader loader = ClassLoader.getSystemClassLoader();

Optional<Module> moduleOpt = ModuleLayer.boot().findModule(moduleName);

if (moduleOpt.isPresent()) {

Module module = moduleOpt.get();

loader = module.getClassLoader();

}

if (loader != null) {

String loaderName = loader.toString();

System.out.println(moduleName + " is loaded by " + loaderName);

}

});

上面的代码首先使用系统Classpath来创建一个ModuleFinder。然后,通过finder.findAll()方法找到所有当前系统中模块的ModuleReference。接下来,它遍历每个模块的模块描述符,并使用findModule()方法查找给定名称的模块。如果找到了这个模块,就从中获取它的类加载器,否则它将使用系统Classpath加载器。最后,它将输出每个模块及其加载器的名称。

结论

Java SE 9中引入了模块化系统,使Java更具模块性。与之相对应的是模块系统与类加载机制之间的关系。Java SE 9中与类装载器相关的功能是在模块化系统之上建立的,Java 9提供了三个类加载器,分别是启动模块加载器、平台类加载器、应用程序(系统)类加载器。我们可以使用Java 9中的模块发现器(ModuleFinder),模块参考(ModuleReference)和类加载器提供者(ClassLoaderProvider)来显示具有类加载器的模块。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签