简体   繁体   English

将 JRE 与 gradle 中的 launch4j 应用程序捆绑在一起

[英]Bundling a JRE with a launch4j application in gradle

Background背景

I'm using the edu.sc.seis.launch4j plugin to build distributable applications using a gradle build script.我正在使用 edu.sc.seis.launch4j 插件使用 gradle 构建脚本构建可分发的应用程序。 I'm trying to produce these with a bundled JRE.我正在尝试使用捆绑的 JRE 生成这些。

This is the gradle script这是gradle脚本

plugins {
    id 'org.jetbrains.intellij' version '0.3.7'
    id 'java'
    id 'edu.sc.seis.launch4j' version '2.4.4'
}

group 'worldbuilders'
version '0.4.4-SNAPSHOT'

apply plugin: 'application'

sourceCompatibility = 1.8

repositories {
    jcenter()
    mavenCentral()
}

mainClassName = 'hello.HelloWorld'

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

intellij {
    version '2017.3.5'
}

launch4j {
    bundledJrePath = "jre" //my jre to use is in the projectRoot/jre folder but I think that's not what this parameter is for anyway
    mainClassName = 'hello.HelloWorld'
    bundledJre64Bit = true
    //icon = "${projectDir}/icons/myApp.ico"
}

Frustratingly this creates an application that runs (exe created by the gradle task createExe) but clearly doesn't have a JRE bundled in/next to it, presumably because it runs because it falls back to using the system jre, which makes testing things difficult.令人沮丧的是,这会创建一个运行的应用程序(由 gradle 任务 createExe 创建的 exe),但显然没有捆绑在其中/旁边的 JRE,大概是因为它运行是因为它回退到使用系统 jre,这使得测试变得困难. If I put a deliberately corrupted jre at /jre/ it still seems to run, which is even more confusing如果我把故意损坏的jre放在/jre/它似乎仍然运行,这更令人困惑

Question

How can i bundle a JRE with my exe distributable created using the gradle-launch4j plugin?如何将 JRE 与使用 gradle-launch4j 插件创建的 exe 发行版捆绑在一起? (And that is actually used by the exe rather than using the system jre) (而且实际上是由exe使用而不是使用系统jre)

Additional information附加信息

The debug XML created by the plugin (that is consumed by launch4j):插件创建的调试 XML(由 launch4j 使用):

Created with the command gradle createExe -Pl4j-debug使用命令gradle createExe -Pl4j-debug

<?xml version='1.0' encoding='UTF-8'?>
<launch4jConfig>
  <dontWrapJar>false</dontWrapJar>
  <headerType>gui</headerType>
  <jar>lib/onemillionworlds-0.4.4-SNAPSHOT.jar</jar>
  <outfile>onemillionworlds.exe</outfile>
  <errTitle></errTitle>
  <cmdLine></cmdLine>
  <chdir>.</chdir>
  <priority>normal</priority>
  <downloadUrl>http://java.com/download</downloadUrl>
  <supportUrl></supportUrl>
  <stayAlive>false</stayAlive>
  <restartOnCrash>false</restartOnCrash>
  <manifest></manifest>
  <icon></icon>
  <classPath>
    <mainClass>hello.HelloWorld</mainClass>
    <cp>lib\onemillionworlds-0.4.4-SNAPSHOT.jar</cp>
    <cp>lib\tools.jar</cp>
    <cp>lib\jme3-lwjgl-3.2.0-stable.jar</cp>
    <cp>lib\jme3-desktop-3.2.0-stable.jar</cp>
    <cp>lib\jme3-core-3.2.0-stable.jar</cp>
    <cp>lib\lwjgl-2.9.3.jar</cp>
    <cp>lib\lwjgl-platform-2.9.3-natives-windows.jar</cp>
    <cp>lib\lwjgl-platform-2.9.3-natives-linux.jar</cp>
    <cp>lib\lwjgl-platform-2.9.3-natives-osx.jar</cp>
    <cp>lib\jinput-2.0.5.jar</cp>
    <cp>lib\jutils-1.0.0.jar</cp>
    <cp>lib\jinput-platform-2.0.5-natives-linux.jar</cp>
    <cp>lib\jinput-platform-2.0.5-natives-windows.jar</cp>
    <cp>lib\jinput-platform-2.0.5-natives-osx.jar</cp>
  </classPath>
  <jre>
    <path>jre</path>
    <bundledJre64Bit>true</bundledJre64Bit>
    <bundledJreAsFallback>false</bundledJreAsFallback>
    <minVersion>1.8.0</minVersion>
    <maxVersion></maxVersion>
    <jdkPreference>jdkOnly</jdkPreference>
    <runtimeBits>64/32</runtimeBits>
  </jre>
  <versionInfo>
    <fileVersion>0.0.0.1</fileVersion>
    <txtFileVersion>unspecified</txtFileVersion>
    <fileDescription>onemillionworlds</fileDescription>
    <copyright>unknown</copyright>
    <productVersion>0.0.0.1</productVersion>
    <txtProductVersion>unspecified</txtProductVersion>
    <productName>onemillionworlds</productName>
    <companyName></companyName>
    <internalName>onemillionworlds</internalName>
    <originalFilename>onemillionworlds.exe</originalFilename>
    <trademarks></trademarks>
    <language>ENGLISH_US</language>
  </versionInfo>
</launch4jConfig>

Pragmatic answer务实的回答

Looking at this with 2 years distance I realise my question was effectively "I want Launch4J to behave exactly like a bat file".以 2 年的距离来看这个,我意识到我的问题实际上是“我希望 Launch4J 的行为与 bat 文件完全一样”。 For the linux release I used the linux equivalent of a bat, an sh file, and in retrospect I should have done the same for the windows release.对于 linux 版本,我使用了相当于 bat 的 linux 文件,一个 sh 文件,回想起来,我应该对 windows 版本也这样做。

Literal answer字面答案

The bundledJrePath config for launch4j is telling launch4j where to find the JRE, not where to put it, you must seperately put it there. launch4j 的 bundledJrePath 配置告诉 launch4j 在哪里可以找到 JRE,而不是把它放在哪里,你必须单独把它放在那里。 And if launch4j can't find it it will use the installed JRE (or download one).如果 launch4j 找不到它,它将使用已安装的 JRE(或下载一个)。

My relevant Gradle config ended up like this我的相关 Gradle 配置最终是这样的

launch4j { //used for windows
    mainClassName = 'mygame.Main'
    bundledJrePath = 'jre'
    bundledJre64Bit = true
    jreMinVersion = '11'
}

task packageExecutableDistribution(type: Zip) {
    archiveName = "oneMillionWorlds.zip"
    destinationDir = file("$buildDir/distExecutable")

    from "$buildDir/launch4j"
}

task addJreToDistributable(type: Copy) {
    from zipTree("resources/desktop-deployment/OpenJDK11U-jre_x64_windows_hotspot_11.0.4_11.zip")
    destinationDir = file("$buildDir/launch4j")
}

packageExecutableDistribution.dependsOn createExe
packageExecutableDistribution.dependsOn addJreToDistributable

And my folder structure ended up like this我的文件夹结构最终是这样的

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM