在Java 9中,module-info.java应该放在哪个位置?

17

我有一个OSGI应用程序,大约有30个捆绑包(jar文件)。今天我决定测试一下它是否能在Java 9上工作。

然后我启动了我的应用程序并得到了以下信息:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.felix.framework.util.SecureAction (file:/home/.../jar/org.apache.felix.framework-5.4.0.jar) to method java.net.URLClassLoader.addURL(java.net.URL)
WARNING: Please consider reporting this to the maintainers of org.apache.felix.framework.util.SecureAction
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

阅读一些内容后,我添加了命令行选项

--add-exports java.base/java.net=org.apache.felix.framework 

并创建了名为module-info.java的文件,其内容如下:

module org.apache.felix.framework { }

我有两个问题。我应该将这个module-info.java放在哪里才能让jvm读取它?我应该如何将这个module-info与org.apache.felix.framework-5.4.0.jar文件/捆绑/ jar?

如果我做错了,请指出我正确的方向来解决这个问题。


1
这可能不值得回答,但如果有帮助的话,这里是一个Java 9的小例子。请参见链接以获取其在OSGi(Java 8)中的版本。 - Michael Easter
3个回答

22

通用提示:

回答您的具体问题:

模块声明 (module-info.java) 放置到项目的源根目录中 (例如 src/main/java)。 它必须列在编译文件列表中,以便将其转换为 模块描述符 (module-info.class)。 最后一步是将其包含在打包成JAR的类文件列表中。 在JAR文件中包含模块描述符将其变为模块化 JAR。 如果放置在模块路径上,则JPMS将其转换为模块。

如果您最终不想创建模块并希望代码在未命名模块中运行,则可以使用占位符ALL-UNNAMED允许它访问内部API - 在您的警告情况下,您需要打开该包以进行反射:

--add-opens java.base/java.net=ALL-UNNAMED

更好的解决方案是停止使用内部API。由于这不是您的代码,而是您的依赖项,您应该寻找或打开一个问题与Apache Felix一起请求删除对内部API的访问权限。


谢谢。好的,我不想创建任何模块,我希望它们没有名称。但是那么我应该如何解决“WARNING:An illegal reflective access operation has occurred”问题? - Pavel_K
1
更新了答案,包括 ALL-UNNAMED - Nicolai Parlog
1
是的,抱歉,我没有仔细查看你的日志。顺便说一下,这只是一个警告,而不是错误。 - Nicolai Parlog
1
@Pavel_K 昨天似乎有点晚了。是的,你需要在那里加上 =(已更正答案),但然后它应该可以工作(对我来说是这样)。 - Nicolai Parlog
@Nicolai 当将module-info.java放入src/main/java中时,可能使用的src/main/resources不在模块路径上。将其移动到src/main目录下是否可行? - SixDoubleFiveTreeTwoOne
显示剩余2条评论

3

由于 org.apache.felix.framework-5.4.0.jar 中的代码存在非法访问问题,因此您应该向 Apache Felix 提交错误报告并进行修复。我快速测试了更新版本 5.6.8 并使用 --illegal-access=debug,看起来 Felix 存在多个需要关注的问题。是的,您可以通过将 java.net 包打开到“ALL-UNNAMED”来暂时消除上述特定警告,但这只是一个或多个问题。


3

如果您正在使用Java-9启动项目,那么Jigsaw快速入门是一个不错的起点。

我应该把module-info.java放在哪里才能让jvm读取它?

根据声明 module org.apache.felix.framework { } 推断出您的模块名称,您应该将 module-info.java 文件放置在您的项目目录中的以下位置:

src/org.apache.felix.framework/module-info.java 

我该如何将module-info与org.apache.felix.framework-5.4.0.jar文件/捆绑包/jar关联?
为编译模块并打包它们(在模块化的jar文件的顶级目录中绑定module-info.class),您可以使用javac和jar命令。
以下是上述操作的示例命令:
$ javac --module-path mods -d mods/org.apache.felix.framework \
    src/org.apache.felix.framework/module-info.java src/org.apache.felix.framework/com/apache/felix/framework/Application.java


$ jar --create --file=mlib/org.apache.felix.framework.jar \
    --main-class=com.apache.felix.framework.Application -C mods/com.apache.felix.framework

此外,您可以使用以下方式执行该模块:

$ java -p mlib -m com.apache.felix.framework

除了状态模块系统和快速入门文档之外,如果要将现有项目迁移到Java-9,我建议您遵循JDK9迁移指南,其中清楚地说明了需要逐步过渡以适应Java9的步骤。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接