Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the JRE to bundle with launch4j?

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).

like image 690
pupeno Avatar asked Apr 04 '18 13:04

pupeno


People also ask

Can I bundle JRE with my application?

In this field, you can select the location of the JRE you want to be bundled with the current build. The content of this folder will be added automatically in the "Destination" folder. Builds with the same destination folder use the same JRE bundle.

What is bundled JRE?

Bundling a JRE, basically means that your application includes its own JRE, that gets installed, along with your application; typically within the same folder (Windows) or within the app bundle (Mac).


1 Answers

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>
like image 109
Sarel Botha Avatar answered Oct 22 '22 22:10

Sarel Botha