gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-11-01 02:57:50 24 4
gpt4 key购买 nike

我有这样一个项目:

\---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 的实现是:

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

请注意,main 是未命名的模块。

api/src/module-info.java 是:

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

impl/src/module-info.java是:

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

更新 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.javauses com.foo.api.ApiInterface; 但它给出了相同的结果(无)。

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

<强>1。当未命名模块尝试与命名模块交互时,java 9 如何工作?

<强>2。是否有可能让它工作并保持 main 像未命名的模块?

更新 1.3 - added related project

最佳答案

ServiceLoader::load 照常工作,但还有其他事情。

[简答]

1. 未命名模块命名模块命名模块的读取相同,但已命名模块 无法访问未命名模块 中的类型。

2.您正在尝试从非模块化 JAR 启动应用程序,因此您必须通过 --add-modules com.foo.impl 明确解析所需的模块。 .

请注意,您需要的模块必须在模块图 上(例如,通过--module-path 添加)。

[更多详情]

1. 有 4 种不同类型的模块:内置平台模块、命名模块、自动模块 未命名模块 和每个其中的命名不同于未命名模块

As they wrote 未命名模块命名模块一样对待所有其他模块:

All other modules have names, of course, so we will henceforth refer to those as named modules.

The unnamed module reads every other module. [...]

The unnamed module exports all of its packages. [...] It does not, however, mean that code in a named module can access types in the unnamed module. A named module cannot, in fact, even declare a dependence upon the unnamed module. [...]

If a package is defined in both a named module and the unnamed module then the package in the unnamed module is ignored.

甚至自动模块也是named :

An automatic module is a named module that is defined implicitly, since it does not have a module declaration.

2. Second part of this answer

If you compile non-modular code or launch an application from a non-modular JAR, the module system is still in play and because non-modular code does not express any dependencies, it will not resolve modules from the module path.

So if non-modular code depends on artifacts on the module path, you need to add them manually with the --add-modules option. Not necessarily all of them, just those that you directly depend on (the module system will pull in transitive dependencies) - or you can use ALL-MODULE-PATH (check the linked post, it explains this in more detail).

这个@nullpointer 注释会很有用

Also, the module resolution still needed the impl to be resolved during the startup. To check which you could also make use of the --show-module-resolution flag.

关于java - 未命名模块通过 ServiceLoader::load 与命名模块交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48327898/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com