未命名模块通过 ServiceLoader::load 与命名模块交互

2023-12-27

我有一个这样的项目:

\---main
    \---src
        \---com.foo
            \---UnnamedStart.java
\---api
    \---src
        \---com.foo.api
            \---ApiInterface.java
        \---module-info.java
\---impl
    \---src
        \---com.foo.impl
            \---ApiInterfaceImpl.java
        \---module-info.java

实施UnnamedStart.java is:

public static void main(String[] args) {
    ServiceLoader<ApiInterface> services = ServiceLoader.load(ApiInterface.class);
    ...
}

注意main是未命名的模块。

api/src/module-info.java is:

module com.foo.api {
     exports com.foo.api;
}

and impl/src/module-info.java is:

更新1.1- 下面的代码已更新,请参阅评论,添加requires

更新1.2- 下面的代码已更新,provides A with B变成provides B with A创建问题时出错,本来可以

module com.foo.impl {
     requires com.foo.api; //added (update 1.1)
     provides com.foo.impl.ApiInterface
         with com.foo.api.ApiInterfaceImpl; //vice versa (update 1.2)
}

当我运行我的代码时UnnamedStart.java我最终没有任何元素services.

我还尝试在中创建静态方法com.foo.api.ApiInterface:

static List<ApiInterface> getInstances() {
    ServiceLoader<ApiInterface> services = ServiceLoader.load(ApiInterface.class);
    List<ApiInterface> list = new ArrayList<>();
    services.iterator().forEachRemaining(list::add);
    return list;
}

并添加api/src/module-info.java line uses com.foo.api.ApiInterface;但它给出了相同的结果(什么也没有)。

我让它发挥作用的唯一方法是迁移main从未命名模块到命名模块。

1. 怎样做java 9当未命名模块尝试与命名模块交互时工作?

2.是否有可能让它发挥作用并保持main比如未命名的模块?

更新1.3 - 添加了相关项目 https://github.com/akhmelov/service-loader-problem


服务加载器::加载像往常一样工作,但还有其他事情。

[简短回答]

1. 未命名模块读起来一样命名模块 to 命名模块, but 命名模块无法访问中的类型未命名模块.

2.您正在尝试从非模块化 JAR 启动应用程序,因此您必须通过以下方式显式解析所需的模块--add-modules com.foo.impl https://blog.codefx.org/java/five-command-line-options-to-hack-the-java-9-module-system/#Extending-The-Module-Graph-With--add-modules.

请注意,您所需的模块必须打开模块图(例如添加方式--module-path).

[更多细节]

1.有 4 种不同类型的模块:内置平台模块、命名模块、自动模块、 未命名模块他们每个人的名字都是分开的未命名模块

正如他们所写 http://openjdk.java.net/projects/jigsaw/spec/sotms/#the-unnamed-module the 未命名模块像对待所有其他模块一样命名模块:

当然,所有其他模块都有名称,因此我们今后将这些模块称为命名模块。

未命名的模块读取所有其他模块。 [...]

未命名的模块导出其所有包。 [...] 但是,这并不意味着命名模块中的代码可以访问未命名模块中的类型。事实上,命名模块甚至不能声明对未命名模块的依赖。 [...]

如果在命名模块和未命名模块中都定义了包,则未命名模块中的包将被忽略。

Even an 自动模块确实也是named http://openjdk.java.net/projects/jigsaw/spec/sotms/#automatic-modules:

自动模块是隐式定义的命名模块,因为它没有模块声明。

2. 这个答案的第二部分 https://stackoverflow.com/questions/46288170/is-it-possible-to-mix-class-path-and-module-path-in-javac-jdk-9/46289257#46289257

如果您编译非模块化代码或从非模块化 JAR 启动应用程序,则模块系统仍在发挥作用,并且由于非模块化代码不表达任何依赖项,因此它不会从模块路径解析模块。

因此,如果非模块化代码依赖于模块路径上的工件,则需要使用以下命令手动添加它们the --add-modules option https://blog.codefx.org/java/five-command-line-options-to-hack-the-java-9-module-system/#Extending-The-Module-Graph-With--add-modules。不一定是全部,只是那些你直接依赖的(模块系统将引入传递依赖) - 或者你可以使用ALL-MODULE-PATH(查看链接的帖子,它更详细地解释了这一点)。

这个@nullpointer 注释将会很有用

此外,模块解析仍然需要在启动期间解析 impl。要检查您还可以利用--show-module-resolution https://stackoverflow.com/questions/48339598/list-the-modules-resolved-during-the-application-startup flag.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

未命名模块通过 ServiceLoader::load 与命名模块交互 的相关文章

  • 如何在日期选择器中设置不在当前月份的单元格的样式

    我目前正在为我的 JavaFX 应用程序制作注册表 问题是 当日期选择器中的单元格不在页面的月份上时 我想让该单元格变灰 让我们看看我当前的日期选择器 我的日期选择器 正如您所看到的 我希望下个月的日期 27 日 28 日 30 日以及 1
  • 如何在 JFace 的 TableViewer 中创建复选框?

    我创建了一个包含两列的 tableViewer 我想将其中一列设为复选框 为此 我创建了一个 CheckBoxCellEditor 但我不知道为什么它不起作用 名为 tableName 的列显示其值正常 色谱柱规格如下 String COL
  • IntelliJ IDEA 创建的 JAR 文件无法运行

    我在 IntelliJ 中编写了一个跨越几个类的程序 当我在 IDE 中测试它时它运行良好 但是 每当我按照教程将项目制作成 jar 可执行文件时 它就不会运行 双击 out 文件夹中的文件时 该文件不会运行 并显示 无法启动 Java J
  • 在浏览器中点击应用程序时播放框架挂起

    我正在 Play 中运行一个应用程序activator run 也许 5 次中有 3 次 它会挂起 当我去http localhost 9000 它就永远坐在那里旋转 我看到很多promise timed out错误也 我应该去哪里寻找这个
  • java.io.IOException: %1 不是有效的 Win32 应用程序

    我正在尝试对 XML 文档进行数字签名 为此我有两个选择 有一个由爱沙尼亚认证中心为程序员创建的库 还有一个由银行制作的运行 Java 代码的脚本 如果使用官方 认证中心 库 那么一切都会像魅力一样进行一些调整 但是当涉及到银行脚本时 它会
  • 使用 ANTLR 为 java 源代码生成抽象语法树

    如何使用 ANTLR 从 java src 代码生成 AST 有什么帮助吗 好的 步骤如下 前往ANTLR站点 http www antlr org 并下载最新版本 下载Java g和JavaTreeParser g文件来自here htt
  • Java 页面爬行和解析之 Crawler4j 与 Jsoup

    我想获取页面的内容并提取其中的特定部分 据我所知 此类任务至少有两种解决方案 爬虫4j https github com yasserg crawler4j and Jsoup http jsoup org 它们都能够检索页面的内容并提取其
  • hibernate总是自己删除表中的所有数据

    您好 我正在开发一个 spring mvc 应用程序 它使用 hibernate 连接到存储文件的 mysql 数据库 我有两个方法 一个方法添加我选择的特定文件路径中的所有文件 另一种方法调用查询以返回从 mysql 存储的文件列表 问题
  • 无法理解 Java 地图条目集

    我正在看一个 java 刽子手游戏 https github com leleah EvilHangman blob master EvilHangman java https github com leleah EvilHangman b
  • 迁移到 java 17 后有关“每个进程的内存映射”和 JVM 崩溃的 GC 警告

    我们正在将 java 8 应用程序迁移到 java 17 并将 GC 从G1GC to ZGC 我们的应用程序作为容器运行 这两个基础映像之间的唯一区别是 java 的版本 例如对于 java 17 版本 FROM ubuntu 20 04
  • Clip 在 Java 中播放 WAV 文件时出现严重延迟

    我编写了一段代码来读取 WAV 文件 大小约为 80 mb 并播放该文件 问题是声音播放效果很差 极度滞后 你能告诉我有什么问题吗 这是我的代码 我称之为doPlayJframe 构造函数内的函数 private void doPlay f
  • 检查 Android 手机上的方向

    如何查看Android手机是横屏还是竖屏 当前配置用于确定要检索的资源 可从资源中获取Configuration object getResources getConfiguration orientation 您可以通过查看其值来检查方向
  • 反思 Groovy 脚本中声明的函数

    有没有一种方法可以获取 Groovy 脚本中声明的函数的反射数据 该脚本已通过GroovyShell目的 具体来说 我想枚举脚本中的函数并访问附加到它们的注释 Put this到 Groovy 脚本的最后一行 它将作为脚本的返回值 a la
  • 检查 protobuf 消息 - 如何按名称获取字段值?

    我似乎无法找到一种方法来验证 protobuf 消息中字段的值 而无需显式调用其 getter 我看到周围的例子使用Descriptors FieldDescriptor实例到达消息映射内部 但它们要么基于迭代器 要么由字段号驱动 一旦我有
  • Tomcat 6找不到mysql驱动

    这里有一个类似的问题 但关于类路径 ClassNotFoundException com mysql jdbc Driver https stackoverflow com questions 1585811 classnotfoundex
  • Java - 不要用 bufferedwriter 覆盖

    我有一个程序可以将人员添加到数组列表中 我想做的是将这些人也添加到文本文件中 但程序会覆盖第一行 因此这些人会被删除 如何告诉编译器在下一个空闲行写入 import java io import java util import javax
  • Springs 元素“beans”不能具有字符 [children],因为该类型的内容类型是仅元素

    我在 stackoverflow 中搜索了一些页面来解决这个问题 确实遵循了一些正确的答案 但不起作用 我是春天的新人 对不起 这是我的调度程序 servlet
  • java迭代器内部是如何工作的? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个员工列表 List
  • 中断连接套接字

    我有一个 GUI 其中包含要连接的服务器列表 如果用户单击服务器 则会连接到该服务器 如果用户单击第二个服务器 它将断开第一个服务器的连接并连接到第二个服务器 每个新连接都在一个新线程中运行 以便程序可以执行其他任务 但是 如果用户在第一个
  • JAVA - 如何从扫描仪读取文件中检测到“\n”字符

    第一次海报 我在读取文本文件的扫描仪中读取返回字符时遇到问题 正在读取的文本文件如下所示 test txt start 2 0 30 30 1 1 90 30 0 test txt end 第一行 2 表示两个点 第二行 位置索引 0 xp

随机推荐