Измените реализацию JavaFX 11 в IntelliJ с «сборки и запуска с параметрами jvm внутри IDE» на «создать образ времени выполнения» - PullRequest
0 голосов
/ 28 мая 2020

РЕДАКТИРОВАТЬ №3 (РЕШЕНИЕ)

Я решил эту проблему, не используя ни один из предложенных ответов. В конце у меня есть несколько папок и файлов, которые я могу заархивировать и отправить, которые не требуют установки java и которые можно запустить, дважды щелкнув .bat-файл. Для меня сработала следующая процедура:

  • Создать новый проект Gradle с нуля

  • Добавить все модули / код в src / main / java папка

  • создать AppLauncher. java, который вызывает основной метод

  • перемещает все fxml / css изнутри из папок java в папку ресурсов

  • убедитесь, что ваши вызовы f xml - / css -файлы не подвергаются ошибочному рефакторингу, и используйте следующий код :

//Main start method
Parent root = FXMLLoader.load(new File("fxml/main.fxml").toURI().toURL());

//Other FXML loading operations
FXMLLoader loader = null;
try { loader = new FXMLLoader(new File("fxml/GRAPHISO_proof.fxml").toURI().toURL()); }
...

и для таблиц стилей:

scene.getStylesheets().add("file:///" + new File("css/text-field-red-border.css").getAbsolutePath().replace('\\', '/'));
  • создать module-info.java внутри папки src / main / java со следующей структурой:
module XYZ {
    requires javafx.controls;
    requires javafx.graphics;
    requires java.desktop;
    requires javafx.fxml;
    requires javafx.base;

    opens main.controller to javafx.fxml;
    //Open ALL controller-modules (all of my modules have a controller-submodule, e.g. main/controller, dlog/controller, graphiso/controller, ...) to javafx.fxml
    //...

    exports main;
}
  • убедитесь, что gradle / wrapper / gradle-wrapper.properties установлен на не очень старую версию gradle (distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip)

  • используйте это в качестве build.gradle:

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath 'org.openjfx:javafx-plugin:0.0.8'
        classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'
    }
}

plugins {
    id 'java'
    id 'org.beryx.jlink' version '2.19.0'
}

apply plugin: 'org.openjfx.javafxplugin'
apply plugin: 'com.github.johnrengelman.shadow'

group 'org.example.abc'
version '1.0'

sourceCompatibility = 1.14

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

javafx {
    sdk = 'C:\\Program Files\\Java\\javafx-sdk-14.0.1'
    modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.base' ]
}

jlink {
    mainClassName = 'main.AppLauncher'
    launcher {
        name = 'Whatever you want as name'
    }
}

tasks.jlink.doLast {
    copy {
        from('src/main/resources')
        into("$buildDir/image/bin")
    }
    copy {
        from 'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\glass.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\javafx_font.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\prism_d3d.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\prism_sw.dll'
        into("$buildDir/image/bin")
    }
}

Обратите внимание, как я включил некоторые dll-файлы в tasks.jlink.doLast. Без них программа продолжает давать сбой и обращается к QuantumRenderer.

  • установите двоичные файлы openjdk-14.0.1 и соответствующим образом установите% JAVA_HOME%, также установите openjfx-14.0.1 (программе требуются некоторые библиотеки DLL, как указано выше)

Исходный вопрос

Я пытаюсь создать образ времени выполнения из проекта, который я реализовал в JavaFX 11, просто используя функциональность «конфигурации запуска» в IntelliJ. Мне кажется, что большой проблемой здесь является то, что мои знания maven / gradle практически отсутствуют, и что эти инструменты сборки имеют решающее значение на этом этапе.

Внутри C:\Program Files\Java Я установил:

  • javafx-sdk-11.0.2 и
  • jdk-13.0.2

Я настроил параметры виртуальной машины внутри «конфигурации запуска» IntellJ как --module-path "C:\Program Files\Java\javafx-sdk-11.0.2\lib" --add-modules javafx.controls,javafx.fxml и установил основной класс в "main.Main".

Моя структура проекта выглядит так: Структура папок проекта

Выделенный Main. java - это обычный Main-файл (расширяющий Приложение, вызывающее запуск (args) внутри main). Он может загружать другие windows, находящиеся в других пакетах. Это не Launcher-файл, который не расширяет приложение и вызывает фактический основной файл (как это предлагается несколькими решениями для построения градиентов).

Первоначально я пробовал чтобы получить .jar-файл, который можно запустить без дополнительных параметров на Windows и Linux. После некоторого чтения я решил, что это не будет чистым решением, и многие источники заявили, что в современных решениях файлы .jar будут объединены и отправлены с файлом .bat /.sh, который включает все необходимые параметры. .

Мой вопрос: как мне лучше действовать и какие конфигурации / дополнительные файлы мне нужны, чтобы преобразовать этот проект «кликни для запуска внутри IDE» в «автономное приложение», которое я могу поделиться по электронной почте или аналогичным образом?

Я попытался создать новый проект Gradle через IntelliJ (следуя https://openjfx.io/openjfx-docs) и скопировал исходные файлы в src / main / java. Затем я опробовал предоставленный файл build.gradle и - после того, как это не сработало - внес некоторые изменения, предложенные различными блогами / форумами / et c. Ни один из них не позволял мне запускать проект через IntelliJ или из командной строки.

Большинство из этих подходов позволяют мне построить проект, но при попытке запустить с помощью «gradlew run» или вызова «java -jar file.jar "Я получаю сообщения об ошибках из-за исключений классов или сообщения о том, что мне все еще не хватает модулей javafx. Я также пробовал преобразовать мой текущий проект в проект gradle, но это даже не позволило мне впоследствии построить проект.


EDIT # 1 (JPackageScriptFX)

Я просмотрел ссылку на JPackageScriptFX. Теперь я получаю установщик (использующий mvn clean install), который работает на моем компьютере, но при запуске полученного исполняемого файла я получаю сообщение об ошибке «Не удалось запустить JVM».

Что я сделал для этого far is:

  • установлен jdk-14.0.1 и установлен JAVA_HOME, установлен wix311

  • создан новый проект IntelliJ maven под названием "bachelor_maven"

  • удален исходный sr c -папка

  • добавлен новый модуль «ZKP_Inspector» и мои старые модули внутри полученного src / main / java папка

  • добавлены и отредактированы src / main / logo / windows / duke.ico, два файла pom. xml и build_app.bat из JPackageScriptFX

  • реализован AppLauncher. java, который вызывает Main. java

Мои файлы конфигурации:

  • Новая структура проекта: Imgur

  • pom. xml (Уровень проекта, bachelor_maven): Pastebin

    * 1 144 *
  • пом. xml (уровень модуля, ZKP_Inspector): Pastebin

  • build_app.bat: Pastebin


EDIT # 2

Я попытался удалить --runtime-image target/java-runtime ^ из параметров jpackage в файле build_app.bat, чтобы позволить jpackage решать, что включить. Это увеличило размер файла установщика (как и ожидалось), но привело к той же ошибке при попытке выполнить полученную программу.

Я также загрузил файлы JMOD и использовал их в задаче jlink в build_app. bat, как указано здесь .

Итак, я заменил --add-modules %detected_modules%,%manual_modules% ^ на

--module-path "C:\Program Files\Java\javafx-jmods-11.0.2" --add-modules %detected_modules%,%manual_modules%,javafx.controls,javafx.fxml

Это создало еще один установщик, который работал нормально и чья программа выкинул ту же ошибку.

Ответы [ 3 ]

1 голос
/ 29 мая 2020

Хорошо, я попытаюсь показать, как этого добиться, используя только jlink . Предположим, у нас есть пример проекта в каталоге 'C: \ Users \ Alexiy \ IdeaProjects \ AnotherBuildTool \ rundir'. Его структура:

/rundir
--classes [compilation output]
--source  [source code]
--images  [runtime image output]

У меня есть класс 'source \ io \ github \ alexiyorlov \ Calculator \ Program. java':

package io.github.alexiyorlov.calculator;

import javafx.application.Application;
import javafx.stage.Stage;
import java.nio.file.Path;
public class Program extends Application {

   @Override
   public void start(Stage primaryStage) throws Exception {
       System.out.println("I'm a simple application");
       primaryStage.show();
   }
}

И соответствующий 'source \ module-info. java ':

module io.github.alexiyorlov{
   requires javafx.controls;
   requires javafx.graphics;
   exports io.github.alexiyorlov.calculator;
}

Если я хочу сделать из этого образ времени выполнения, синтаксис команды jlink будет таким:

jlink --launcher [имя для сценария запуска] = [ссылка на основной класс] --module-path '[разделенный список файлов зависимостей проекта + каталог вывода компиляции]' --add-modules [my ссылка на модуль] --compress = 2 --output [каталог для результирующего образа среды выполнения]

Итак, для моего примера проекта он преобразуется в эту команду:

jlink 
--launcher launch=io.github.alexiyorlov/io.github.alexiyorlov.calculator.Program 
--module-path 'C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-controls\11.0.2\javafx-controls-11.0.2-win.jar;C:\Users\Alexiy\.m2\repository\org\junit\jupiter\junit-jupiter-engine\5.7.0-M1\junit-jupiter-engine-5.7.0-M1.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-base\11.0.2\javafx-base-11.0.2.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-base\11.0.2\javafx-base-11.0.2-win.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-graphics\11.0.2\javafx-graphics-11.0.2.jar;C:\Users\Alexiy\.m2\repository\dev\buildtool\json-tools\0.1.0\json-tools-0.1.0.jar;C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir\org\openjfx\javafx\11.0.2\javafx-11.0.2/.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-controls\11.0.2\javafx-controls-11.0.2.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-graphics\11.0.2\javafx-graphics-11.0.2-win.jar;C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir/classes' 
--add-modules io.github.alexiyorlov 
--compress=2 
--output .\images\0.0.1

It создаст изображение в каталоге images \ 0.0.1 со стартовыми скриптами 0.0.1 \ bin \ launch.

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

- add-modules указывает, какие модули вашего приложения нужно включить.

- output указывает каталог для размещения всех файлов изображения.

- программа запуска указывает имя скриптов запуска и правильную ссылку на основной класс после '='.

- compress = 2 заставляет применить сжатие ZIP к изображению .

Не стесняйтесь запрашивать у меня дополнительную информацию.

0 голосов
/ 29 мая 2020

Я решил эту проблему, используя почти самодельное решение. В конце у меня есть несколько папок и файлов, которые я могу заархивировать и отправить, которые не требуют установки java и которые можно запустить двойным щелчком по файлу .bat. Для меня сработала следующая процедура:

  • Создать новый проект Gradle с нуля

  • Добавить все модули / код в src / main / java папка

  • создать AppLauncher. java, который вызывает основной метод

  • перемещает все fxml / css изнутри из папок java в папку ресурсов

  • убедитесь, что ваши вызовы f xml - / css -файлов не подвергаются ошибочному рефакторингу, и используйте следующий код :

//Main start method
Parent root = FXMLLoader.load(new File("fxml/main.fxml").toURI().toURL());

//Other FXML loading operations
FXMLLoader loader = null;
try { loader = new FXMLLoader(new File("fxml/GRAPHISO_proof.fxml").toURI().toURL()); }
...

и для таблиц стилей:

scene.getStylesheets().add("file:///" + new File("css/text-field-red-border.css").getAbsolutePath().replace('\\', '/'));
  • создать module-info.java внутри папки src / main / java со следующей структурой:
module XYZ {
    requires javafx.controls;
    requires javafx.graphics;
    requires java.desktop;
    requires javafx.fxml;
    requires javafx.base;

    opens main.controller to javafx.fxml;
    //Open ALL controller-modules (all of my modules have a controller-submodule, e.g. main/controller, dlog/controller, graphiso/controller, ...) to javafx.fxml
    //...

    exports main;
}
  • убедитесь, что gradle / wrapper / gradle-wrapper.properties установлен на не очень старую версию gradle (distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip)

  • используйте это как build.gradle:

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath 'org.openjfx:javafx-plugin:0.0.8'
        classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'
    }
}

plugins {
    id 'java'
    id 'org.beryx.jlink' version '2.19.0'
}

apply plugin: 'org.openjfx.javafxplugin'
apply plugin: 'com.github.johnrengelman.shadow'

group 'org.example.abc'
version '1.0'

sourceCompatibility = 1.14

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

javafx {
    sdk = 'C:\\Program Files\\Java\\javafx-sdk-14.0.1'
    modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.base' ]
}

jlink {
    mainClassName = 'main.AppLauncher'
    launcher {
        name = 'Whatever you want as name'
    }
}

tasks.jlink.doLast {
    copy {
        from('src/main/resources')
        into("$buildDir/image/bin")
    }
    copy {
        from 'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\glass.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\javafx_font.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\prism_d3d.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\prism_sw.dll'
        into("$buildDir/image/bin")
    }
}

Обратите внимание, как я включил некоторые dll-файлы в tasks.jlink.doLast. Без них программа продолжает давать сбой и обращается к QuantumRenderer.

  • установите двоичные файлы openjdk-14.0.1 и соответствующим образом установите% JAVA_HOME%, также установите openjfx-14.0.1 (программе требуются некоторые библиотеки DLL, как указано выше)
0 голосов
/ 28 мая 2020

У меня уже некоторое время была такая же проблема; c то, что IntelliJ не может развернуть приложение FX самостоятельно, является значительной проблемой.

Первый шаг, который я бы порекомендовал, если вы еще этого не сделали, - это создание стандартного файла Jar и его запуск. из командной строки вместе с необходимыми дополнительными аргументами:

java --module-path "C:\Program Files\Java\javafx-sdk-11.0.2\lib" --add-modules javafx.controls,javafx.fxml -jar your-jar.jar

Это просто для проверки того, что он запускается и работает. Я узнал, что просто потому, что он работает в среде IDE, это не означает, что ошибки не будут появляться при запуске JAR - лучше сначала проверить это.

Затем есть несколько способов можете достичь желаемого, и все это с разной степенью простоты и аккуратности.

  1. Как вы сказали, вы можете запустить файл .bat, чтобы запустить его. Это самый простой способ.
  2. Вы можете создать для него новый ярлык Windows; в поле целевого назначения поместите свою команду, которую вы бы поместили в файл bat, но включите полный путь к файлу javaw.exe и полный путь к файлу jar. Это решение более элегантно, чем приведенное выше, но по-прежнему требует двух файлов (ваш jar и ярлык)
  3. Вы можете попробовать использовать приложение под названием Launch4j . Он упаковывает банку и только необходимые компоненты вашей JVM в exe-файл, и вы также можете указать там аргументы виртуальной машины. Это дает дополнительное преимущество, заключающееся в том, что клиенту не требуется указанная c версия Java, поскольку вы по существу включаете ее в свой файл.
  4. Если вы действительно хотите упаковать только файл jar, это самый сложный способ, но он возможен. Я добился успеха с помощью следующей техники:

Во-первых, скомпилируйте jar-файл JavaFX как обычно, в дальнейшем он будет называться fx.jar. Затем создайте проект, отличный от JavaFX, в дальнейшем называемый nonfx.jar. Поместите fx.jar в папку src nonfx. При запуске nonfx он должен извлечь fx.jar из своего собственного архива, а затем запустить команду, которая открывает fx.jar с необходимыми аргументами виртуальной машины. По сути, nonfx - это контейнер для fx.jar. Чтобы удалить fx.jar после его закрытия, я бы рекомендовал создать задачу Windows, которая делает это из fx.jar.

Этот метод довольно утомителен и подвержен ошибкам, но он действительно работай. Вероятно, есть лучшие способы сделать это с помощью Gradle. Пока fx: deploy снова не будет включен в IntelliJ, обходные пути - лучшее, что у нас есть.

...