【发布时间】:2018-01-18 18:21:20
【问题描述】:
我有一个这样的项目:
\---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 - 更新下面的代码见 cmets,添加 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 行 uses com.foo.api.ApiInterface; 但它给出了相同的结果(什么都没有)。
我让它工作的唯一方法是将 main 从未命名的模块迁移到命名的模块。
1. java 9 在未命名模块尝试与命名模块交互时如何工作?
2。是否可以让它工作并保持 main 像未命名的模块?
更新 1.3 - added related project
【问题讨论】:
-
module com.foo.impl 似乎缺少
requires com.foo.api所以我怀疑它会编译。在任何情况下,您都需要使用--add-moduels com.foo.impl运行以确保解析 com.foo.impl 模块 - 您需要这个,因为没有模块声明需要它,也没有其他模块uses com.foo.api。 -
@Andrew 另外,当您迁移到命名模块时,您没有在主模块描述符中放置
requires com.foo.api吗? -
@nullpointer - 初始模块位于类路径中,因此它没有模块信息。混合模块路径和类路径是可以的,我怀疑他只是缺少
--add-modules com.foo.impl。 -
@AlanBateman 同意 OP 使用未命名模块的情况。该问题还提到了有关迁移到命名模块(模块路径)的问题。那是我询问模块描述符中使用的
requires指令的时候。 -
@AndrewChmielowski 我的意思是一样的(也许是讽刺的),你需要 impl 模块中的需求(如在你的编辑中)来编译未命名场景中的代码。此外,模块解析仍然需要在启动期间解析 impl。要检查您还可以make use of the
--show-module-resolution标记。
标签: java java-9 java-module module-info