Java Module-Info 'Uses' 指令(服务消费)
Posted
技术标签:
【中文标题】Java Module-Info \'Uses\' 指令(服务消费)【英文标题】:Java Module-Info 'Uses' Directive (Service Consumption)Java Module-Info 'Uses' 指令(服务消费) 【发布时间】:2021-12-07 04:56:55 【问题描述】:我正在使用一种新的随机生成器算法 (https://openjdk.java.net/jeps/356):
RandomGeneratorFactory.of("L128X1024MixRandom").create().nextDouble();
而且它有效。 使用 jpackage 工具后除外 (https://openjdk.java.net/jeps/392)
我得到异常
没有可用的随机生成器算法“L128X1024MixRandom”的实现
我尝试在我的 module-info.java (https://docs.oracle.com/javase/specs/jls/se17/html/jls-7.html#jls-7.7.3) 中添加 uses
指令来指定使用该服务
uses java.util.random.RandomGenerator;
但这并不能解决问题,或者在那里似乎很重要(我用错了吗?我认为这应该是解决方案)。
相反,我必须添加 jpackage 选项:
--add-modules jdk.random
复制步骤
1。用文件创建目录:
rngTest/com/example/Test.java
package com.example;
import javax.swing.JOptionPane;
import java.util.random.RandomGeneratorFactory;
public class Test
public static void main(String[] args) throws Exception
try
JOptionPane.showMessageDialog(null, "nextDouble: " + RandomGeneratorFactory.of("L128X1024MixRandom").create().nextDouble());
catch (Exception e)
JOptionPane.showMessageDialog(null, "Exception: " + e.getMessage());
rngTest/module-info.java
module com.example
requires java.desktop;
uses java.util.random.RandomGenerator;
rngTest/manifest.txt
Manifest-Version: 1.0
Created-By: 17.0.1
Build-Jdk-Spec: 17
Main-Class: com.example.Test
2。从 rngTest 目录运行命令
(对于 macOS。对于其他平台需要更改 --type dmg
,请参阅 https://openjdk.java.net/jeps/392)
find . -name "*.java" > sources.txt
javac @sources.txt -d target
mkdir -p lib; cd target; jar cfm ../lib/test.jar ../manifest.txt *; cd ..
$JAVA_HOME/bin/jpackage --module-path lib --module com.example/com.example.Test --type dmg --name Test
3。运行创建的安装程序,然后运行安装的应用程序
注意异常消息。
现在用--add-modules jdk.random
重新运行 jpackage 命令,然后重复步骤 3,注意成功。
$JAVA_HOME/bin/jpackage --module-path lib --module com.example/com.example.Test --type dmg --name Test --add-modules jdk.random
【问题讨论】:
当你说它有效时,完整的命令行会读到什么? @Naman 添加了重现步骤 你必须运行jpackage
和 --jlink-options --bind-services
。
@Holger 效果很好,但与使用--add-modules jdk.random
相比,它使我的应用程序大小(77->154MB)翻了一番,不确定其他服务会绑定什么。
这可能与您指定 --jlink-options
后会覆盖默认选项 --strip-native-commands --strip-debug --no-man-pages --no-header-files
的事实有关。当您进行此调整时,您还可以指定压缩选项,即--jlink-options "--bind-services --strip-native-commands --strip-debug --no-man-pages --no-header-files --compress 2"
【参考方案1】:
我曾尝试将 requires jdk.random;
添加到我的 module-info.java
编译失败,出现错误“module not found: jdk.random”
(我认为它的访问受到限制,只能导出到 java.base)
但那是 maven-compiler-plugin:3.8.1
事实证明它确实可以使用 javac 进行编译并且可以正常工作。
所以可能是 maven-compiler-plugin 的错误。
但我仍然认为uses
指令应该有效。我需要使用 maven-compiler-plugin。
【讨论】:
以上是关于Java Module-Info 'Uses' 指令(服务消费)的主要内容,如果未能解决你的问题,请参考以下文章
使用 module-info.java 时无法加载 FFI 提供程序
Java 9 + maven + junit:测试代码是不是需要自己的 module-info.java 以及放在哪里?
严重:无法在 Tomcat 7 && Java 8 中处理 Jar 条目 [module-info.class]
创建java project是需不需要创建一个module-info.JAVA file
为啥eclipse每次新建项目时都会出现一个错误弹窗,并会在src下自动生成module-info.java文档?
无法索引类 module-info.class atlog4j-api.jar:java.lang.IllegalStateException:未知标签! pos=4 池数 = 24