I'm trying to setup a Tomcat service with Systemd on CentOS 7.

I've installed Oracle Java 1.8u74 to /usr/java/jdk1.8.0_74 and set the environment variable $JAVA_HOME at boot like so:

# echo "export JAVA_HOME=/usr/java/jdk1.8.0_74" > /etc/profile.d/setenv.sh

When I login to the system I can run echo $JAVA_HOME and see the correct path. I have installed Tomcat and the tomcat.service file has the following:

# Systemd unit file for Tomcat

[Unit]
Description=Apache Tomcat
After=syslog.target network.target

[Service]
Type=forking

Environment=JAVA_HOME=/usr/java/jdk1.8.0_74
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'

ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh

User=tomcat
Group=www

[Install]
WantedBy=multi-user.target

The problem is that if I omit the line that reads Environment=JAVA_HOME=/usr/java/jdk1.8.0_74, Tomcat does not find $JAVA_HOME, but I expect it to find $JAVA_HOME because it is set in /etc/profile.d/setenv.sh.

My questions

  • Is it not found due to boot sequence (i.e. setenv.sh runs after the Systemd start)?
  • Did I put setenv.sh in the wrong place?
  • What's the best way to handle this?

This is the expected behavior with systemd.

To understand what the environment that systemd services run in, you can refer to man systemd.exec, specifically the section ENVIRONMENT VARIABLES IN SPAWNED PROCESSES. As it says, only very few variables are set, and you have to set anything else yourself.

It just happens that the files in /etc/profile.d are sourced by interactive shells, which is why you can see the variable when you log in. What you have done is exactly what the tutorial recommends, so you can just stick to it. If you are worried that a Java upgrade would break your unit file, you can make a symlink to your java installation, or even source the file at startup:

ExecStart=/bin/sh -c '. /etc/profile.d/setenv.sh; /opt/tomcat/bin/startup.sh'
ExecStop=/bin/sh -c '. /etc/profile.d/setenv.sh; /opt/tomcat/bin/shutdown.sh'

I would personally stick with what you have already.