我一直在尝试通过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会回到列表中来解析刚发现的早期模块中的符号。考虑一下,我怀疑这样做的原因是,每次添加新模块时都要返回搜索未解析的符号,这对于大型应用程序将需要更长的链接过程。听起来对吗?
答案 0 :(得分:2)
作为@AlanBateman said in his comment:
-module-path指定的模块路径是目录或模块的路径。因此,如果您指定多个具有相同模块版本的位置,顺序就很重要。
在两个示例中,您都将--module-path
中包含JavaFX JMOD文件和JavaFX JAR文件。区别在于您添加它们的顺序。
jlink
将使用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
中完全删除-它们是不必要的,并且会引起混乱。