Website Downloads Documentation Knowledgebase Wiki Issue tracker Commercial support

Running Daisy as a (Unix) service

If you want to run Daisy as part of your operational environment, you might prefer to run the different Daisy components as services, which you can easily start, stop and restart, and which ideally run under a specific user (perhaps with restricted privileges). We recommend using "wrapper" for this, a fine open source project from Tanuki Software. If you use wrapper and are happy with it, consider making a donation to its developers. Wrapper can be used both on Unix and Windows platforms, in order to run Daisy as a Windows service, though we haven't tested this. The Unix config below works.

Wrapper configuration

Of course, you start with downloading wrapper. There's binary releases for a lot of platforms, or you can download the sources, which are handily packaged together with the Ant build tool. As of currently (June 2005), the wrapper sources don't compile under Java 1.5, however.

You need to install wrapper somewhere, this might be in /opt or /usr/local. Next, create an environment variable ($WRAPPER_HOME) pointing to the wrapper installation directory.

I did this by editing the .profile file of the user which will be running Daisy (in which home directory I installed Daisy, i.e. /home/daisy):

JAVA_HOME=/usr/j2se ; export JAVA_HOME
DAISY_HOME=/home/daisy/daisy ; export DAISY_HOME
OPENJMS_HOME=$DAISY_HOME/openjms ; export OPENJMS_HOME
WRAPPER_HOME=/home/daisy/wrapper ; export WRAPPER_HOME
DAISY_DATADIR=/home/daisy/daisydata ; export DAISY_DATADIR

wrapper comes with a skeleton shell script which you can find in $WRAPPER_HOME/src/bin/sh.script.in. Make three copies of this file: one for OpenJMS, one for the Daisy repository, and one for the Wiki application. I'll call them dsy_openjms.sh, dsy_repo.sh and dsy_wiki.sh. Edit them as follows:

dsy_openjms.sh

#! /bin/sh

#
# Skeleton sh script suitable for starting and stopping 
# wrapped Java apps on the Solaris platform. 
#
# Make sure that PIDFILE points to the correct location,
# if you have changed the default location set in the 
# wrapper configuration file.
#

#-----------------------------------------------------------------------------
# These settings can be modified to fit the needs of your application

# Application
APP_NAME="dsy_openjms"
APP_LONG_NAME="Daisy OpenJMS Server"

# Wrapper
WRAPPER_CMD="$WRAPPER_HOME/bin/wrapper"
WRAPPER_CONF="./dsy_openjms_wrapper.conf"

# Priority at which to run the wrapper.  See "man nice" for valid priorities.
#  nice is only used if a priority is specified.
PRIORITY=

# Location of the pid file.
PIDDIR="."

# If uncommented, causes the Wrapper to be shutdown using an anchor file.
#  When launched with the 'start' command, it will also ignore all INT and
#  TERM signals.
#IGNORE_SIGNALS=true

# If specified, the Wrapper will be run as the specified user when the 'start'
#  command is passed to this script.  When running with the 'console' command
#  the current user will be used.
# IMPORTANT - Make sure that the user has the required privileges to write
#  the PID file and wrapper.log files.  Failure to be able to write the log
#  file will cause the Wrapper to exit without any way to write out an error
#  message.
# NOTE - This will set the user which is used to run the Wrapper as well as
#  the JVM and is not useful in situations where a privileged resource or
#  port needs to be allocated prior to the user being changed.
RUN_AS_USER=daisy

dsy_repo.sh

#! /bin/sh

DAISY_HOME=/home/daisy/daisy ; export DAISY_HOME
DAISY_DATADIR=/home/daisy/daisydata ; export DAISY_DATADIR
MERLIN_HOME=$DAISY_HOME/repository-server/merlin ; export MERLIN_HOME

#
# Skeleton sh script suitable for starting and stopping 
# wrapped Java apps on the Solaris platform. 
#
# Make sure that PIDFILE points to the correct location,
# if you have changed the default location set in the 
# wrapper configuration file.
#

#-----------------------------------------------------------------------------
# These settings can be modified to fit the needs of your application

# Application
APP_NAME="dsy_repo_srv"
APP_LONG_NAME="Daisy Repository Server"

# Wrapper
WRAPPER_CMD="$WRAPPER_HOME/bin/wrapper"
WRAPPER_CONF="./dsy_repo_wrapper.conf"

# Priority at which to run the wrapper.  See "man nice" for valid priorities.
#  nice is only used if a priority is specified.
PRIORITY=

# Location of the pid file.
PIDDIR="."

# If uncommented, causes the Wrapper to be shutdown using an anchor file.
#  When launched with the 'start' command, it will also ignore all INT and
#  TERM signals.
#IGNORE_SIGNALS=true

# If specified, the Wrapper will be run as the specified user when the 'start'
#  command is passed to this script.  When running with the 'console' command
#  the current user will be used.
# IMPORTANT - Make sure that the user has the required privileges to write
#  the PID file and wrapper.log files.  Failure to be able to write the log
#  file will cause the Wrapper to exit without any way to write out an error
#  message.
# NOTE - This will set the user which is used to run the Wrapper as well as
#  the JVM and is not useful in situations where a privileged resource or
#  port needs to be allocated prior to the user being changed.
RUN_AS_USER=daisy

dsy_wiki.sh

#! /bin/sh

DAISY_HOME=/home/daisy/daisy ; export DAISY_HOME
JETTY_HOME=$DAISY_HOME/daisywiki/jetty ; export JETTY_HOME

#
# Skeleton sh script suitable for starting and stopping 
# wrapped Java apps on the Solaris platform. 
#
# Make sure that PIDFILE points to the correct location,
# if you have changed the default location set in the 
# wrapper configuration file.
#

#-----------------------------------------------------------------------------
# These settings can be modified to fit the needs of your application

# Application
APP_NAME="dsy_wiki"
APP_LONG_NAME="Daisy Wiki Webapp (Cocoon)"

# Wrapper
WRAPPER_CMD="$WRAPPER_HOME/bin/wrapper"
WRAPPER_CONF="./dsy_wiki_wrapper.conf"

# Priority at which to run the wrapper.  See "man nice" for valid priorities.
#  nice is only used if a priority is specified.
PRIORITY=

# Location of the pid file.
PIDDIR="."

# If uncommented, causes the Wrapper to be shutdown using an anchor file.
#  When launched with the 'start' command, it will also ignore all INT and
#  TERM signals.
#IGNORE_SIGNALS=true

# If specified, the Wrapper will be run as the specified user when the 'start'
#  command is passed to this script.  When running with the 'console' command
#  the current user will be used.
# IMPORTANT - Make sure that the user has the required privileges to write
#  the PID file and wrapper.log files.  Failure to be able to write the log
#  file will cause the Wrapper to exit without any way to write out an error
#  message.
# NOTE - This will set the user which is used to run the Wrapper as well as
#  the JVM and is not useful in situations where a privileged resource or
#  port needs to be allocated prior to the user being changed.
RUN_AS_USER=daisy

Next, you need to create three configuration files for your wrapper scripts. Again, you'll find a skeleton configuration file in your wrapper installation directory (src/conf/wrapper.conf.in).

dsy_openjms_wrapper.conf

#********************************************************************
# Wrapper Properties
#********************************************************************
# Java Application
wrapper.java.command=%JAVA_HOME%/bin/java

# Java Main class.  This class must implement the WrapperListener interface
#  or guarantee that the WrapperManager class is initialized.  Helper
#  classes are provided to do this for you.  See the Integration section
#  of the documentation for details.
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

# Java Classpath (include wrapper.jar)  Add class path elements as
#  needed starting from 1
wrapper.java.classpath.1=%WRAPPER_HOME%/lib/wrapper.jar
wrapper.java.classpath.2=%DAISY_HOME%/lib/mysql/jars/mysql-connector-java-3.1.7-bin.jar
wrapper.java.classpath.3=%OPENJMS_HOME%/lib/openjms-0.7.6.1.jar

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

# Java Additional Parameters
wrapper.java.additional.1=-Dopenjms.home=%OPENJMS_HOME%
wrapper.java.additional.2=-Djava.security.manager
wrapper.java.additional.3=-Djava.security.policy=%OPENJMS_HOME%/config/openjms.policy

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

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

# Application parameters.  Add parameters as needed starting from 1
wrapper.app.parameter.1=org.exolab.jms.server.JmsServer

#********************************************************************
# Wrapper Logging Properties
#********************************************************************
# (I made no changes below this point)

dsy_repo_wrapper.conf

#********************************************************************
# Wrapper Properties
#********************************************************************
# Java Application
wrapper.java.command=%JAVA_HOME%/bin/java

# Java Main class.  This class must implement the WrapperListener interface
#  or guarantee that the WrapperManager class is initialized.  Helper
#  classes are provided to do this for you.  See the Integration section
#  of the documentation for details.
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

# Java Classpath (include wrapper.jar)  Add class path elements as
#  needed starting from 1
wrapper.java.classpath.1=%WRAPPER_HOME%/lib/wrapper.jar
wrapper.java.classpath.2=%DAISY_HOME%/repository-server/merlin/system/merlin/jars/merlin-cli-3.3.0.jar

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

# Java Additional Parameters
wrapper.java.additional.1=-Dmerlin.deployment.timeout=0
wrapper.java.additional.2=-Dmerlin.logging.config=%DAISY_DATADIR%/conf/logkit.xml
wrapper.java.additional.3=-Dfile.encoding=UTF-8

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

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

# Application parameters.  Add parameters as needed starting from 1
wrapper.app.parameter.1=org.apache.avalon.merlin.cli.Main
wrapper.app.parameter.2=-offline
wrapper.app.parameter.3=-home
wrapper.app.parameter.4=%DAISY_DATADIR%
wrapper.app.parameter.5=-repository
wrapper.app.parameter.6=%DAISY_HOME%/lib
wrapper.app.parameter.7=-config
wrapper.app.parameter.8=%DAISY_DATADIR%/conf/myconfig.xml
wrapper.app.parameter.9=%DAISY_HOME%/repository-server/conf/block.xml

dsy_wiki_wrapper.conf

#********************************************************************
# Wrapper Properties
#********************************************************************
# Java Application
wrapper.java.command=%JAVA_HOME%/bin/java

# Java Main class.  This class must implement the WrapperListener interface
#  or guarantee that the WrapperManager class is initialized.  Helper
#  classes are provided to do this for you.  See the Integration section
#  of the documentation for details.
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

# Java Classpath (include wrapper.jar)  Add class path elements as
#  needed starting from 1
wrapper.java.classpath.1=%WRAPPER_HOME%/lib/wrapper.jar
wrapper.java.classpath.2=%JETTY_HOME%/ext/ant.jar
wrapper.java.classpath.3=%JETTY_HOME%/ext/jasper-compiler.jar
wrapper.java.classpath.4=%JETTY_HOME%/ext/jasper-runtime.jar
wrapper.java.classpath.5=%JETTY_HOME%/ext/jcert.jar
wrapper.java.classpath.6=%JETTY_HOME%/ext/jmxri.jar
wrapper.java.classpath.7=%JETTY_HOME%/ext/jmxtools.jar
wrapper.java.classpath.8=%JETTY_HOME%/ext/jnet.jar
wrapper.java.classpath.9=%JETTY_HOME%/ext/jsse.jar
wrapper.java.classpath.10=%JETTY_HOME%/ext/xercesImpl.jar
wrapper.java.classpath.11=%JETTY_HOME%/ext/xml-apis.jar
wrapper.java.classpath.12=%JETTY_HOME%/lib/javax.servlet.jar
wrapper.java.classpath.13=%JETTY_HOME%/lib/org.mortbay.jetty.jar
wrapper.java.classpath.14=%JETTY_HOME%/lib/org.mortbay.jmx.jar
wrapper.java.classpath.15=%JAVA_HOME%/lib/tools.jar

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

# Java Additional Parameters
wrapper.java.additional.1=-Djetty.home=%JETTY_HOME%
wrapper.java.additional.2=-Ddaisywiki.home=%DAISY_HOME%/daisywiki
wrapper.java.additional.3=-Dfile.encoding=UTF-8
wrapper.java.additional.4=-Djava.endorsed.dirs=%DAISY_HOME%/daisywiki/endorsedlibs
wrapper.java.additional.5=-Dorg.mortbay.util.URI.charset=UTF-8

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

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

# Application parameters.  Add parameters as needed starting from 1
wrapper.app.parameter.1=org.mortbay.jetty.Server
wrapper.app.parameter.2=%DAISY_HOME%/daisywiki/conf/jetty-daisywiki.xml

As you now should be able to check out, the shell scripts expose the usual Unix service script behaviour:

-bash-3.00$ ./dsy_repo.sh 
Usage: ./dsy_repo.sh { console | start | stop | restart | status | dump }

This means you can also add them to the system service startup scripts (/etc/init.d), and configure when to start and stop them, depending on runlevel changes. Wrapper will make sure the scripts run under the user you configure.

Wrapper also monitors the JVM processes by "pinging" them regularily, and will even restart the processes if a VM gets stuck - which, under normal circumstances, shouldn't happen.

Hope this helps as a quick primer on how to use wrapper with Daisy. Wrapper's documentation is quite good, so please review it before asking questions.

Comments (0)
Advertisement

Daisy hosting, installation, support. Workshops and turnkey Daisy CMS projects. Get Daisy from its creators.

outerthought.org

Downloads provided by

SourceForge.net Logo

Open source stats