The systemd author insists that everything should be callable from an elf binary? Who am I to argue? Actually, I like the idea. So, how would we go about running the tomcat startup?
The bones of a systemd configuration file looks like this:
[Unit] Description=Tomcat Web Server After=syslog.target [Service] ExecStart=/usr/bin/java Type=forking [Install] WantedBy=multi-user.target
The startscript for tomcat6 resides in /usr/sbin/tomcat6. Here’s the heart of it:
java -version
${JAVACMD} $JAVA_OPTS $CATALINA_OPTS \
-classpath “$CLASSPATH” \
-Dcatalina.base=”$CATALINA_BASE” \
-Dcatalina.home=”$CATALINA_HOME” \
-Djava.endorsed.dirs=”$JAVA_ENDORSED_DIRS” \
-Djava.io.tmpdir=”$CATALINA_TMPDIR” \
-Djava.util.logging.config.file=”${CATALINA_BASE}/conf/logging.properties” \
-Djava.util.logging.manager=”org.apache.juli.ClassLoaderLogManager” \
org.apache.catalina.startup.Bootstrap start \
>> ${CATALINA_BASE}/logs/catalina.out 2>&1 &
if [ ! -z “$CATALINA_PID” ]; then
echo $! > $CATALINA_PID
fi
Hrm. The -D options are a vestige of the bad-old days when Java said Environment variables were a no-no. Unfortunately, the variables of the form ‘catalina.base’ are not valid BASH variables, or we could elide even them.
Still, this is no an insurmountable problem. We can still call the code this way, I think. .
The only command line parameters we want to pass are ones that don’t change, so the line should be more like
ExecStart=/usr/bin/java org.apache.catalina.startup.Bootstrap start
First of all the CLASSPATH variable gets passed on anyway. That just needs to be produced, but not passed to the executable.
We can specify a file to be executed ahead of time. For example
ExecStartPre=/usr/share/tomcat6/setup-tomcat.sh
But that doesn’t help out with the other -D params. It is still a shell script, too. Lets take another look at org.apache.catalina.startup.Bootstrap. Here’s a copy.
Here we see that the environment variables passed in just get reprocessed. Now that System.getProperty can once again handle Environment variables, we could easily modify this file to convert catalina.home to “CATALINA_HOME” and so forth. Another simple approach would be to provide a command line option to read in a configuration file that has all of the variables defined, and to source it as a java .properties file.
This would get The basic launch to work, but, of course, loses out on some of the other benefits of systemd. The big one, as I see it is socket activation. Java needs a way to accept sockets from the operating system.Aside from the benefit from using systemd, this would allow Java process to run as non-privileged users, but still to work with ports under 1000, allowing, among other things, Tomcat to listen to ports 443 and 80.
“The systemd author insists that everything should be callable from an elf binary”: actually you can launch whatever shell script you want directly from ExecStart. E.g. I use something like that for jenkins:
[Service]
User=jenkins
ExecStart=/usr/bin/java -Xmx512m \
-jar /usr/lib/jenkins/jenkins.war
where /usr/bin/java is a shell script.
>The systemd author insists that everything should be callable from an elf binary?
Nope, no one has ever said that, you can execute whatever you want with ExecStart as long there is a shebang in the source file indicating in which interpreter it must run..see execve(2).
Yeah, I overstated my case.