Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use launch4j to wrap a GUI application that also provides a command line interface?

I am developing a Java application, which is mainly a GUI application. However, it also provides a command line interface. I can divide the command line parameters in three different types:

  • The first type of parameter changes the behavior of the GUI.
  • The second type starts the GUI in a specific state.
  • The third type causes the application to directly execute an action without displaying the GUI.

When I execute the application with java -jar <application-name>.jar -parameter, everything works as expected. The application executes what it is asked to do. After the application is closed or finished, the shell prompt returns.

Problem

When I use launch4j to create a windows wrapper from the jar file, this behavior changes. The shell prompt always returns immediately. Thus, I can still pass command line parameters, but I cannot interact with the application via the terminal. It does not print anything that is written to stdout or stderr and it also cannot read anything from stdin.

Question

How can I configure launch4j to create an exe wrapper that provides the same command line behavior as the wrapped jar file?

Additional Information

I use the launch4j maven plugin with the following configuration:

<plugin>
    <groupId>com.akathist.maven.plugins.launch4j</groupId>
    <artifactId>launch4j-maven-plugin</artifactId>
    <version>1.7.8</version>
    <executions>
        <execution>
            <id>launch4j</id>
            <phase>package</phase>
            <goals>
                <goal>launch4j</goal>
            </goals>
            <configuration>
                <headerType>gui</headerType>
                <stayAlive>true</stayAlive>
                <outfile>path/to/outfile.exe</outfile>
                <jar>path/to/infile.jar</jar>
                <dontWrapJar>false</dontWrapJar>
                <errTitle>Error in Launcher</errTitle>
                <classPath>
                    <mainClass>com.example.Launch</mainClass>
                    <addDependencies>false</addDependencies>
                </classPath>
                <icon>path/to/icon.ico</icon>
                <jre>
                    <minVersion>1.8.0</minVersion>
                    <initialHeapSize>512</initialHeapSize>
                    <maxHeapSize>1024</maxHeapSize>
                </jre>
            </configuration>
        </execution>
    </executions>
</plugin>

The documentation of launch4j says, that the given combination of the settings headerType=gui and stayAlive=true will Wait for the application to close, which is not the case.

Since I do not have a windows machine available, I cannot try out what happens when I set headerType=console. The documentation says that this causes the wrapper to always wait and return the application's exit code. However, since my application is mainly a GUI application, I wonder whether this setting has any negative side effects. At this point I start to ask myself why I would ever want the wrapped application to have another command line behavior than the jar file.

like image 549
Stefan Dollase Avatar asked Feb 04 '16 15:02

Stefan Dollase


People also ask

How does Launch4J work?

Launch4j is a cross-platform tool for wrapping Java applications distributed as jars in lightweight Windows native executables. The executable can be configured to search for a certain JRE version or use a bundled one, and it's possible to set runtime options, like the initial/max heap size.

Why use Launch4J?

Launch4J allows you to bundle a JVM inside exe file, so: You can ensure to run your application with a minimum JVM version; Customers don't have to worry about downloading Java on their machines; So basically your application becomes portable. :P.

Which file contains all settings configuration for the Launch4J application?

Configuration file. Launch4j requires an xml configuration file for each output executable. You can create and edit it conveniently using the graphic user interface or your favorite editor. Alternatively it's possible to pass all of the configuration parameters through the Ant task.


1 Answers

I finally got a windows machine up and running to test this by myself.

I solved this issue by replacing this

<headerType>gui</headerType>
<stayAlive>true</stayAlive>

by that

<headerType>console</headerType>

According to the documentation stayAlive=true is actually implied by headerType=console, so I can safely remove it from the configuration.

I was not able to notice any side-effects of this to the GUI. The only annoying thing is that this opens a console which displays the console output.

So, I guess the intended solution to this is the configuration as described in the question: headerType=gui and stayAlive=true. However, this does not work. I think this is a bug in launch4j.

like image 122
Stefan Dollase Avatar answered Oct 08 '22 12:10

Stefan Dollase