当前位置: 首页 > 知识库问答 >
问题:

如何获得一个Java9模块参考一个未命名的模块[重复]

东郭和光
2023-03-14

更新:我在这里回答了自己的问题:

在Java 9中运行时扫描类路径/模块路径

--

[老问题----过时:]

在Java 9中,如果只给定一个模块对象,那么获取模块引用的正确方法是什么?

考虑以下两种引用java.base的方法:

Module mod = ModuleLayer.boot().findModule("java.base").orElse(null);
ModuleReference modRef = ModuleFinder.ofSystem().find("java.base").orElse(null);

mod有一个方法设置

modRef有一个方法ModuleReader open(),ModuleReader有一个方法流

但是,对于通过向类路径添加非模块jar文件而生成的自动(因此未命名)模块,您无法从ModuleFinder获取模块引用。of系统()。查找(字符串名称)或ModuleFinder。of系统()。findAll()--您只能从getClass()获取模块的引用。getModule()

我找不到任何方法来获取自动模块的模块引用(ModuleReference)。我也找不到从模块对象获取模块引用的方法,这意味着如果模块是自动和/或未命名的,我无法列出模块中的资源。

肯定有一种方法可以为给定的(已经加载的)Module获取Module引用


共有2个答案

司寇瑾瑜
2023-03-14
匿名用户

ModuleFinder返回的模块查找器。ofSystem()用于定位系统模块,这些模块是运行应用程序的JRE环境中内置的模块。

如果自动模块在文件系统上的位置已知,可以尝试使用目录检索模块查找器,即使用ModuleFinder。of(路径)。另一种方法是使用模块层的配置来解析模块引用:

Optional<ResolvedModule> resolvedModule = ModuleLayer.boot().configuration().findModule(name);
Optional<ModuleReference> moduleReference = resolvedModule.map(ResolvedModule::reference);

要回答有关仅从模块获取模块引用的一般问题,请使用一种方法:

Optional<ModuleReference> moduleReference
     = module.getLayer().configuration()
           .findModule(module.getName())
           .map(ResolvedModule::reference);

对于一个未命名的模块,我的猜测是您无法为它检索Module参考,但至少可以尝试调用配置()。模块()并查看它们是否包含一个未命名的模块。

常睿范
2023-03-14

首先要从问题中弄清楚的是句子中的推论是不正确的——

对于自动(因此未命名)模块,通过将非模块jar文件添加到类路径来生成

自动模块是在模块路径上找到的命名模块。另一方面,未命名模块是模块系统的一个成员,该模块系统支持从类路径加载类型,该类路径的包未在任何已知(命名)模块中定义。

用于加载类型本身的ClassLoader可用于获取Module(未命名)。我试图在Java9中创建了多少未命名模块的答案中解释这一点?以及。链接到相同的精确留档,也回答了未命名模块与哪个类加载器相关联?

事实证明,每个类加载器都有自己独特的未命名模块,由新的方法getUnnamedModule返回。。。。

ClassLoader cl = getClass().getClassLoader();// returns the class loader for the class
Module yourClassLoaderUnnamedModule = cl.getUnnamedModule();

进一步移动文档将添加到获取加载类型的模块表单未命名模块::

.. 类型被认为位于该加载器的未命名模块中,即类型的类对象的getModule方法将返回其加载器的未命名模块。

最终相当于:

Module yourClassUnnamedModule = getClass().getModule(); // from the type itself

主要是在访问未命名模块的资源方面,虽然我同意目前没有可见的API来访问未命名模块的资源等。然而,由于通过此模块加载的Class对象的类型总是来自类路径,因此可以获取正在使用的类路径的所有资源,或者反过来,您可以检查正在使用的资源是从类路径还是模块路径访问的。我可以想到的一种方法是使用上述两个功能进行验证:

yourClassLoaderUnnamedModule.equals(yourClassUnnamedModule)//true if resource is loaded via classpath
 类似资料:
  • 我试图了解JPMS是如何工作的。 从这里开始 类路径还没有完全消失。类路径上的所有JAR(模块化或非模块化)和类都将包含在未命名的模块中。与自动模块类似,它导出所有包并读取所有其他模块。但很明显,它没有名字。因此,它不能被指定的应用程序模块所要求和读取。未命名的模块可以依次访问所有其他模块。 请注意。。。在类路径上,将包含在未命名模块中。模块为单数。 从这里开始 为了兼容性,类路径上的所有代码都打

  • 问题内容: 我知道这个问题已经被问过多次了。我已经阅读了所有内容,但无法解决问题。以下是我的目录结构。 在main.py中,我将导入以下内容。 当我在Windows中执行代码时,它工作得很好。但是在Linux中,出现以下错误。 我还阅读了有关模块和包的官方python文档。 问题答案: 您的包裹结构还可以。您的导入声明很好。唯一缺少的是该软件包在中是可见的,该位置是可以解析import语句的位置列

  • 问题内容: 著名的Angular App Structure最佳实践推荐 博客文章概述了新推荐的angularjs项目结构,该项目结构现在是面向组件而非功能的,或者在最初的github问题中命名为“ Organized by Feature”。 博客文章建议每个模块中的每个文件应以模块名称开头,例如: 问题是:与在功能上命名文件相反,在模块的每个文件名内重复模块名称有什么好处和坏处?例如: 我问的

  • 问题内容: 我想在相同的django模板中两次使用相同的{%block%}。我希望此块在我的基本模板中出现多次: 然后扩展它: 我将得到一个例外,因为Django希望该块仅出现一次: /的TemplateSyntaxError 名称为“ title”的“ block”标签出现了多次 一种快速而肮脏的解决方案是将块标题复制为title1和title2: 但这违反了DRY原则。因为我有很多继承模板,而

  • 我得到3个不同的错误。 无法确定模块名称... 未命名模块读取包... 模块org.reactivestreams读取包从两个... 这些错误到底是什么? 建筑格拉德尔 错误消息: 编译Java 错误:无法确定/Users/srihariprasad/的模块名称。gradle/caches/modules-2/files-2.1/io。github。resilience4j/resilience4