Method 4 - WrapperJarApp Integration (Linux / UNIX)

Overview

The fourth and final method is to use the WrapperJarApp helper class to launch the application. This is another simple way to integrate with the Wrapper when the application is already configured to run as an executable jar.

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 shut down 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 4 (WrapperJarApp helper class), the WrapperJarApp class replaces an application's main class. This gives the WrapperJarApp class a chance to immediately initialize the WrapperManager and register the JVM with the Wrapper. The WrapperJarApp 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 jar's manifest is inspected and its configured main class is called. The WrapperJarApp creates a new ClassLoader which is able to load classes from the executable jar file as well as any other jar files referenced within its manifest file.

The WrapperJarApp helper class is told how to launch the application by passing the absolute or relative location of the executable jar file, followed by any additional application parameters to the main method of the WrapperJarApp.

Detailed Instructions

This section will walk you through a detailed explanation of how to configure JBoss to run within the Wrapper. Most other applications deployed as executable jars can be integrated by following the same steps.

Install JBoss EAP

This tutorial will start with a clean install of JBoss EAP. We used JBoss EAP 7.0.0, so the exact steps may be slightly different depending on the exact version installed. After downloading JBoss, extract the files somewhere. In this tutorial we will use the folder /usr/lib/jboss. Then create the following folders:

mkdir /usr/lib/jboss/lib
mkdir /usr/lib/jboss/conf
mkdir /usr/lib/jboss/logs

Installing Wrapper Files

After downloading the Wrapper, extract the files somewhere, that will be referenced as {WRAPPER_HOME}. There are four directories which are required to be configured in order to be able to use the Wrapper.

NOTE

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

{JBOSS_HOME}/bin/myJBoss

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 JBoss. 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="jboss"
APP_LONG_NAME="JBoss EAP"

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 following two files into the JBoss 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

The Wrapper requires a configuration file "wrapper.conf" for each application. 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 JBoss conf directory.

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

Rename the file and be sure to remove the .in extension so that the file is named wrapper.conf.

You should now have:

{JBOSS_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 script 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 into the JBoss logs directory.

{JBOSS_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.

The Java Command Line

The Java command line of an executable jar is quite simple. In the case of JBoss, you would simply go to the JBoss directory and execute:

java -jar /usr/lib/jboss/jboss-modules.jar

Any arguments would be passed in as follows:

java -jar /usr/lib/jboss/jboss-modules.jar arg1 arg2 arg3

Modifying the "wrapper.conf" File

In order 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

For all properties 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.

Java Executable

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

wrapper.java.command=java

Wrapper Jar

The Wrapper requires that its wrapper.jar be specified:

wrapper.jarfile=/usr/lib/jboss/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. Java does not actually allow you to specify a classpath when running with the -jar parameter but this integration with the Wrapper works a little differently.

wrapper.java.classpath.1=/usr/lib/jboss/jboss-modules.jar

Main Class

When using the Wrapper and the WrapperJarApp helper class, Java is not executing the jar directly. It is necessary to specify the helper class as the main class of the application. The main class executed by Java when launched is specified by using the wrapper.java.mainclass property as follows:

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperJarApp

Application Parameters

Application parameters are set using the wrapper.app.parameter.<n> properties. In this case, the command line to launch JBoss requires some application parameters. It is necessary to tell the WrapperJarApp helper class which jar to execute. This is done as follows:

wrapper.app.parameter.1=/usr/lib/jboss/jboss-modules.jar
wrapper.app.parameter.2=-mp
wrapper.app.parameter.3=/usr/lib/jboss/modules
wrapper.app.parameter.4=-jaxpmodule
wrapper.app.parameter.5=javax.xml.jaxp-provider
wrapper.app.parameter.6=org.jboss.as.standalone
wrapper.app.parameter.7=-Djboss.home.dir=/usr/lib/jboss
wrapper.app.parameter.8=-Djboss.server.base.dir=/usr/lib/jboss/standalone

Java additional Parameters

Java additional parameters are set using the wrapper.java.additional.<n> properties. Some parameters must be set for the JVM in order to start JBoss correctly.

wrapper.java.additional.1=-D"[Standalone]"
wrapper.java.additional.2=-server
wrapper.java.additional.3=-XX:+UseCompressedOops
wrapper.java.additional.4=-Xms1303M
wrapper.java.additional.5=-Xmx1303M
wrapper.java.additional.6=-Djava.net.preferIPv4Stack=true
wrapper.java.additional.7=-Djboss.modules.system.pkgs=org.jboss.byteman
wrapper.java.additional.8=-Djava.awt.headless=true
wrapper.java.additional.9=-Dorg.jboss.boot.log.file=/usr/lib/jboss/standalone/log/server.log
wrapper.java.additional.10=-Dlogging.configuration=file:/usr/lib/jboss/standalone/configuration/logging.properties
wrapper.java.additional.11=-Dorg.tanukisoftware.wrapper.WrapperManager.mbean=false
wrapper.java.additional.12=-Djava.util.logging.manager=org.jboss.logmanager.LogManager
wrapper.java.additional.13=-Dorg.jboss.logging.Logger.pluginClass=org.jboss.logging.logmanager.LoggerPluginImpl

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.

JBoss does not have any native libraries of its own, but if it did, the directories where they were located would also need to be specified. The library path is set using the wrapper.java.library.path.<n> properties.

wrapper.java.library.path.1=/usr/lib/jboss/lib

Putting It All Together

Putting it all together, we get the following:

wrapper.java.command=java

wrapper.jarfile=/usr/lib/jboss/lib/wrapper.jar

wrapper.java.classpath.1=/usr/lib/jboss/jboss-modules.jar

wrapper.java.library.path.1=/usr/lib/jboss/lib

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperJarApp

wrapper.java.additional.1=-D"[Standalone]"
wrapper.java.additional.2=-server
wrapper.java.additional.3=-XX:+UseCompressedOops
wrapper.java.additional.4=-Xms1303M
wrapper.java.additional.5=-Xmx1303M
wrapper.java.additional.6=-Djava.net.preferIPv4Stack=true
wrapper.java.additional.7=-Djboss.modules.system.pkgs=org.jboss.byteman
wrapper.java.additional.8=-Djava.awt.headless=true
wrapper.java.additional.9=-Dorg.jboss.boot.log.file=/usr/lib/jboss/standalone/log/server.log
wrapper.java.additional.10=-Dlogging.configuration=file:/usr/lib/jboss/standalone/configuration/logging.properties
wrapper.java.additional.11=-Dorg.tanukisoftware.wrapper.WrapperManager.mbean=false
wrapper.java.additional.12=-Djava.util.logging.manager=org.jboss.logmanager.LogManager
wrapper.java.additional.13=-Dorg.jboss.logging.Logger.pluginClass=org.jboss.logging.logmanager.LoggerPluginImpl

wrapper.app.parameter.1=/usr/lib/jboss/jboss-modules.jar
wrapper.app.parameter.2=-mp
wrapper.app.parameter.3=/usr/lib/jboss/modules
wrapper.app.parameter.4=-jaxpmodule
wrapper.app.parameter.5=javax.xml.jaxp-provider
wrapper.app.parameter.6=org.jboss.as.standalone
wrapper.app.parameter.7=-Djboss.home.dir=/usr/lib/jboss
wrapper.app.parameter.8=-Djboss.server.base.dir=/usr/lib/jboss/standalone

Notice, while these configurations will work correctly on our test machine, it is highly dependent on the directory structure and platform. By taking advantage of the fact that the Wrapper always sets the working directory to the location of the wrapper.exe file and by making use of a single environment variable, we are able to modify the above properties so that they are completely platform and machine independent:

set.JBOSS_HOME=/usr/lib/jboss

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

wrapper.jarfile=../lib/wrapper.jar

wrapper.java.classpath.1=../jboss-modules.jar

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

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperJarApp

wrapper.java.additional.1=-D"[Standalone]"
wrapper.java.additional.2=-server
wrapper.java.additional.3=-XX:+UseCompressedOops
wrapper.java.additional.4=-Xms1303M
wrapper.java.additional.5=-Xmx1303M
wrapper.java.additional.6=-Djava.net.preferIPv4Stack=true
wrapper.java.additional.7=-Djboss.modules.system.pkgs=org.jboss.byteman
wrapper.java.additional.8=-Djava.awt.headless=true
wrapper.java.additional.9=-Dorg.jboss.boot.log.file=%JBOSS_HOME%/standalone/log/server.log
wrapper.java.additional.10=-Dlogging.configuration=file:%JBOSS_HOME%/standalone/configuration/logging.properties
wrapper.java.additional.11=-Dorg.tanukisoftware.wrapper.WrapperManager.mbean=false
wrapper.java.additional.12=-Djava.util.logging.manager=org.jboss.logmanager.LogManager
wrapper.java.additional.13=-Dorg.jboss.logging.Logger.pluginClass=org.jboss.logging.logmanager.LoggerPluginImpl

wrapper.app.parameter.1=../jboss-modules.jar
wrapper.app.parameter.2=-mp
wrapper.app.parameter.3=%JBOSS_HOME%/modules
wrapper.app.parameter.4=-jaxpmodule
wrapper.app.parameter.5=javax.xml.jaxp-provider
wrapper.app.parameter.6=org.jboss.as.standalone
wrapper.app.parameter.7=-Djboss.home.dir=%JBOSS_HOME%
wrapper.app.parameter.8=-Djboss.server.base.dir=%JBOSS_HOME%/standalone

Trying It Out

JBoss can now be run by simply executing the script bin/myJBoss 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 script shipped with the Wrapper is fairly standard Daemon script. 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 its JVM to do a full thread dump.

Congratulations. Your application should now be up and running.

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