如何让JRE与Launch4j捆绑?

9
我知道launch4j不能在.exe中捆绑JRE,但你需要将它放在旁边。我的问题是,我应该如何做呢?有没有办法让Maven自动定位并复制我用来构建应用程序的JDK的JRE,并将其复制到指定目录?
我尝试过类似这样的操作:
    <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.6</version>
        <executions>
            <execution>
                <id>copy-resources</id>
                <!-- here the phase you need -->
                <phase>package</phase>
                <goals>
                    <goal>copy-resources</goal>
                </goals>
                <configuration>
                    <outputDirectory>${basedir}/target/windows/jre</outputDirectory>
                    <resources>
                        <resource>
                            <directory>${java.home}</directory>
                        </resource>
                    </resources>
                </configuration>
            </execution>
        </executions>
    </plugin>

但程序无法启动。它显示一个小对话框,立即消失(似乎是空白的,但它消失得太快了,我真的没注意到)。


@SarelBotha:目前是的,支持Windows 7、8和10;32位和64位。 - pupeno
Maven构建输出是否表明它正在尝试复制目录?尝试将JRE目录的路径硬编码。 - Sarel Botha
Maven 何时调用 launch4j?是在打包阶段吗?这会在您的自定义执行之前吗?也许将您的自定义执行更改为在编译阶段运行,以确保它首先完成。 - Sarel Botha
@SarelBotha:如果那是唯一的选项,那么是的。否则,我宁愿给我的客户提供32位和64位的二进制文件。 - pupeno
更新了我的回答。我相信现在它可以满足你的需求了。 - Sarel Botha
显示剩余3条评论
2个回答

14

更新:删除了之前的回答,并用经过测试的工作示例进行替换。

更新2:此pom.xml现在下载JRE tgz并解压缩它,launch4j exe将使用它并正常工作。我添加了注释来解释它的工作原理。

我建议仅使用32位exe和JRE。使用64位JRE的唯一原因是如果您的程序需要使用超过4GB的RAM。

当然,现在您需要一个安装程序,将所有内容安装到Program Files中。我过去使用过NSIS进行此操作。学习曲线对于NSIS来说不太陡峭。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.akathist.encc</groupId>
    <artifactId>mavenproject1</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <!-- This is the win32 JRE tgz hosted by alfresco - https://mvnrepository.com/artifact/com.oracle.java/jre -->
        <dependency>
            <groupId>com.oracle.java</groupId>
            <artifactId>jre</artifactId>
            <classifier>win32</classifier>
            <type>tgz</type>
            <version>1.8.0_131</version>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <!-- this repository has the JRE tgz -->
            <id>alfresco</id>
            <url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>
        </repository>
    </repositories>
    <build>
        <plugins>
            <plugin>
                <!-- this is to extract the JRE tgz file we downloaded -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.5.1</version>
                <executions>
                    <execution>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>unpack-dependencies</goal>
                        </goals>
                        <configuration>
                            <includeGroupIds>com.oracle.java</includeGroupIds>
                            <includeTypes>tgz</includeTypes>
                            <includeArtifactIds>jre</includeArtifactIds>
                            <includeClassifiers>win32</includeClassifiers>
                            <outputDirectory>target/win32</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <!-- This calls launch4j to create the program EXE -->
                <groupId>com.akathist.maven.plugins.launch4j</groupId>
                <artifactId>launch4j-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>l4j-clui</id>
                        <phase>package</phase>
                        <goals>
                            <goal>launch4j</goal>
                        </goals>
                        <configuration>
                            <headerType>console</headerType>
                            <outfile>target/encc.exe</outfile>
                            <jar>target/mavenproject1-1.0-SNAPSHOT.jar</jar>
                            <errTitle>encc</errTitle>
                            <classPath>
                                <mainClass>com.akathist.encc.Clui</mainClass>
                                <addDependencies>false</addDependencies>
                                <preCp>anything</preCp>
                            </classPath>
                            <jre>
                                <path>./win32/java</path>
                            </jre>
                            <versionInfo>
                                <fileVersion>1.2.3.4</fileVersion>
                                <txtFileVersion>txt file version?</txtFileVersion>
                                <fileDescription>a description</fileDescription>
                                <copyright>my copyright</copyright>
                                <productVersion>4.3.2.1</productVersion>
                                <txtProductVersion>txt product version</txtProductVersion>
                                <productName>E-N-C-C</productName>
                                <internalName>ccne</internalName>
                                <originalFilename>original.exe</originalFilename>
                            </versionInfo>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

更新3:令人遗憾的是,没有任何官方或者最新的Maven仓库提供您所需的JRE版本。您可以自己搭建一个Maven仓库,并将所需的JRE版本添加到其中。但需要注意,您必须在每次新版本发布后及时更新仓库,并在发布新版本前进行测试。Java的新版本通常在每个月的第三个星期二发布,您可以设置一个提醒来检查是否发布了新版本,并进行下载。由于许可协议的检查,自动化此过程可能会有些麻烦。这篇文章可能会有所帮助,但您可能无法通过这种方式下载tar.gz版本的JRE:Java check latest version programmatically

如果您希望支持多个平台,则搭建自己的Maven仓库是一个不错的选择。您可以搭建自己的仓库,并使用此方法在每次发布新版本时添加新的JRE tar.gz文件:https://dev59.com/YWYr5IYBdhLWcg3wQH--#29261502

最简单的选择是使用您正在构建的JRE版本。只要使用32位JRE进行构建,即可支持Windows 32位和64位。您可以在有时间测试新版本时偶尔进行更新。以下是一个可用的pom.xml文件示例:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.akathist.encc</groupId>
    <artifactId>mavenproject1</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <build>
        <plugins>
            <plugin>
                <!-- This copies the JRE used to do the build from java.home - should be 32 bit Windows JRE -->
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <!-- here the phase you need -->
                        <phase>package</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${basedir}/target/win32/java</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>${java.home}</directory>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <!-- This calls launch4j to create the program EXE -->
                <groupId>com.akathist.maven.plugins.launch4j</groupId>
                <artifactId>launch4j-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>l4j-clui</id>
                        <phase>package</phase>
                        <goals>
                            <goal>launch4j</goal>
                        </goals>
                        <configuration>
                            <headerType>console</headerType>
                            <outfile>target/encc.exe</outfile>
                            <jar>target/mavenproject1-1.0-SNAPSHOT.jar</jar>
                            <errTitle>encc</errTitle>
                            <classPath>
                                <mainClass>com.akathist.encc.Clui</mainClass>
                                <addDependencies>false</addDependencies>
                                <preCp>anything</preCp>
                            </classPath>
                            <jre>
                                <path>./win32/java</path>
                            </jre>
                            <versionInfo>
                                <fileVersion>1.2.3.4</fileVersion>
                                <txtFileVersion>txt file version?</txtFileVersion>
                                <fileDescription>a description</fileDescription>
                                <copyright>my copyright</copyright>
                                <productVersion>4.3.2.1</productVersion>
                                <txtProductVersion>txt product version</txtProductVersion>
                                <productName>E-N-C-C</productName>
                                <internalName>ccne</internalName>
                                <originalFilename>original.exe</originalFilename>
                            </versionInfo>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

不确定gvSIG.confDir的作用是什么。我会分两个阶段来解决这个问题。首先,手动将JRE目录复制到launch4j XML文件旁边,使其正常工作。然后尝试自动复制JRE目录。 - Sarel Botha
谢谢您的答案,Sarel。不幸的是,该存储库似乎停留在1.8.0_133版本,而我已经错过了一些我指望通过使用1.8.0_162版本来解决的问题(尽管我不记得它们是什么,我只是记得需要升级,我可能需要在这里做一些研究)。但是也没有Java 9或10。:( - pupeno
我更新了答案以解决这些问题。是的,不同的方法有其优缺点。你需要根据自己能接受的情况来选择。Java 9和10不支持32位Windows,所以在你进行转换之前可能还需要一段时间。 - Sarel Botha
我无法使用另一个依赖项,因为它需要 tgz 依赖项,这会干扰 shade:[ERROR] Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:3.1.0:shade (default) on project dashman: Error creating shaded jar: error in opening zip file C:\Users\pupeno\.m2\repository\com\oracle\java\jre\1.8.0_131\jre-1.8.0_131-win32.tgz -> [Help 1]。我相信这很容易解决,但我对 Maven 不熟悉。 - pupeno
我们可以在开发环境中使用已安装的JDK中的JRE吗?我们可以获取环境变量(<local.jre.path>${env.JAVA17_HOME}</local.jre.path>),但我不确定如何配置launch4j来使用它。 - White_King
显示剩余6条评论

0

我相信这就是你要找的内容:

<plugin>
  <groupId>com.akathist.maven.plugins.launch4j</groupId>
  <artifactId>launch4j-maven-plugin</artifactId>
  <executions>
    <execution>
      ...
      <configuration>
        ...
        <jre>
          <path>${java.home}</path> <!-- SEE THIS -->
        </jre>
        ...
      </configuration>
    </execution>
  </executions>
</plugin>

Java 允许您使用 java.home 系统属性访问 JRE 路径。您可以 在 pom 中访问 java 系统属性。还可以使用包装器插件来启动 launch4j。将它们组合起来,就得到了解决方案。

我认为作者想要一个在电脑没有安装Java的情况下也能正常运行的解决方案,所以他希望将JRE打包到exe文件中。 - Maciej Pulikowski
这将在最终的exe中捆绑maven使用的JRE。 - James
3
不,它不会。这将创建一个期望在每台计算机上存在${java.home}的exe,也就是应用程序的用户。当捆绑时,jre路径应该相对于当前路径。 - pupeno
@pupeno 是的,完全正确。 - Maciej Pulikowski
这个解决方案让我避免了1.5天的挣扎 :) - Ahmet Eroğlu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接