JBoss Community

Currently Being Moderated

StartJBossOnBootWithLinux

VERSION 27

Created on: Feb 25, 2004 11:39 AM by unknownMigrationUser - Last Modified:  Apr 4, 2008 11:10 AM by consquigulator

How do I Start JBoss on boot with Linux?

 

Overview

 

Linux uses System V init scripts.  Although there can be some differences between distributions, generally it looks like this:

 

  • /etc/rc.d/init.d/ - contains the start and stop scripts (other distributions: /etc/init.d/)

  • /etc/rc.(x)/ - contains links to the start and stop scripts prefixed with S or K (start or kill respectively)

 

There are various run levels for various stages of system use.

 

  1. rc1.d - Single User Mode

  2. rc2.d - Single User Mode with Networking

  3. rc3.d - Multi-User Mode - boot up in text mode

  4. rc4.d - Undefined

  5. rc5.d - Multi-User Mode - boot up in X Windows

  6. rc6.d - Shutdown

 

Most Linux systems used as Application Servers boot into run level 3 (if not, your system admin needs to be questioned on why your server needs to boot into X-Windows and needlessly waste system resources).

 

Your task is to:

 

  • create a user for JBoss (recommended) so that JBoss can be restricted to accessing only the files and system resources that it has permission to access via the "jboss" user.

  • create a script called /etc/rc.d/init.d/jboss

  • create a link called /etc/rc3.d/S84jboss

    • optionally /etc/rc5.d/S84jboss and /etc/rc4.d/S84jboss

  • create a link called /etc/rc6.d/K15jboss

    • create the K15 link in /etc/rc1.d, /etc/rc2.d, /etc/rc0.d

-


Create a user called "jboss" (recommended)

 

As root type "adduser --system jboss" and enter a password in case you later want to login as user jboss; Normally you will treat jboss like the users apache, www, postgres,... and disable direct login. Su to jboss and install the server in $JBOSS_HOME. Make sure the $JBOSS_HOME directory can be read by "jboss" and that the $JBOSS_HOME/server/default/work directory can be read and written. In case some permissions are messed up check the RecommendedUNIXFilesystemPermissionsForJBossApplicationServer.

 

Note that SELinux environment uses "runuser" instead of "su" (see below). "runuser" requires a

valid shell like "bin/sh" for your JBOSS user.

 

-


Create the script in /etc/rc.d/init.d

 

As root (su - root) type vi /etc/rc.d/init.d/jboss and paste the below:

 


#! /bin/sh


start(){
        echo "Starting jboss.."

        # If using an SELinux system such as RHEL 4, use the command below
        # instead of the "su":
        # eval "runuser - jboss -c '/opt/jboss/current/bin/run.sh > /dev/null 2> /dev/null &'
        # if the 'su -l ...' command fails (the -l flag is not recognized by my su cmd) try:
        #   sudo -u jboss /opt/jboss/bin/run.sh > /dev/null 2> /dev/null &
        su -l jboss -c '/opt/jboss/current/bin/run.sh > /dev/null 2> /dev/null &'
}

stop(){
        echo "Stopping jboss.."

        # If using an SELinux system such as RHEL 4, use the command below
        # instead of the "su":
        # eval "runuser - jboss -c '/opt/jboss/current/bin/shutdown.sh -S &'
        # if the 'su -l ...' command fails try:
        #   sudo -u jboss /opt/jboss/bin/shutdown.sh -S &
        su -l jboss -c '/opt/jboss/current/bin/shutdown.sh -S &'
}

restart(){
        stop
# give stuff some time to stop before we restart
        sleep 60
# protect against any services that can't stop before we restart (warning this kills all Java instances running as 'jboss' user)
        su -l jboss -c 'killall java'
# if the 'su -l ...' command fails try:
        #   sudo -u jboss killall java
        start
}




case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        restart
        ;;
  *)
        echo "Usage: jboss {start|stop|restart}"
        exit 1
esac

exit 0

 

Also as root type "chmod 755 /etc/rc.d/init.d/jboss" in order to make the script executable.  You should be able to test it by typing "service jboss stop", "service jboss start" and so forth.  Note that the script hard codes $JBOSS_HOME so make sure that it reflects your JBOSS_HOME.  Because the console output is also in the server.log we're just sending it to /dev/null.

 

The restart target in this script does not perform the same actions as a stop followed by a start; it contains a hard-coded 60-second sleep before killing Java the hard way.  This has several negative effects, including:

  • making a restart take at least 60 seconds (incurring at least 60 seconds service downtime)

  • potentially aborting a JBoss instance that would have shut down of its own accord in due course (the corollary of this is that the stop target is not guaranteed to stop the running JBoss instance)

 

 

Using the included init Scripts (JBoss 4.0.1 and higher)

Alternatively, JBoss 4.0.1 (and higher) comes with prebaked init scripts in the bin directory, jboss_init_redhat.sh and jboss_init_suse.sh.  You can copy one of these scripts to /etc/rc.d/init.d/jboss, then make the links below, or create a symbolic link from /etc/rc.d/init.d/jboss to one of them.  These scripts don't pipe logging to /dev/null, but to a real file, so you'll have to add one additional step:

 


mkdir $JBOSS_HOME/log
chown jboss $JBOSS_HOME/log

 

You will also need to modify the start and stop commands to use "runuser" instead of "su" if using a SELinux distribution such as RHEL 4.

 

example modifications:


JBOSSUS=${JBOSSUS:-"jboss"}                        # put this before JBOSS_CONSOLE def                                
SUBIT="runuser - $JBOSSUS -c "                     # replace su by runuser due to SELinux
JBOSS_CONSOLE="$JBOSS_HOME/log/jboss.log"          # instead of nothing 
chown $JBOSSUS $JBOSS_CONSOLE                      # make log writable by JBOSS user               
JBOSSSH=${JBOSSSH:-"$JBOSS_HOME/bin/run.sh -c default"} # change "all" for "default"  

 

-


create links

 

The links will be used to identify at which run levels JBoss should be started and stopped.  In general this is probably what you want (do as root):

 


ln -s /etc/rc.d/init.d/jboss /etc/rc3.d/S84jboss
ln -s /etc/rc.d/init.d/jboss /etc/rc5.d/S84jboss 
ln -s /etc/rc.d/init.d/jboss /etc/rc4.d/S84jboss

ln -s /etc/rc.d/init.d/jboss /etc/rc6.d/K15jboss 
ln -s /etc/rc.d/init.d/jboss /etc/rc0.d/K15jboss
ln -s /etc/rc.d/init.d/jboss /etc/rc1.d/K15jboss
ln -s /etc/rc.d/init.d/jboss /etc/rc2.d/K15jboss

 

Linux will execute the equivilent of "service jboss start" for the "S" links and "service jboss stop" for the K links.

 

RedHat has a chkconfig command to manage these links, which may or may not work (it uses comments in the top of the script to determine which run-levels it should be started/stopped in).  For Debian or Ubuntu, use update-rc.d(8).  For SuSe, use the insserv command to properly register the new jboss script--skip the symlinking you see above, this will be ignored and will not run JBoss at boot time).

 

-


Using Tanuki Software's Java Service Wrapper

 

Have a look at http://wrapper.tanukisoftware.org/ - the Java Service Wrapper is a very powerful service wrapper for any Java application and works fine with JBoss.

 

You can also have a look at the Windows Java Service page, which has more instructions and configuration options for the Java Service Wrapper. 

 

A basic wrapper.conf would look like this:

 


wrapper.java.command=/usr/java/bin/java
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=run.jar
wrapper.java.classpath.3=/usr/java/lib/tools.jar

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

wrapper.java.additional.1=-server
wrapper.java.additional.2=-Dprogram.name=run.sh

wrapper.java.initmemory=256
wrapper.java.maxmemory=256

wrapper.app.parameter.1=org.jboss.Main
wrapper.app.parameter.2=-c
wrapper.app.parameter.3=default

wrapper.console.format=PM
wrapper.console.loglevel=INFO

wrapper.logfile=wrapper.log
wrapper.logfile.format=LPTM
wrapper.logfile.loglevel=INFO
wrapper.logfile.maxsize=1m
wrapper.logfile.maxfiles=1

wrapper.syslog.loglevel=NONE

 

Average User Rating
(0 ratings)




Henning Vogt Henning Vogt  says:

What I would not like about the init script above is, that "restart" kills all the java apps for the user, but starts only the jboss anew.  This is not healthy for a production system.

 

Much nicer is:

  • Linux bash: export LAUNCH_JBOSS_IN_BACKGROUND=true
  • patch run.sh to include "echo $JBOSS_PID>$JBOSS_HOME/jboss.pid"
  • start bin/run.sh

 

include this in your init-script for stopping (untested from the top of my head):

kill -HUP $(cat <jboss_path>/jboss.pid)
sleep 10
kill -9  $(cat <jboss_path>/jboss.pid)

 

and you are a little bit better off, than relying on jboss' shutdown script, which does not kill an unstable jboss (which CAN happen, and then you need a gut shutdown-script, beeing able to handle this incident)...

Sparkle Arkle Sparkle Arkle  says in response to Henning Vogt:

Also be aware of the Solaris bug where the wait command doesn't work properly.

I use a jboss start/stop script like this:

#!/bin/ksh
JBOSS_HOME=/usr/local/jboss
JAVA_HOME=/usr/java
CONFIG=<set it here or pass it as a variable>
BIND=<set it here or pass it as a variable>
PIDFILE=${JBOSS_HOME}/jboss_${CONFIG}.pid
LAUNCH_JBOSS_IN_BACKGROUND=true
PATH=$PATH:${JBOSS_HOME}/bin:${JAVA_HOME}/bin
export JBOSS_HOME JAVA_HOME CONFIG RUN_CONF PIDFILE LAUNCH_JBOSS_IN_BACKGROUND P
ATH

 

case $1 in
start)
        ${JBOSS_HOME}/bin/run_jboss.sh -b ${BIND} -c ${CONFIG} 2>&1 &
;;
stop)
        PID=`cat ${PIDFILE}`
        /usr/bin/kill -HUP ${PID}
        rm ${PIDFILE}
;;
*)
        echo "usage: $0 (start|stop)"
;;
esac

Simple but effective. I moved my config stuff to the run_${CONFIG}.conf file in the bin directory. The run_jboss.sh is just a copy of run.sh with the non relevant stuff taken out and the reference to my config specific run.conf file updated. I also do the write to the pid file from there.

 

Here is is, pardon the Solaris specific slant, you can see the patch for the wait section. Pardon my mixed variable syntax, I use ${VAR} they use don't and I haven't cleaned up. I hope this helps someone:

 

#!/bin/sh
### ====================================================================== ###
##                                                                          ##
##  JBoss Bootstrap Script                                                  ##
##                                                                          ##
### ====================================================================== ###

 

### $Id: run.sh 73862 2008-05-30 18:27:03Z mmoyses $ ###

 

DIRNAME=`dirname $0`
PROGNAME=`basename $0`
GREP="grep"

 

# Set conf if specified, else set to production
JBOSSCONF="production"
CONF_SPECIFIED=false
JBOSS_HOME=/usr/local/jboss
JAVA_HOME=/usr/java

 

arg_count=1
eval SWITCH=\${$arg_count}
while [ ! -z "$SWITCH" ]
do

 

        if [ "$SWITCH" = "-c" ]; then
            eval JBOSSCONF=\$`expr $arg_count + 1`
            CONF_SPECIFIED=true
            break
        fi

 

        arg_count=`expr $arg_count + 1`
        eval SWITCH=\${$arg_count}
done

 

if [ x${CONF_SPECIFIED} = "xfalse" ]
then
   set -- "-c" ${JBOSSCONF} $@
fi

 

# Use the maximum available, or set MAX_FD != -1 to use that
MAX_FD="maximum"

 

#
# Helper to complain.
#
warn() {
    echo "${PROGNAME}: $*"

}

 

 

#
# Helper to puke.
#
die() {
    warn $*
    exit 1
}

 

# Read an optional running configuration file
if [ "x$RUN_CONF" = "x" ]; then

 

    if [ ! -z "$JBOSSCONF" ] && [ -f "$DIRNAME/../server/$JBOSSCONF/run.conf" ]; then
        RUN_CONF="$DIRNAME/../server/$JBOSSCONF/run.conf"
    else
        RUN_CONF="$DIRNAME/run_${JBOSSCONF}.conf"
    fi
fi
echo $RUN_CONF
if [ -r "$RUN_CONF" ]; then
    . "$RUN_CONF"
fi

 

MAX_FD_LIMIT=`ulimit -H -n`
ulimit -n $MAX_FD_LIMIT

 

JAVA="$JAVA_HOME/bin/java"

 

# Setup the classpath
runjar="$JBOSS_HOME/bin/run.jar"
if [ ! -f "$runjar" ]; then
    die "Missing required file: $runjar"
fi
JBOSS_BOOT_CLASSPATH="$runjar"

 

# Tomcat uses the JDT Compiler
# Only include tools.jar if someone wants to use the JDK instead.
# compatible distribution which JAVA_HOME points to
if [ "x$JAVAC_JAR" = "x" ]; then
    JAVAC_JAR_FILE="$JAVA_HOME/lib/tools.jar"
else
    JAVAC_JAR_FILE="$JAVAC_JAR"
fi

 

if [ "x$JBOSS_CLASSPATH" = "x" ]; then

    JBOSS_CLASSPATH="$JBOSS_BOOT_CLASSPATH"
else
    JBOSS_CLASSPATH="$JBOSS_CLASSPATH:$JBOSS_BOOT_CLASSPATH"
fi
if [ "x$JAVAC_JAR_FILE" != "x" ]; then
    JBOSS_CLASSPATH="$JBOSS_CLASSPATH:$JAVAC_JAR_FILE"
fi

 

# If -server not set in JAVA_OPTS, set it, if supported
SERVER_SET=`echo $JAVA_OPTS | $GREP "\-server"`
if [ "x$SERVER_SET" = "x" ]; then

 

    # Check for SUN(tm) JVM w/ HotSpot support
    if [ "x$HAS_HOTSPOT" = "x" ]; then
        HAS_HOTSPOT=`"$JAVA" -version 2>&1 | $GREP -i HotSpot`
    fi
fi

 

# Setup JBosst Native library path
JBOSS_NATIVE_DIR="$JBOSS_HOME/bin/native"
if [ -d "$JBOSS_NATIVE_DIR" ]; then
    if [ "x$LD_LIBRARY_PATH" = "x" ]; then
        LD_LIBRARY_PATH="$JBOSS_NATIVE_DIR"
    else
        LD_LIBRARY_PATH="$JBOSS_NATIVE_DIR:$LD_LIBRARY_PATH"
    fi
    export LD_LIBRARY_PATH
    if [ "x$JAVA_OPTS" = "x" ]; then
        JAVA_OPTS="-Djava.library.path=$JBOSS_NATIVE_DIR"
    else
        JAVA_OPTS="$JAVA_OPTS -Djava.library.path=$JBOSS_NATIVE_DIR"
    fi
fi

 

# Setup JBoss sepecific properties
JAVA_OPTS="-Dprogram.name=$PROGNAME $JAVA_OPTS"

 

# Setup the java endorsed dirs
JBOSS_ENDORSED_DIRS="$JBOSS_HOME/lib/endorsed"

 

# Display our environment
echo "========================================================================="
echo ""
echo "  JBoss Bootstrap Environment"
echo ""
echo "  JBOSS_HOME: $JBOSS_HOME"
echo ""

echo "  JAVA: $JAVA"
echo ""
echo "  JAVA_OPTS: $JAVA_OPTS"
echo ""
echo "  CLASSPATH: $JBOSS_CLASSPATH"
echo ""
echo "========================================================================="
echo ""

 

while true; do
   if [ "x$LAUNCH_JBOSS_IN_BACKGROUND" = "x" ]; then
      # Execute the JVM in the foreground
      "$JAVA" $JAVA_OPTS \
         -Djava.endorsed.dirs="$JBOSS_ENDORSED_DIRS" \
         -classpath "$JBOSS_CLASSPATH" \
         org.jboss.Main "$@"
      JBOSS_STATUS=$?
   else
      # Execute the JVM in the background
      "$JAVA" $JAVA_OPTS \
         -Djava.endorsed.dirs="$JBOSS_ENDORSED_DIRS" \
         -classpath "$JBOSS_CLASSPATH" \
         org.jboss.Main "$@" &
      JBOSS_PID=$!
      echo $JBOSS_PID > $JBOSS_HOME/jboss_${JBOSSCONF}.pid
      # Trap common signals and relay them to the jboss process
      trap "kill -HUP  $JBOSS_PID" HUP
      trap "kill -TERM $JBOSS_PID" INT
      trap "kill -QUIT $JBOSS_PID" QUIT
      trap "kill -PIPE $JBOSS_PID" PIPE
      trap "kill -TERM $JBOSS_PID" TERM
      # Wait until the background process exits
      WAIT_STATUS=128
      while [ "$WAIT_STATUS" -ge 128 ]; do
         wait $JBOSS_PID 2>/dev/null
         WAIT_STATUS=$?
         if [ "${WAIT_STATUS}" -gt 128 ]; then
            SIGNAL=`expr ${WAIT_STATUS} - 128`
            SIGNAL_NAME=`kill -l ${SIGNAL}`
            echo "*** JBossAS process (${JBOSS_PID}) received ${SIGNAL_NAME} signal. ***" >&2
         fi
      done
      if [ "${WAIT_STATUS}" -lt 127 ]; then
         JBOSS_STATUS=$WAIT_STATUS
      else
         JBOSS_STATUS=0

      fi
   fi
   # If restart doesn't work, check you are running JBossAS 4.0.4+
   #    http://jira.jboss.com/jira/browse/JBAS-2483
   # or the following if you're running Red Hat 7.0
   #    http://developer.java.sun.com/developer/bugParade/bugs/4465334.html
   if [ "$JBOSS_STATUS" -eq 10 ]; then
      echo "Restarting JBoss..."
   else
      exit $JBOSS_STATUS
   fi
done

Franklin Norman Franklin Norman  says:

I am using JBossAS without Apache.  I am using JBossAS to serve both static and dynamic content.  If I run JBossAS as user 'jboss', then 'jboss' doesn't have access to port 80 (or any other port below 1024).  Is there a way to grant access to user 'jboss' to port 80?

Henrik Aronsen Henrik Aronsen  says:
The standard jboss_init_redhat.sh is pretty crude.  Here's my take at a better init script: https://jira.jboss.org/jira/browse/JBPAPP-3194

More Like This

  • Retrieving data ...

Incoming Links