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