Method 1 - WrapperSimpleApp Integration (Linux / UNIX)

Overview

The Method 1 is to use the WrapperSimpleApp helper class to launch the application. This is by far the simplest way to integrate with the Wrapper, and where possible, it is highly recommended.

There are some things to be aware of when using this method, however. When the Wrapper shuts down the JVM, there is no direct call to an application requesting that it shuts down cleanly. Rather, the Wrapper will exit the JVM by calling System.exit() from within the JVM. If the application has registered its own Shutdown Hook, it will be invoked, giving the application a chance to shutdown cleanly. If on the other hand, a Shutdown Hook is not registered, then the application will suddenly exit like when pressing CTRL-C in the console (command window). Both cases, with and without a Shutdown Hook, provide the exact same behavior as if the application was running without the Wrapper.

When integrating with this Method 1, the WrapperSimpleApp helper class replaces an application's main class. This gives the WrapperSimpleApp class a chance to immediately initialize the WrapperManager and register the JVM with the Wrapper. The WrapperSimpleApp class then manages all interaction with the Wrapper as well as the life-cycle of an application. When the Wrapper sends a start message to the JVM via the WrapperManager, the main method of the application's actual main class is called.

The WrapperSimpleApp helper class is told how to launch the application by passing the application's main class name, followed by any additional application parameters to the main method of the WrapperSimpleApp.

Detailed Instructions

This section will walk you through a detailed explanation of how to configure a simple HelloWorld application to run within the Wrapper. Most other applications can be integrated by following the same steps.

HelloWorld Application

This tutorial will start a simple application HelloWorld that just prints "Hello world". The path to this application is /usr/lib/helloworld and will be referenced as {MYAPP_HOME}. Some extra folders (bin, lib, conf and logs) need to exist in which files from the Wrapper will be copied.

Installing Wrapper Files

There are four directories which are required to be configured in order to be able to use the Wrapper.

NOTE

Please make sure that you are using the appropriate Wrapper and libwrapper.so files which were built for the platform being run. It sounds obvious, but the Wrapper Linux version will not work on Solaris for example.

bin directory

The Wrapper is shipped with a shell script (sh) which can be used to reliably start and stop any Java application controlled by the Java Service Wrapper.

First, copy the following file into the HelloWorld bin directory (on older Wrapper versions, this file was named 'sh.script.in'):

{WRAPPER_HOME}/bin/wrapper
{WRAPPER_HOME}/src/bin/App.sh.in

Rename the script file to reflect the name of the application.

{MYAPP_HOME}/bin/helloworld

Now open the script into an editor. We need to set the long and short names to reflect that the script is being used to launch HelloWorld. You will see two variables immediately after the header of the script APP_NAME and APP_LONG_NAME. Suggested values for these variables are shown below.

APP_NAME="helloworld"
APP_LONG_NAME="Hello World"

The script should not require any additional modification. However it does assume that the wrapper.conf file will be located within a conf directory (one level up, ../conf/wrapper.conf). If you wish to place the wrapper.conf file somewhere else, the WRAPPER_CONF variable in the script will require appropriate modification.

NOTE

Important! Before proceeding, please make sure that all files copied into the bin directory have their executable bit set.

lib directory

Copy the native library and the Wrapper jar file into the HelloWorld lib directory:

{WRAPPER_HOME}/lib/libwrapper.so
{WRAPPER_HOME}/lib/wrapper.jar

The libwrapper.so file is a native library file required by the portion of the Wrapper which runs within the JVM. The wrapper.jar file contains all of the Wrapper classes.

NOTE

Note that the native library follows slightly different naming conventions on some platforms. Possible names include; libwrapper.a, libwrapper.sl, libwrapper.so, and libwrapper.jnilib. In any case, the file should be copied over without changing the extension.

conf directory

All the configurations of the Wrapper is done in wrapper.conf. The standard location for this file is in a conf directory in the application's home directory. Copy the following template file wrapper.conf.in into the conf directory of HelloWorld.

{WRAPPER_HOME}/src/conf/wrapper.conf.in

Be sure to remove the .in extension so that the file is named wrapper.conf.

You should now have:

{MYAPP_HOME}/conf/wrapper.conf

If you wish to relocate the configuration file wrapper.conf, you are free to do so. You will need to modify the scripts copied into the bin directory above to reflect the new location.

logs directory

The default configuration file wrapper.conf will place a wrapper.log file in a logs directory under the application's home directory.

Make sure you have created the directory:

{MYAPP_HOME}/logs

If you wish to place the wrapper.log file in another location, you will need to edit the wrapper.conf file and modify the wrapper.logfile property to reflect the new location.

lang directory

Starting with Wrapper version 3.5.0, the Wrapper can be localized. The language resource files can be found in the lang directory. If needed, create a lang directory under the application's home directory and copy those files to there:

{MYAPP_HOME}/lang/wrapper_XX.mo
{MYAPP_HOME}/lang/wrapperjni_XX.mo

If you wish to place the language resource files *.mo to another location, you will need to edit the wrapper.conf file and modify the wrapper.lang.folder property to reflect the new location.

Locate the Application's Java Command Line

Before the Wrapper can be configured to launch an application, you will need to know the full Java command which is normally used to launch the application.

Most applications make use of a script to build up the actual command line. These scripts tend to get quite unwieldy but in fact, the featured ability to avoid having to work with them is one of the benefits of working with the Wrapper.

The majority of the script has the task of collecting system specific information and storing that information into environment variables and then to run the Java command.

In order to configure the Wrapper, all that is really needed is the final Java command line.

In the case of our simple HelloWorld application, a script is not needed. The command to launch it would look like this:

java com.tanukisoftware.HelloWorld

A more complex command to launch a Java application would look like this:

java -classpath "/usr/lib/helloworld/lib/myjar.jar" -Xms128M -Xmx512M com.tanukisoftware.HelloWorld arg1 arg2

Modifying the wrapper.conf File

In order to be able to use the above Java command line with the Wrapper, we need to break up the command line's components into a configuration file. Open the wrapper.conf file into an editor and make the changes below.

NOTE

Where properties are mentioned below, links are provided to their descriptions. Please take the time to review the descriptions of any properties which are modified. In many cases, there are further details on their usage which are not mentioned here.

Environment Variable:

In order to ease the configuration, it is recommended to store the HOME directory of HelloWorld and Java into a environment variable in the configuration file. This will make the conf file much more readable and eventually easier to maintain in case a directory path gets changed. If set in the configuration file, the Wrapper will set the environment variables everytime it launches:

set.MYAPP_HOME=/usr/lib/helloworld
set.JAVA_HOME=/usr/lib/jvm/java-8-openjdk

Java Executable

First is to extract the Java executable and assign the location path to the wrapper.java.command property:

wrapper.java.command=%JAVA_HOME%/bin/java

Java Arguments

Most applications provide a number of parameters to the Java executable when it is launched. The Wrapper provides special properties for configuring things like memory, as well as class and library paths. These will be covered below, however any other settings are configured using the wrapper.java.additional.<n> series of properties.

The HelloWorld application takes 2 additional Java arguments.

wrapper.java.additional.1=-Xms128M
wrapper.java.additional.2=-Xmx512M

The initial and maximal memory size of the JVM specified by -Xms128M (initial) and -Xmx512M (maximal), can also be defined using the wrapper.java.initmemory and wrapper.java.maxmemory properties.

# Initial Java Heap Size (in MB)
wrapper.java.initmemory=128

# Maximum Java Heap Size (in MB)
wrapper.java.maxmemory=512

Wrapper Jar

The Wrapper requires that its wrapper.jar be specified:

wrapper.jarfile=%MYAPP_HOME%/lib/wrapper.jar

WARNING

The wrapper.jarfile property was introduced in version 3.5.55. When using earlier Wrapper versions, it is necessary to include wrapper.jar in the classpath:

wrapper.java.classpath.1=D:\apache-tomcat-9.0.0.M13\lib\wrapper.jar

Then, the indices of next classpath elements must be adjusted so that the wrapper.java.classpath.1 property is not repeated.

Classpath

Next, comes the classpath, which is configured using the wrapper.java.classpath.<n> properties. The Wrapper requires that the classpath be broken up into its individual elements.

wrapper.java.classpath.1=%MYAPP_HOME%/bin/myjar.jar

Main Class

In order to establish a communication between HellowWorld and the Wrapper, the use of the helper class WrapperSimpleApp as the main class is necessary. The main class executed by Java when launched is specified by using the wrapper.java.mainclass property. The HelloWorld main class is then specified as the first application parameter (see section below).

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

Application Parameters

Application parameters are set using the wrapper.app.parameter.<n> properties. Application parameters appear in the Java command line directly after the main class. As mentioned above, it is necessary to set the first parameter as the HelloWorld main class. Any other parameters come after.

wrapper.app.parameter.1=com.tanukisoftware.HelloWorld
wrapper.app.parameter.2=arg1
wrapper.app.parameter.3=arg2

Library Path

In order to use the Wrapper, one more property must be set. The Wrapper makes use of a native library to control interactions with the system. This library file libwrapper.so needs to be specified on the library path supplied to the JVM.

The library path is set using the wrapper.java.library.path.<n> properties.

wrapper.java.library.path.1=%MYAPP_HOME%/lib

Putting It All Together

Putting it all together, we get the following:

set.MYAPP_HOME=/usr/lib/helloworld
set.JAVA_HOME=/usr/lib/jvm/java-8-openjdk

wrapper.java.command=%JAVA_HOME%/bin/java

# Java Main class.
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

# Wrapper Jar
wrapper.jarfile=%MYAPP_HOME%/lib/wrapper.jar

# Java Classpath
wrapper.java.classpath.1=%MYAPP_HOME%/bin/myjar.jar

# Java Library Path (location of Wrapper.DLL or libwrapper.so)
wrapper.java.library.path.1=%MYAPP_HOME%/lib

# Java Bits.  On applicable platforms, tells the JVM to run in 32 or 64-bit mode.
wrapper.java.additional.auto_bits=TRUE

# JVM settings
wrapper.java.additional.1=-Xms128M
wrapper.java.additional.2=-Xmx512M

# Initial Java Heap Size (in MB)
#wrapper.java.initmemory=128

# Maximum Java Heap Size (in MB)
#wrapper.java.maxmemory=512

# Application parameters. Add parameters as needed starting from 1
wrapper.app.parameter.1=com.tanukisoftware.HelloWorld
wrapper.app.parameter.2=arg1
wrapper.app.parameter.3=arg2

Trying It Out

HelloWorld can now be run by simply executing the script bin/helloworld console. Because of the way the Wrapper sets its current directory, it is not necessary to run this script from within the bin directory.

As you will see if you omit a command, the scripts shipped with the Wrapper are fairly standard Daemon scripts. They accept console, start, stop, restart, and dump commands. The start, stop, and restart commands are common to most Daemon scripts and are used to control the Wrapper and its application as a Daemon process. The status command can be used to find out whether or not the Wrapper is currently running. The console command will launch the Wrapper in the current shell, making it possible to kill the application with CTRL-C. The final command, dump, will send a kill -3 signal to the Wrapper causing the its JVM to do a full thread dump.

Congratulations. Your application should now be up and running.

If you did have any problems, please take a look at the Troubleshooting section for help with tracking down the problem.

Advanced

Tuning The Startup

By default the WrapperSimpleApp class will wait 2 seconds for the user application's main method to complete. After that, it assumes that the application has started and reports back to the Wrapper process. This is done because many user applications are written with main methods that do not return for the life of the application. In such cases, there is no reliable way for the WrapperSimpleApp class to tell when and if the application has completed its startup.

If, however, it is known that the application's main method will return once the application is started, it would be ideal for the Wrapper to wait until it has done so before continuing.

waitForStartMain System Property:

For main methods that return in this way, the WrapperSimpleApp looks for the org.tanukisoftware.wrapper.WrapperSimpleApp.waitForStartMain system property. If it is set to TRUE, the WrapperSimpleApp will wait indefinitely for the main method to complete.

Example: (enable to wait)
wrapper.java.additional.10=-Dorg.tanukisoftware.wrapper.WrapperSimpleApp.waitForStartMain=TRUE

maxStartMainWait System Property:

Waiting indefinitely is an advantageous option if it known for sure that the main method will return in a timely manner. But on the other hand, while it is waiting eternally, the Wrapper will never give up on the startup process, no matter how long it takes.

So, if there is any chance that this startup could hang, then the org.tanukisoftware.wrapper.WrapperSimpleApp.maxStartMainWait system property to set the maximum wait time may be a better option. For instance, to wait for up to 5 minutes (300 seconds) for the startup main method to complete, set the property to 300 as follows:

The default value is 2 seconds.

Example: (300 seconds)
wrapper.java.additional.10=-Dorg.tanukisoftware.wrapper.WrapperSimpleApp.maxStartMainWait=300

NOTE

The main methods of many applications are designed not to return. In these cases, you must either stick with the default 2-second startup timeout or specify a slightly longer timeout, using the maxStartMainWait property, to simulate the amount of time your application takes to start up.

WARNING

If TRUE in the waitForStartMain is specified for an application whose start method never returns, the Wrapper will appear at first to be functioning correctly. However, the Wrapper is actually in a wait status eternally and will never enter a running state where it can monitor your application.