我一直在尝试通过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会回到列表中来解析刚刚发现的早期模块中的符号。考虑一下,我怀疑这样做的原因是,每次添加新模块时都要返回搜索未解析的符号,这对于大型应用程序将需要更长的链接过程。那个听起来是对的吗?
最佳答案
作为@AlanBateman said in his comment:
指定给--module-path的模块路径是目录或模块的路径。因此,如果您指定多个具有相同模块版本的位置,顺序就很重要。
在两个示例中,您都在--module-path
中包含JavaFX JMOD文件和JavaFX JAR文件。区别在于您添加它们的顺序。
工作示例:首先是JMOD文件。jlink
将使用JMOD文件中包含的模块
非工作示例:JMOD文件位于最后。jlink
将使用JAR文件中包含的模块
JavaFX SDK附带的JAR文件不包含任何必需的本机代码。如果链接到JAR文件,则生成的图像将无法执行。
但是,JMOD文件确实包含必要的本机代码。实际上,将本机代码与Java代码绑定在一起是实现JMOD格式的主要原因之一。从JEP 261:
新的JMOD格式超出了JAR文件的范围,包括了本机代码,配置文件和其他类型的数据,这些数据根本无法自然地适应JAR文件。 JMOD文件用于打包JDK本身的模块;如果需要,开发人员也可以使用它们来打包自己的模块。
JMOD文件可以在编译时和链接时使用,但不能在运行时使用。为了在运行时支持它们,通常需要准备好即时提取和链接本机代码库。尽管这可能非常棘手,但在大多数平台上都是可行的,并且我们还没有看到许多需要此功能的用例,因此,为简单起见,我们选择限制此发行版中JMOD文件的实用性。
使用jlink
时,应在可用的位置链接到JMOD文件。如果库不提供JMOD文件,则链接JAR文件。
综上所述,您应该将JavaFX JAR文件从--module-path
完全删除-它们是不必要的,并且会引起混乱。
关于java - jlink --module-path是否为有序路径?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53240219/