Как связать JRE в EXE для Java-приложения? Launch4j говорит, что "среда выполнения отсутствует или повреждена".
Я новичок в программировании на Java, но в целом знаком с тем, как все работает. Я хотел бы иметь возможность поместить как jar-файл, так и jre-файл в исполняемый файл Windows (exe), чтобы при его распространении клиенту не нужно было устанавливать JRE. Какую программу я должен использовать?
У меня есть launch4j, и он, кажется, делает именно то, что я хочу, но когда я пытаюсь запустить приложение, я получаю "Это приложение было настроено на использование связанной среды выполнения Java, но среда выполнения отсутствует или повреждена".
Я хочу, чтобы мое приложение было работоспособным, а не установщиком. По крайней мере, кто-нибудь может показать мне, как правильно связать JRE с launch4j?
6 ответов
Единственный способ собрать JRE - использовать Launch4J и Inno Setup Compiler.
Сначала создайте jre6
папка (например) в том же каталоге, что и ваш выходной файл (.exe).
Затем скопируйте JRE из вашей системы в папку jre6.
Затем вы открываете Launch4J и задаете путь к пакету JRE - просто введите jre6
, Затем нажмите кнопку "Построить" (очевидно, после того, как вы ввели все остальные параметры - но единственное значение, которое вам нужно ввести на самой вкладке JRE, - это значение Bundled JRE.)
Я ожидал бы, что это сработает, но если вы затем переместите.exe в новое место (чтобы он больше не находился в папке jre6), вы получите Это приложение было настроено на использование связанной среды выполнения Java, но Ошибка времени выполнения или ошибка при попытке запустить приложение...
Я играл с этим весь день, и я не мог заставить Launch4J включить JRE в файл.exe. На самом деле, на мой взгляд, плохо, так как их документация вообще не имеет отношения к этой проблеме.
Поэтому я решил использовать Inno Setup Compiler (ISC). Это приложение используется для упаковки вашего.exe в виде файла установщика Windows. Поэтому я добавил параметр в сценарий ISC, который копирует JRE в пакет установщика. Строка, которую я добавил к сценарию (в [Files]
раздел) было:
Source: "M:\Netbeans\MyApp\jre6\*"; DestDir: "{app}\jre6\"; Flags: recursesubdirs createallsubdirs
... немного обходного пути, но он добился цели.
Повторите все вышеперечисленные шаги, и вы должны быть отсортированы.
Простой способ упаковать jre в exe, который упакован lanch4j, - это использовать wrap.
warp-packer --arch windows-x64 --input_dir mycrt --exec run.bat --output single.exe
а затем остановить окна cmd при запуске exe.
editbin /subsystem:windows
деформация: https://github.com/dgiagio/warp
editbin: установлен VS
Демо:
Java Packager, входящий в состав JDK из JDK 7 (обновление 6), является официальным способом встраивания JRE вместе с вашим кодом в собственный исполняемый файл. Кажется, что какой-то плагин maven решает задачу упаковки и создания собственного исполняемого файла для основных форм пластины.
Из JDK11 нужно будет загрузить java packager в соответствии с java-packager-with-jdk11, который демонстрирует упаковку с использованием gradle
Комплексное решение JRE для установки Inno
Чтобы реализовать связанное решение JRE с приложением jar, я создал скрипт Inno Setup, который:
1) копирует JRE в установочный exe
2) выполняет эквивалент команды терминала: java -jar myjar.jar, используя связанный JRE
Сначала я копирую JRE:
#define MyJREPath "C:\Program Files\Java\jre1.8.0_191"
[Files]
Source: "{#MyJREPath}\*"; DestDir: "{app}\runtime\jre\"; \
Flags: ignoreversion recursesubdirs createallsubdirs;
Я придерживаюсь соглашения о структуре каталогов, показанного здесь: https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/self-contained-packaging.html
Чтобы запустить эквивалент java -jar myjar.jar:
[Run]
Filename: "{app}\runtime\jre\bin\javaw.exe"; Parameters: " -jar myjar.jar"; \
WorkingDir: "{app}\app\"; \
Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
Flags: postinstall skipifsilent
(nb java.exe работает с терминалом, а javaw.exe работает без терминала)
Ярлык на рабочем столе должен иметь правильное имя файла, параметры и рабочий каталог:
[Icons]
Name: "{commondesktop}\{#MyAppName}"; \
IconFilename: "{app}\app\{#MyAppIcoName}"; \
Filename: "{app}\runtime\jre\bin\javaw.exe"; \
Parameters: " -jar myjar.jar"; \
WorkingDir: "{app}\app\"; \
Tasks: desktopicon
[Tasks]
Name: "desktopicon"; \
Description: "{cm:CreateDesktopIcon}"; \
GroupDescription: "{cm:AdditionalIcons}"; \
Flags: unchecked
Для того, чтобы обледенеть торт, чтобы мой сценарий обрабатывал как связанные JRE, так и никакие связанные параметры, я использую инструкцию IF препроцессора (дублируется в каждом разделе сценария), чтобы проверить, имеет ли сценарий пустой MyJREPath или нет. Если MyJREPath не пуст и поэтому требуется комплексное решение JRE, я использую приведенную выше кодировку; в качестве альтернативы, если пакетное решение не требуется, тогда я использую более "нормальное" кодирование, показанное в примерах установки Inno или созданное их мастером. Вот заявление IF:
#if MyJREPath != ""
; bundled JRE required
#else
; bundled JRE not required
#endif
Вот большая часть моего сценария вместе взятая:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
; some more #defines here
#define MyAppExeName "javaw.exe"
#define MyJREPath "C:\Program Files\Java\jre1.8.0_191"
;#define MyJREPath ""
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId=XXXXXXXXXX
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
DefaultGroupName={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyDefaultDirName}
DisableProgramGroupPage=yes
LicenseFile={#MyInnoSetupDir}\system\{#MyLicenseFile}
OutputDir={#MyInnoSetupDir}
#if MyJREPath != ""
; run app with bundled JRE
OutputBaseFilename={#MyAppName}-{#MyAppVersion}-bundledJRE-setup
#else
; run app without bundled JRE
OutputBaseFilename={#MyAppName}-{#MyAppVersion}-setup
#endif
SetupIconFile={#MyInnoSetupDir}\{#MyAppIcoName}
Compression=lzma
SolidCompression=yes
AppComments={#MyAppName}
AppCopyright={#MyAppCopyright}
UninstallDisplayIcon={#MyInnoSetupDir}\{#MyAppIcoName}
UninstallDisplayName={#MyAppName}
WizardImageStretch=No
WizardSmallImageFile={#MyInnoSetupDir}\{#MyAppBmpName}
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
;Name: "german"; MessagesFile: "compiler:Languages\German.isl"
[Tasks]
Name: "desktopicon"; \
Description: "{cm:CreateDesktopIcon}"; \
GroupDescription: "{cm:AdditionalIcons}"; \
Flags: unchecked
Name: "quicklaunchicon"; \
Description: "{cm:CreateQuickLaunchIcon}"; \
GroupDescription: "{cm:AdditionalIcons}"; \
Flags: unchecked; OnlyBelowVersion: 0,6.1
[Files]
; bundle JRE if required
#if MyJREPath != ""
Source: "{#MyJREPath}\*"; DestDir: "{app}\runtime\jre\"; \
Flags: ignoreversion recursesubdirs createallsubdirs;
#endif
; copy jar and all files
Source: "{#MyInnoSetupDir}\*"; DestDir: "{app}\app\"; \
Flags: ignoreversion recursesubdirs createallsubdirs
[Icons]
#if MyJREPath != ""
; set up icons with bundled JRE
Name: "{commonprograms}\{#MyAppName}"; \
IconFilename: "{app}\app\{#MyAppIcoName}"; \
Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; \
Parameters: " -jar {#MyJarName}"; \
WorkingDir: "{app}\app\"
Name: "{commondesktop}\{#MyAppName}"; \
IconFilename: "{app}\app\{#MyAppIcoName}"; \
Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; \
Parameters: " -jar {#MyJarName}"; \
WorkingDir: "{app}\app\"; \
Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; \
IconFilename: "{app}\app\{#MyAppIcoName}"; \
Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; \
Parameters: " -jar {#MyJarName}"; \
WorkingDir: "{app}\app\"; \
Tasks: quicklaunchicon
#else
; set up icons without bundled JRE
Name: "{commonprograms}\{#MyAppName}"; \
IconFilename: "{app}\app\{#MyAppIcoName}"; \
Filename: "{app}\app\{#MyJarName}"; \
WorkingDir: "{app}\app\"
Name: "{commondesktop}\{#MyAppName}"; \
IconFilename: "{app}\app\{#MyAppIcoName}"; \
Filename: "{app}\app\{#MyJarName}"; \
WorkingDir: "{app}\app\"; \
Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; \
IconFilename: "{app}\app\{#MyAppIcoName}"; \
Filename: "{app}\app\{#MyJarName}"; \
WorkingDir: "{app}\app\"; \
Tasks: quicklaunchicon
#endif
[Run]
#if MyJREPath != ""
; run app with bundled JRE
Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; Parameters: " -jar {#MyJarName}"; \
WorkingDir: "{app}\app\"; \
Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
Flags: postinstall skipifsilent
#else
; run app without bundled JRE
Filename: "{app}\app\{#MyJarName}"; \
WorkingDir: "{app}\app\"; \
Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
Flags: shellexec postinstall skipifsilent
#endif
Надеюсь это поможет.
Я никогда не использовал продукт Launch4J, удачи в правильной настройке.
Похоже, вы могли бы пойти на дискуссионный форум по Sourceforge для других подсказок здесь
Другие предложения:
Большинство продуктов, которые я видел в IBM (Websphere) и Oracle, просто извлекают JRE из каталога установки и настраивают пакетную команду запуска для использования установленной JRE. По сути, JRE и ваш файл jar будут установлены за один раз.
Установочный exe обычно проверяет, установлен ли он уже, и пропускает этот шаг, если находит его там. Это полезно для обновления только файла JAR.
Локальная установка также решает проблему установки клиентом собственной JRE, которая может быть несовместимой или содержать ошибки. Таким образом, вы имеете дело с известной версией JRE.
Маршрут эксельсиора в порядке, если у вас нет графического компонента в приложении (это было давно, это ограничение могло измениться). Есть и другие ограничения, но вам, вероятно, лучше просто распространять JRE с вашим кодом в одном исполняемом установщике.
Кажется, вам нужен компилятор нативного кода. Эти компиляторы создают собственный код, который не требует JRE.
Проверьте эту статью - https://www.excelsior-usa.com/articles/java-to-exe.html.
Его легко собрать JR в launch4j..
просто скопируйте JRE в ту же папку вывода
В текстовом поле окружения bundle jre просто укажите саму папку jre
В текстовом поле переменной среды (присутствует на той же странице ниже), дайте до бен
Затем создайте exe.. Он работает как положено без JRE в машине.
Спасибо
То, о чем вы просите, будет нелегко сделать (если это вообще выполнимо). На вашем месте я бы занялся созданием исполняемого файла JAR:
java eclipse создать исполняемый jar
Другой вариант - использовать Java Web Start. Предполагалось, что вы используете современный браузер, JNLP автоматически предложит пользователю установить правильную версию Java.
http://docs.oracle.com/javase/tutorial/deployment/webstart/index.html
Есть несколько причин, по которым launch4j не будет работать гладко. некоторые из причин:
1) пользователь не запускает приложение от имени администратора
2) Пользователь неправильно настроил изображение значка. должен строго.ico