如何将JRE捆绑到Java应用程序的EXE中? Launch4j说“运行时丢失或损坏。”

时间:2012-12-21 20:07:22

标签: jar exe java launch4j

我是Java编程的新手,但我一般都熟悉一切是如何工作的。我希望能够将一个jar文件和一个jre放入一个Wi​​ndows可执行文件(exe)中,这样当我分发它时,客户端不需要安装JRE。我应该使用什么程序?

我有launch4j,它似乎正是我想要的,但当我尝试运行应用程序时,我得到“这个应用程序配置为使用捆绑的Java运行时环境,但运行时丢失或损坏。”

我希望我的应用程序只是一个可运行的exe,而不是安装程序。至少,任何人都可以告诉我如何正确地将JRE与launch4j捆绑在一起吗?

9 个答案:

答案 0 :(得分:34)

我捆绑JRE的唯一方法是使用Launch4JInno Setup Compiler

首先,在与输出文件(.exe)相同的目录中创建一个jre6文件夹。

然后将JRE从您的系统复制到 jre6 文件夹中。

然后打开Launch4J并设置捆绑的JRE路径 - 只需输入jre6即可。然后单击“构建”按钮(显然,在您输入所有其他参数后 - 但您需要在 JRE 选项卡上输入的唯一值是捆绑的JRE路径价值。)

我原本希望这样做,但如果您将.exe移动到新位置(因此它不再与您的 jre6 文件夹位于同一位置),您将获得当您尝试运行应用程序时,此应用程序配置为使用捆绑的Java运行时环境但运行时丢失或损坏错误...

我整天都玩这个,但我无法让 Launch4J 将JRE包含在.exe文件中。我认为真的很差,因为他们的文档似乎根本没有提到这个问题。

所以我要解决的是使用 Inno Setup Compiler(ISC)。此应用程序用于将.exe包装为Windows Installer文件。所以我在ISC脚本中添加了一个设置,将JRE复制到安装程序包中。我添加到脚本中的行(在[Files]部分中)是:

Source: "M:\Netbeans\MyApp\jre6\*"; DestDir: "{app}\jre6\"; Flags: recursesubdirs createallsubdirs

...有点解决方法,但它确实有效。

重复上述所有步骤,您应该进行排序。

答案 1 :(得分:1)

我从未使用过Launch4J产品,祝它正确配置好。

看起来您可以访问Sourceforge上的论坛获取其他提示here

其他建议:

我从IBM(Websphere)和Oracle看到的大多数产品只是在安装目录下提取JRE并配置startup batch命令以使用已安装的JRE。基本上JRE和你的jar文件将一次性安装。

安装exe通常检查它是否已经安装,如果发现它已经存在,则跳过该步骤。这对于仅升级jar文件很有用。

本地安装还解决了客户安装自己的JRE的问题,这些JRE可能不兼容或包含错误。这样你就可以处理一个已知的JRE版本了。

如果您的应用程序没有图形组件,那么excelsior路线就可以了(已经有一段时间了,这个限制可能已经改变了)。还有其他限制,但您最好只在单个可执行安装程序中使用代码分发JRE。

答案 2 :(得分:0)

您似乎需要本机代码编译器。这些编译器生成不需要JRE的本机代码。

查看此文章 - https://www.excelsior-usa.com/articles/java-to-exe.html#aot

答案 3 :(得分:0)

很容易将jre捆绑到launch4j ..

将jre复制到相同的输出文件夹

在捆绑jre环境文本框中,只需给jre文件夹本身

在环境变量文本框中(显示在下面的同一页面中),直到bin

然后创建exe ..它按预期工作,没有机器中的jre。

由于

答案 4 :(得分:0)

用于Inno设置的捆绑JRE解决方案

为了用应用程序jar实施捆绑的JRE解决方案,我创建了一个Inno Setup脚本,该脚本:

1)将JRE复制到安装exe

2)使用捆绑的JRE执行等效的终端命令:java -jar myjar.jar

首先,我复制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   

(n.b。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和无捆绑的选项 我使用Preprocessor IF语句(在每个脚本部分重复)来测试脚本是否具有 是否为空MyJREPath。如果MyJREPath不为空,则为捆绑的JRE解决方案 需要我使用上面的编码;或者,如果不需要捆绑的解决方案 然后我使用Inno Setup示例中显示的或由其向导生成的更多“常规”编码。这是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 

希望这会有所帮助。

答案 5 :(得分:0)

将lanch4j打包到exe的简单方法是使用wrap。

warp-packer --arch windows-x64 --input_dir mycrt --exec run.bat --output single.exe

然后在启动exe时停止cmd Windows。

editbin /subsystem:windows

弯曲https://github.com/dgiagio/warp

editbin :由VS安装

演示:

enter image description here

enter image description here

答案 6 :(得分:0)

JDK 7 Update 6中的JDK附带的Java Packager 是official way,可将JRE和您的代码嵌入本机可执行文件中。 Some maven plugin似乎打包了主要平台的打包和生成本机可执行文件的任务。

需要根据java-packager-with-jdk11从JDK11下载Java打包程序,巫婆演示了使用gradle进行打包

答案 7 :(得分:-2)

你所要求的并不容易(如果可行的话)。如果我是你,我会考虑创建一个可执行的JAR文件:

java eclipse create executable jar

另一种选择是使用Java Web Start。假设您正在使用现代浏览器,JNLP将自动提示用户安装正确版本的Java。

http://docs.oracle.com/javase/tutorial/deployment/webstart/index.html

答案 8 :(得分:-3)

为什么launch4j不能顺利运行有几个原因。一些原因是:

1)用户不以管理员身份运行应用程序

2)用户未正确设置图标图像。必须严格.ico