jlink --module-path是否为有序路径?

时间:2018-11-10 15:03:00

标签: java java-9 jlink

我一直在尝试通过Hello World和Hello JFX World程序将程序迁移到 jlink 。在执行程序时,我遵循的示例似乎指定了-add-modules 。我不明白为什么该程序需要运行时提供的jlink时所需的信息。

我现在已经成功构建了一个简单的 jlink Hello World程序,该程序将在命令行中没有-add-modules 的情况下运行。技巧是更改jlink模块路径上指定的模块顺序。我不知道为什么这样。

JDK-9,JDK-10或JDK-11文档在哪里指定或描述了这种jlink行为?应该如何构造模块路径?

此外:30年前,当我用来在DEC PDP-11小型计算机上链接Fortran IV和Macro-11程序时,这种有序链接很常见。当我要放弃时,我想尝试摆弄jlink的顺序

module-info.java:

module TestFXord {
    requires javafx.controls;
    exports testfxord to javafx.graphics;
}

TestFXord.java:

package testfxord;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class TestFXord extends Application {

    @Override
    public void start(Stage primaryStage) {

        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction((ActionEvent event) -> {
            System.out.println("Hello World!");
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

不生成可运行图像的jlink命令

#! /bin/sh
<jdk-11-path>/bin/jlink --module-path <jdk-11-path>/jmods:<javafx-sdk-11-path>/lib/javafx.base.jar:<javafx-sdk-11-path>/lib/javafx.controls.jar:<javafx-sdk-11-path>/lib/javafx.graphics.jar:<javafx-jmods-11-path>:<path-to-projects>/TestFXord/dist/TestFXord.jar --add-modules TestFXord --strip-debug --launcher TestFXord=TestFXord/testfxord.TestFXord --output dist/jlink/TestFXord

jlink命令可构建可运行的映像。请注意,现在立即显示在它所依赖的位置之后。

#! /bin/sh
    <jdk-11-path>/bin/jlink --module-path <jdk-11-path>/jmods:<javafx-jmods-11-path>:<javafx-sdk-11-path>/lib/javafx.base.jar:<javafx-sdk-11-path>/lib/javafx.controls.jar:<javafx-sdk-11-path>/lib/javafx.graphics.jar:<path-to-projects>/TestFXord/dist/TestFXord.jar --add-modules TestFXord --strip-debug --launcher TestFXord=TestFXord/testfxord.TestFXord --output dist/jlink/TestFXord

我认为 jlink 逐步构建符号表,将符号映射到地址,从左至右在模块路径中向下工作,并解析(查找地址)具有地址的符号,并添加找到的新符号条目,这些符号条目可用于解决以后的模块中的调用。如果模块路径顺序正确,则在此过程中将解析每个符号。如果模块路径的顺序不正确,将存在尚未解析的符号。在运行映像时,用户将必须添加模块来解决剩余的符号。

换句话说,我不认为jlink会回到列表中来解析刚发现的早期模块中的符号。考虑一下,我怀疑这样做的原因是,每次添加新模块时都要返回搜索未解析的符号,这对于大型应用程序将需要更长的链接过程。听起来对吗?

1 个答案:

答案 0 :(得分:2)

作为@AlanBateman said in his comment

  

-module-path指定的模块路径是目录或模块的路径。因此,如果您指定多个具有相同模块版本的位置,顺序就很重要。

在两个示例中,您都将--module-path中包含JavaFX JMOD文件和JavaFX JAR文件。区别在于您添加它们的顺序。

  • 工作示例:首先是 JMOD文件
    • jlink将使用JMOD文件中包含的模块
  • 非工作示例: JMOD文件为最后
    • jlink将使用JAR文件中包含的模块

JavaFX SDK附带的JAR文件不包含任何必要的本机代码。如果链接到JAR文件,则生成的图像将无法执行。

JMOD文件,但是, do 包含必要的本机代码。实际上,将本机代码与Java代码绑定在一起是实现JMOD格式的主要原因之一。来自JEP 261

  

新的JMOD格式超出了JAR文件的范围,将本机代码,配置文件和其他类型的数据(如果有的话)完全不自然地包含在JAR文件中。 JMOD文件用于打包JDK本身的模块;如果需要,开发人员还可以使用它们来打包自己的模块。

     

JMOD文件可以在编译时和链接时使用,但不能在运行时使用。为了在运行时支持它们,通常需要准备好即时提取和链接本机代码库。尽管这可能非常棘手,但在大多数平台上都是可行的,并且我们还没有看到很多需要此功能的用例,因此,为简单起见,我们选择限制此版本中JMOD文件的实用性。

使用jlink时,应链接JMOD文件(如果可用)。如果库不提供JMOD文件,则链接JAR文件。

话虽如此,您应该将JavaFX JAR文件从--module-path中完全删除-它们是不必要的,并且会引起混乱。