Является ли jlink --module-path упорядоченным путем? - PullRequest
0 голосов
/ 10 ноября 2018

Я экспериментировал с переносом своих программ на 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 возвращается в список для разрешения символов в более ранних модулях, которые он только что обнаружил. Размышляя об этом, я подозреваю, что причина этого заключается в том, что для поиска неразрешенных символов каждый раз, когда вы добавляете новый модуль, потребуется гораздо более длительный процесс связывания для больших приложений. Это звучит примерно так?

1 Ответ

0 голосов
/ 12 ноября 2018

Как сказал @AlanBateman в своем комментарии :

Путь к модулю, указанный в --module-path, является путем к каталогам или модулям. Таким образом, порядок имеет значение, если указать несколько местоположений, которые имеют разные версии одного и того же модуля.

В обоих ваших примерах вы включаете файлы JavaFX JMOD и JavaFX JAR в --module-path. Разница в том, что вы их включили.

  • Рабочий пример: Сначала JMOD-файлы .
    • jlink будет использовать модули, содержащиеся в файлах JMOD
  • Нерабочий пример: Последние файлы JMOD .
    • jlink будет использовать модули, содержащиеся в файлах JAR

Файлы JAR, поставляемые с JavaFX SDK, не содержат необходимого собственного кода. Если вы ссылаетесь на файлы JAR, результирующее изображение не будет выполнено.

Файлы JMOD, однако, do содержат необходимый собственный код. Фактически, объединение нативного кода с Java-кодом является одной из основных причин, по которым был реализован формат JMOD. С JEP 261 :

Новый формат JMOD выходит за рамки файлов JAR и включает собственный код, файлы конфигурации и другие виды данных, которые не вписываются в файлы JAR естественным образом или вообще не помещаются. Файлы JMOD используются для упаковки модулей самого JDK; при желании они также могут использоваться разработчиками для упаковки своих собственных модулей.

Файлы JMOD могут использоваться во время компиляции и во время компоновки, но не во время выполнения. Как правило, для их поддержки во время выполнения мы должны быть готовы извлекать и связывать библиотеки нативного кода на лету. Это выполнимо на большинстве платформ, хотя это может быть очень сложно, и мы не видели много вариантов использования, которые требуют этой возможности, поэтому для простоты мы решили ограничить полезность файлов JMOD в этом выпуске.

При использовании jlink вы должны ссылаться на файлы JMOD, если они доступны. Если библиотека не предоставляет файлы JMOD, тогда создайте ссылку на файлы JAR.

С учетом всего вышесказанного вы должны полностью удалить файлы JAR JavaFX из --module-path - они не нужны и вызывают путаницу.

...