问题
I understand that launch4j doesn't bundle the JRE in the .exe
but that you have to place it next to it. My question is, how am I supposed to do that? Is there a way for maven to automatically locate and copy the JRE of the JDK I'm using to build my application and copy it to a given directory?
I've tried doing something like this:
<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>
but the program doesn't start. It shows a little dialog that immediately disappears (it seems to be blank, but it goes away too quickly for me to really notice it).
回答1:
UPDATE: Deleted my previous answer and replacing with tested working example
UPDATE 2: This pom.xml now downloads the JRE tgz and unpacks it and the launch4j exe uses it and it works. I added comments to explain how it works.
I would recommend sticking with just a 32 bit exe and JRE. The only reason to use the 64 bit JRE would be if your program needs to use more than 4 GB of RAM.
Of course now you need an installer that takes all this and installs to Program Files. I've used NSIS for this in the past. There is a learning curve for NSIS but it is not too bad.
<?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>
UPDATE 3: The sad fact is that there exists no offical or even up-to-date maven repo with the JREs that you want. You could host your own maven repo that has the desired JREs. You will have to update this as new releases are done. It is also a good idea to test with the new version before releasing with it. The third Tuesday of every month is when new Java releases are done. You can set a reminder for this to check if a new version was released and download it. Automating this is a pain because of the license agreement check. This post might help but you probably can't download the tar.gz version of the JRE this way: Java check latest version programmatically
If you want to support multiple platforms then hosting your own maven repo is a good way to go. You can host your own repo and update it with the new JRE tar.gz every time a release is done with this: https://stackoverflow.com/a/29261502/35264
The simplest option is to do what you were aiming for already and just use the JRE that you are building with. This will allow you to support Windows 32 and 64 as long as you build with the 32 bit JRE. You can update this occasionally as you have time to test with the new version. Here is a working pom.xml that does this:
<?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>
回答2:
I believe this is what you are looking for:
<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 lets you access JRE path using java.home
system property. And you can access java system properties within pom. And you have a plugin that wraps launch4j. Put all of these together and you have the solution.
来源:https://stackoverflow.com/questions/49651902/how-to-get-the-jre-to-bundle-with-launch4j