使用 Launch4J 构建的 Micronaut 应用程序未启动
Micronaut application built with Launch4J not launching
我已经成功地将我的桌面应用程序从 Dagger/Spring 移植到 Micronaut/Spring(那里的 Spring 代码太多了,我无法及时将其全部删除方式)。使用 Micronaut 和 PicoCLI,一切都在 Eclipse/Gradle 中完美运行。它正在启动,测试正在通过,所以现在我想构建并安装它以确保一切都适用于我们的客户。
我们的构建(通过 Gradle)使用 Shadow(com.github.johnrengelman.shadow)将我们的应用程序及其所有依赖项组合到一个 Jar 文件中。我已经检查过,所有预期的依赖项似乎都存在,从它的外观来看,生成的 Micronaut 类 也存在于 shadow jar 中。然后我们使用 Launch4J 使这个 shadow jar 可执行。据我所知,Launch4J 的输出看起来是正确的,但是当我尝试 运行 安装的应用程序时,启动画面只出现了几分之一秒,仅此而已。当我 运行 Launch4J 生成可执行文件作为 jar 文件时,我得到以下信息:
Error: An unexpected error occurred while trying to open file My App.exe
我们正在 运行 OpenJDK11 (11.0.2) 并生成一个 JRE 作为 gradle build
的一部分
runtime {
modules = [
'java.base',
'java.compiler',
'java.datatransfer',
'java.desktop',
'java.instrument',
'java.logging',
'java.management',
'java.naming',
'java.prefs',
'java.rmi',
'java.scripting',
'java.security.sasl',
'java.sql',
'java.transaction.xa',
'java.xml',
'jdk.compiler',
'jdk.httpserver',
'jdk.javadoc',
'jdk.naming.rmi',
'jdk.unsupported'
]
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
}
我收集到的所有 Launch4J 调试信息看起来都是正确的(退出代码 1 除外),到目前为止,我对此进行的所有深入研究都被证明是徒劳的。我收集到此类错误的最常见原因是 jar 中的 MANIFEST.MD 无效(我已经检查过,它与原始的 Micronaut 之前的清单相同),或者类路径问题(shadow jar 应该包含所有必需的依赖项,据我所知没有使用其他类路径引用)。 build.gradle的相关部分如下:
task createExe(type: Launch4jLibraryTask) {
jarTask = shadowJar
icon = "${projectDir}/src/main/installer/nsis/Icon.ico"
outfile = "${appName}.exe"
copyConfigurable = files {}
stayAlive = 'true'
bundledJrePath = 'jre'
bundledJre64Bit = true
jvmOptions = [
'-Xmx1024m',
'-Dsun.java2d.d3d=false'
]
fileDescription = appName + ' Application'
productName = appName
internalName = appName
copyright = 'My Company'
companyName = 'My Company'
}
jar {
manifest {
attributes(
'Main-Class': mainClassName,
'SplashScreen-Image': 'images/Z006BASSPS.jpg'
)
}
}
shadowJar {
dependsOn replaceTokens
zip64 true
mergeServiceFiles() {
exclude 'META-INF/services/org.xmlpull.v1.XmlPullParserFactory'
}
append 'META-INF/spring.factories'
append 'META-INF/spring.handlers'
append 'META-INF/spring.schemas'
append 'META-INF/spring.tooling'
}
None 其中自 Micronaut 之前一切正常时已更改。
我已经尝试使用它生成的 JRE 启动由构建生成的影子 jar,看起来它正在工作(或者至少,它正在执行而不是立即死亡)。所以我相当有信心问题出在构建的 Launch4J 部分。
Micronaut 与 Launch4j 兼容吗?是否缺少某些东西,或者可以尝试查看可能发生的其他事情?我真的很困惑,一切 看起来 应该可以,但事实并非如此...
更新:
经过大量挖掘后,我开始意识到问题出在 Launch4j 上。此构建生成的影子罐运行良好。然而 运行通过 Launch4j 连接工作 Jar 会产生一个只生成
的可执行文件
Error: An unexpected error occurred while trying to open file launch4j\MyApp.exe
我创建了一个虚拟的 Micronaut 应用程序并使用 Launch4j 生成它的构建似乎也完全按预期工作,所以我认为这不是 Launch4j - Micronaut 不兼容的说法。
有什么方法可以从可执行文件中获取更多信息吗?实际可行的东西?我尝试将 headerType 从 gui 更改为控制台(根据我在此处看到的其他 Launch4j 问题),但这没有任何影响。我试过 运行 --l4j-debug(-all),并将其与升级前的输出进行比较,生成的日志文件中没有任何有意义的变化。
更新:
我相信我已经缩小了问题的范围:如果 jar 中的文件太多,launch4j 似乎无法工作。我假设限制是 65535,因为这是 Shadow 需要 zip64 标志的限制。在我的微型虚拟应用程序中,我将 70,000 个文本文件添加到资源目录中,并且在这些文件就位后,它将不再 运行(按照上面的描述)。一旦我将文本文件的数量减少到 50,000,一切又开始了 运行ning。我不确定每次说的限制是否为 65535(但这是我的期望),但一切似乎都指向它。
我还没有找到任何关于将 launch4j 用于超过 65535 个文件的信息(即:类似 shadowJar zip64 标志的东西),也没有找到关于这方面的一般信息。然而,一种对我有用的解决方案是将 dontWrapJar
设置为 true
。这会为 运行 使用捆绑的 JRE 创建的 jar 文件创建一个微型启动器,而不是转换整个 jar,将所有(或至少大部分)文件保留在 launch4j 生成的可执行文件之外。更新后的gradle任务如下
task createExe(type: Launch4jLibraryTask) {
jarTask = shadowJar
dontWrapJar true // <<<< THIS IS THE ADDED LINE
icon = "${projectDir}/src/main/installer/nsis/Icon.ico"
outfile = "${appName}.exe"
copyConfigurable = files {}
stayAlive = 'true'
bundledJrePath = 'jre'
bundledJre64Bit = true
jvmOptions = [
'-Xmx1024m',
'-Dsun.java2d.d3d=false'
]
fileDescription = appName + ' Application'
productName = appName
internalName = appName
copyright = 'My Company'
companyName = 'My Company'
}
除此之外,唯一的其他更改是更新打包过程以将生成的影子 jar 合并到生成的安装程序的 lib
目录中。
我已经成功地将我的桌面应用程序从 Dagger/Spring 移植到 Micronaut/Spring(那里的 Spring 代码太多了,我无法及时将其全部删除方式)。使用 Micronaut 和 PicoCLI,一切都在 Eclipse/Gradle 中完美运行。它正在启动,测试正在通过,所以现在我想构建并安装它以确保一切都适用于我们的客户。
我们的构建(通过 Gradle)使用 Shadow(com.github.johnrengelman.shadow)将我们的应用程序及其所有依赖项组合到一个 Jar 文件中。我已经检查过,所有预期的依赖项似乎都存在,从它的外观来看,生成的 Micronaut 类 也存在于 shadow jar 中。然后我们使用 Launch4J 使这个 shadow jar 可执行。据我所知,Launch4J 的输出看起来是正确的,但是当我尝试 运行 安装的应用程序时,启动画面只出现了几分之一秒,仅此而已。当我 运行 Launch4J 生成可执行文件作为 jar 文件时,我得到以下信息:
Error: An unexpected error occurred while trying to open file My App.exe
我们正在 运行 OpenJDK11 (11.0.2) 并生成一个 JRE 作为 gradle build
的一部分runtime {
modules = [
'java.base',
'java.compiler',
'java.datatransfer',
'java.desktop',
'java.instrument',
'java.logging',
'java.management',
'java.naming',
'java.prefs',
'java.rmi',
'java.scripting',
'java.security.sasl',
'java.sql',
'java.transaction.xa',
'java.xml',
'jdk.compiler',
'jdk.httpserver',
'jdk.javadoc',
'jdk.naming.rmi',
'jdk.unsupported'
]
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
}
我收集到的所有 Launch4J 调试信息看起来都是正确的(退出代码 1 除外),到目前为止,我对此进行的所有深入研究都被证明是徒劳的。我收集到此类错误的最常见原因是 jar 中的 MANIFEST.MD 无效(我已经检查过,它与原始的 Micronaut 之前的清单相同),或者类路径问题(shadow jar 应该包含所有必需的依赖项,据我所知没有使用其他类路径引用)。 build.gradle的相关部分如下:
task createExe(type: Launch4jLibraryTask) {
jarTask = shadowJar
icon = "${projectDir}/src/main/installer/nsis/Icon.ico"
outfile = "${appName}.exe"
copyConfigurable = files {}
stayAlive = 'true'
bundledJrePath = 'jre'
bundledJre64Bit = true
jvmOptions = [
'-Xmx1024m',
'-Dsun.java2d.d3d=false'
]
fileDescription = appName + ' Application'
productName = appName
internalName = appName
copyright = 'My Company'
companyName = 'My Company'
}
jar {
manifest {
attributes(
'Main-Class': mainClassName,
'SplashScreen-Image': 'images/Z006BASSPS.jpg'
)
}
}
shadowJar {
dependsOn replaceTokens
zip64 true
mergeServiceFiles() {
exclude 'META-INF/services/org.xmlpull.v1.XmlPullParserFactory'
}
append 'META-INF/spring.factories'
append 'META-INF/spring.handlers'
append 'META-INF/spring.schemas'
append 'META-INF/spring.tooling'
}
None 其中自 Micronaut 之前一切正常时已更改。
我已经尝试使用它生成的 JRE 启动由构建生成的影子 jar,看起来它正在工作(或者至少,它正在执行而不是立即死亡)。所以我相当有信心问题出在构建的 Launch4J 部分。
Micronaut 与 Launch4j 兼容吗?是否缺少某些东西,或者可以尝试查看可能发生的其他事情?我真的很困惑,一切 看起来 应该可以,但事实并非如此...
更新:
经过大量挖掘后,我开始意识到问题出在 Launch4j 上。此构建生成的影子罐运行良好。然而 运行通过 Launch4j 连接工作 Jar 会产生一个只生成
的可执行文件Error: An unexpected error occurred while trying to open file launch4j\MyApp.exe
我创建了一个虚拟的 Micronaut 应用程序并使用 Launch4j 生成它的构建似乎也完全按预期工作,所以我认为这不是 Launch4j - Micronaut 不兼容的说法。
有什么方法可以从可执行文件中获取更多信息吗?实际可行的东西?我尝试将 headerType 从 gui 更改为控制台(根据我在此处看到的其他 Launch4j 问题),但这没有任何影响。我试过 运行 --l4j-debug(-all),并将其与升级前的输出进行比较,生成的日志文件中没有任何有意义的变化。
更新:
我相信我已经缩小了问题的范围:如果 jar 中的文件太多,launch4j 似乎无法工作。我假设限制是 65535,因为这是 Shadow 需要 zip64 标志的限制。在我的微型虚拟应用程序中,我将 70,000 个文本文件添加到资源目录中,并且在这些文件就位后,它将不再 运行(按照上面的描述)。一旦我将文本文件的数量减少到 50,000,一切又开始了 运行ning。我不确定每次说的限制是否为 65535(但这是我的期望),但一切似乎都指向它。
我还没有找到任何关于将 launch4j 用于超过 65535 个文件的信息(即:类似 shadowJar zip64 标志的东西),也没有找到关于这方面的一般信息。然而,一种对我有用的解决方案是将 dontWrapJar
设置为 true
。这会为 运行 使用捆绑的 JRE 创建的 jar 文件创建一个微型启动器,而不是转换整个 jar,将所有(或至少大部分)文件保留在 launch4j 生成的可执行文件之外。更新后的gradle任务如下
task createExe(type: Launch4jLibraryTask) {
jarTask = shadowJar
dontWrapJar true // <<<< THIS IS THE ADDED LINE
icon = "${projectDir}/src/main/installer/nsis/Icon.ico"
outfile = "${appName}.exe"
copyConfigurable = files {}
stayAlive = 'true'
bundledJrePath = 'jre'
bundledJre64Bit = true
jvmOptions = [
'-Xmx1024m',
'-Dsun.java2d.d3d=false'
]
fileDescription = appName + ' Application'
productName = appName
internalName = appName
copyright = 'My Company'
companyName = 'My Company'
}
除此之外,唯一的其他更改是更新打包过程以将生成的影子 jar 合并到生成的安装程序的 lib
目录中。