Я экспериментировал с переносом своих программ на jlink с помощью экспериментов с Hello World и Hello JFX World. Кажется, что в примерах, которые я использовал, указано - add-modules , когда дело доходит до запуска программы. Я не понимаю, почему программе требуется информация, предоставляемая во время выполнения, которую она имела во время jlink.
Теперь я успешно создал простую jlink программу Hello World, которая будет работать без - add-modules в командной строке. Хитрость заключалась в том, чтобы изменить порядок модулей, указанных в пути модуля jlink. Я не знаю, почему это сработало.
Где это поведение jlink указано или описано в документации JDK-9, JDK-10 или JDK-11? Как следует строить модуль-путь?
В сторону: этот вид упорядоченного связывания был обычным явлением 30 лет назад, когда я использовал для связывания программ Fortran IV и Macro-11 на миникомпьютере DEC PDP-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 возвращается в список для разрешения символов в более ранних модулях, которые он только что обнаружил. Размышляя об этом, я подозреваю, что причина этого заключается в том, что для поиска неразрешенных символов каждый раз, когда вы добавляете новый модуль, потребуется гораздо более длительный процесс связывания для больших приложений. Это звучит примерно так?