|
|
 |
|
|  |
 |
 |
 |
| WrapperSimpleApp Integration (Linux / UNIX) |
WrapperSimpleApp Integration (Linux / UNIX)
 |
|
|
 |
 |
 |
|
The first method 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 shutdown 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. Both cases, with and without a
shutdown hook, provide the exact same behavior as if the application
was running without the Wrapper and a user pressed CTRL-C in the console.
When integrating with the WrapperSimpleApp
helper class, the WrapperSimpleApp
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.
The following section will walk you through a detailed explanation of
how to configure JBoss to
run within the Wrapper. Most other applications can be integrated by
following the same steps.
|
 |
 |
 |
 |
|
This tutorial will start with a clean install of
JBoss. We used version
3.0.4 so the exact steps may be slightly different depending
on the exact version installed. JBoss was installed in the
/usr/lib directory, resulting
in a JBoss Home directory of
/usr/lib/jboss-3.0.4.
|
 |
 |
|
There are four files which are required to be able to use the
Wrapper. We will also copy over a script which makes it easy to
launch and control the Wrapper.
|
NOTE
|  |
Please make sure that you are using the
wrapper, and
libwrapper.so files which
were built for the platform being run. It sounds obvious,
but the Linux version will not work on Solaris for example.
|
 |
 |
|
The Wrapper is shipped with a sh
script which can be used to reliably start and stop any Java
application controlled by the Java Service Wrapper.
First we will copy the following files into the JBoss
bin directory:
{WRAPPER_HOME}/bin/wrapper
{WRAPPER_HOME}/src/bin/sh.script.in
|
Rename the script file to reflect the name of the application.
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. Note that
the default values of both of these variables are
Ant friendly
tokens which can easily be replaced as part of a build.
Suggested values for these variables are shown below.
APP_NAME="jboss"
APP_LONG_NAME="JBoss Application Server"
|
These script should not require any additional modification.
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 locate this file someplace else, then that can also
be set using the WRAPPER_CONF
variable in the script.
|
NOTE
|  |
Important! Before proceeding, please make sure that all
three files copied into the bin
directory have their executable bit set.
|
|
 |
 |
|
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 required by the portion of the Wrapper which
runs within the JVM. The wrapper.jar
file contains all of the Wrapper classes.
|
 |
 |
|
The Wrapper requires a configuration file. The standard
location for this file is in a conf directory in the
application's home directory. JBoss does not have such
a directory by default, so we will need to create one.
Please do so and copy the template
wrapper.conf file to
that location:
{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:
{JBOSS_HOME}/conf/wrapper.conf
|
If you wish to relocate the configuration file, you are free
to do so. You will need to modify the batch scripts copied
into the bin directory above,
to reflect the new location.
|
 |
 |
|
The default wrapper.conf file
will place a wrapper.log file
in a logs directory under the
application home directory. JBoss does not have such a directory
by default, so we will need to create one. Please do so. You
should now have the following directory:
If you wish to place the 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.
|
|
 |
 |
|
Before the Wrapper can be configured to launch an Application,
you will need to know the full Java command which is normally
used.
Most applications make use of a script to build up the actual
command line. These scripts tend to get quite unwieldy and
in fact, the ability to avoid having to work with them is one of
the benefits of working with the Wrapper.
JBoss is launched by using a script called
run.sh. It is
launched by first changing the current directory to the
bin directory and then
run from there. If you open
run.sh into an editor, you
will notice the following lines towards the end of the file:
exec $JAVA $JAVA_OPTS \
-classpath "$JBOSS_CLASSPATH" \
org.jboss.Main "$@"
|
The majority of the script has the task of collecting system
specific information and storing that information into environment
variables. The lines above then expands all of the collected
information into the final Java command which launches the
application. From looking at the source of the script,
we hope you appreciate the complexity and the desire to have to
avoid completely writing such scripts yourself.
In order to configure the Wrapper, all that is really needed is
the final expanded command line. Rather than reading through the
entire script and attempting to understand it, we will use a
simple trick to display the final command line in the console.
Edit the script by changing it as follows:
#exec $JAVA $JAVA_OPTS \
# -classpath "$JBOSS_CLASSPATH" \
# org.jboss.Main "$@"
echo "exec $JAVA $JAVA_OPTS -classpath $JBOSS_CLASSPATH org.jboss.Main $@"
|
If you now rerun the script, you will see something like the
following in the console (Your output will all be on one line):
exec /opt/IBMJava2-131/bin/java -Dprogram.name=run.sh
-classpath /usr/lib/jboss-3.0.4/bin/run.jar:/opt/IBMJava2-131/lib/tools.jar org.jboss.Main
|
|
 |
 |
|
In order to be able to use this command with the Wrapper, we need
to break up its components. 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.
|
 |
 |
|
First is to extract the java executable and assign it to the
wrapper.java.command
property:
wrapper.java.command=/opt/IBMJava2-131/bin/java
|
|
 |
 |
|
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 JBoss command line only has one such property. In this
case, we have changed the name of the script used to launch
JBoss from run.sh, but
for consistency we will leave it as is.:
wrapper.java.additional.1=-Dprogram.name=run.sh
|
Notice that the full property was copied directly from the
command line without any modifications. See the property
documentation for details on how to handle properties
containing spaces.
|
 |
 |
|
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. Then, because we
will also be making use of the Wrapper, it is necessary to
include the wrapper.jar
file as well:
wrapper.java.classpath.1=/usr/lib/jboss-3.0.4/wrapper.jar
wrapper.java.classpath.2=/usr/lib/jboss-3.0.4/bin/run.jar
wrapper.java.classpath.3=/opt/IBMJava2-131/lib/tools.jar
|
|
 |
 |
|
The final component of the command used to launch JBoss is the
main class, org.jboss.Main.
The main class executed by Java when launched is specified by
using the
wrapper.java.mainclass
property. As mentioned above however. Because the JBoss main
class does not know how to communicate with the Wrapper, we
will set the main class to be the full class name of
WrapperSimpleApp.
The JBoss main class is then specified as the first application
parameter below.
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
|
|
 |
 |
|
Application parameters are set using the
wrapper.app-parameter.<n>
properties. Application parameters appear in the Java command
line directly after the main class. While JBoss does not have
any such parameters, it is still necessary to set one of these
properties. This is because we are using the
WrapperSimpleApp helper class
and as described above, its first parameter is the main class
name of the application being run. in this case,
org.jboss.Main:
wrapper.app.parameter.1=org.jboss.Main
|
|
 |
 |
|
In order to use the Wrapper, there is one more property which
much be set. The Wrapper makes use of a native library to
control interactions with the system. This 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-3.0.4/lib
|
|
 |
 |
|
Putting it all together, we get the following:
wrapper.java.command=/opt/IBMJava2-131/bin/java
wrapper.java.additional.1=-Dprogram.name=run.sh
wrapper.java.classpath.1=/usr/lib/jboss-3.0.4/wrapper.jar
wrapper.java.classpath.2=/usr/lib/jboss-3.0.4/bin/run.jar
wrapper.java.classpath.3=/opt/IBMJava2-131/lib/tools.jar
wrapper.java.library.path.1=/usr/lib/jboss-3.0.4/lib
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
wrapper.app.parameter.1=org.jboss.Main
|
Notice what while this will function correctly on this
particular machine, it is highly dependent on the directory
structure and platform. By taking advantage of the fact that
the Wrapper's scripts always set the current directory to the
location of the script, 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:
wrapper.java.command=%JAVA_HOME%/bin/java
wrapper.java.additional.1=-Dprogram.name=run.sh
wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=./run.jar
wrapper.java.classpath.3=%JAVA_HOME%/lib/tools.jar
wrapper.java.library.path.1=../lib
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
wrapper.app.parameter.1=org.jboss.Main
|
|
|
 |
 |
|
JBoss can now be run by simply executing
bin/jboss 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.
|
|
 |
 |
 |
 |
|
By default the WrapperSimpleApp class will wait 2 seconds for the user
application's main method to complete. If it does not do so then it
assumes that the application has started and reports that 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.
For main methods that return in this way, the WrapperSimpleApp looks
for the org...WrapperSimpleApp.waitForStartMain
system property. If it is set to TRUE, the WrapperSimpleApp will wait
indefinitely for the main method to complete.
wrapper.java.additional.1=-Dorg.tanukisoftware.wrapper.WrapperSimpleApp.waitForStartMain=TRUE
|
Waiting indefinitely is an option if it known for sure that the main
method will return in a timely manner. But while it is waiting, the
Wrapper will never give up on the startup process, no matter how long
it takes. But if there is any chance that this startup could hang, then
the org...WrapperSimpleApp.maxStartMainWait
system property may be a better option. It allows the 2 second wait time to be
overridden. To wait for up to 5 minutes for the startup main method to
complete, set the property to 300 as follows (defaults to 2 seconds):
wrapper.java.additional.1=-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 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 will never enter a running
state, this means that the Windows Service Manager and several of the
Wrapper's error recovery mechanisms will not function correctly.
|
|
|
|
|
|
| |
 | If you notice something that is incorrect, missing, or simply feel that some part of this page could be explained better, feel free to log in and add a comment. You will need to register before you can log on.  |  |  Wayne, The Wrapper is mainly a native application which is used to work with Java applications. For that reason, there are platform specific versions of the Wrapper which need to be downloaded or compiled. Windows versions supply a wrapper.exe and wrapper.dll file. But on UNIX or Linux versions a wrapper and libwrapper.so file is supplied. If you download the distribution for the UNIX platform you are trying to integrate to, you will find all the files you need. Cheers, Leif |
 |  |  Hi, In integrated method 1 - WrapperSimpleApp Integration (Linux / UNIX), I got confused on: First we will copy the following files into the JBoss bin directory: {WRAPPER_HOME}/bin/wrapper {WRAPPER_HOME}/src/bin/sh.script.in What does wrapper reger to? Is it wrapper.exe? Can a .exe file be run under Unix? Can anyone help me? Thanks a lot. Best regards, Wayne |
|
|
|  |
|
 |
|