Skip to content

Instantly share code, notes, and snippets.

@zengxs
Last active August 14, 2022 17:26
Show Gist options
  • Save zengxs/a697d786b244d7b857d3d006213306a1 to your computer and use it in GitHub Desktop.
Save zengxs/a697d786b244d7b857d3d006213306a1 to your computer and use it in GitHub Desktop.
tomcat systemd service script
# Systemd unit file for tomcat
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target
[Service]
Type=forking
Environment=JAVA_HOME=/usr/lib/jvm/jre
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINE_BASE=/opt/tomcat
Environment='CATALINE_OPTS=-Xms128M -Xmx765M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.haedless=true -Djava.security.egd=file:/dev/./urandom'
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/bin/kill -15 $MAINPID
User=tomcat
Group=tomcat
[Install]
WantedBy=multi-user.target
Copy link

ghost commented Jun 29, 2017

Hi,

I tried the script. I need tomcat to be run as tomcat user and start automatically at the system boot. Everything's work fine except I am getting an exception in the startup log.

56:40.051[%!-5.5p]: ##VelocityEngineInitializationException## --> (ConfigurationAndResourceIntializationHandler.java:78)
com.sz.api.common.exceps.VelocityEngineInitializationException: ##Exception##
at com.sz.api.services.velocityengine.VelocityEngineHandler.initializeVelocityEngine(VelocityEngineHandler.java:64)
at com.sz.api.engine.alert.bootup.ConfigurationAndResourceIntializationHandler.initializeVelocityEngine(ConfigurationAndResourceIntializationHandler.java:230)
at com.sz.api.engine.alert.bootup.ConfigurationAndResourceIntializationHandler.configureHandler(ConfigurationAndResourceIntializationHandler.java:61)
at com.sz.api.engine.alert.driver.AlertEngineDriver.startSystem(AlertEngineDriver.java:40)
at com.sz.api.ws.bootstrap.StartUpService.initializeAlertEngine(StartUpService.java:309)
at com.sz.api.ws.bootstrap.StartUpService.init(StartUpService.java:70)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1267)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1186)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1081)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5027)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5314)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:977)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1655)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:473)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.velocity.exception.VelocityException: Failed to initialize an instance of org.apache.velocity.runtime.log.Log4JLogChute with the current runtime configuration.
at org.apache.velocity.runtime.log.LogManager.createLogChute(LogManager.java:206)
at org.apache.velocity.runtime.log.LogManager.updateLog(LogManager.java:255)
at org.apache.velocity.runtime.RuntimeInstance.initializeLog(RuntimeInstance.java:795)
at org.apache.velocity.runtime.RuntimeInstance.init(RuntimeInstance.java:250)
at org.apache.velocity.app.VelocityEngine.init(VelocityEngine.java:107)
at com.sz.api.services.velocityengine.VelocityEngineHandler.initializeVelocityEngine(VelocityEngineHandler.java:53)
... 22 more
Caused by: java.lang.RuntimeException: Error configuring Log4JLogChute :
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.apache.velocity.util.ExceptionUtils.createWithCause(ExceptionUtils.java:67)
at org.apache.velocity.util.ExceptionUtils.createRuntimeException(ExceptionUtils.java:45)
at org.apache.velocity.runtime.log.Log4JLogChute.initAppender(Log4JLogChute.java:133)
at org.apache.velocity.runtime.log.Log4JLogChute.init(Log4JLogChute.java:85)
at org.apache.velocity.runtime.log.LogManager.createLogChute(LogManager.java:157)
... 27 more
Caused by: java.io.FileNotFoundException: velocity.log (Permission denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.(FileOutputStream.java:221)
at java.io.FileOutputStream.(FileOutputStream.java:142)
at org.apache.log4j.FileAppender.setFile(FileAppender.java:294)
at org.apache.log4j.RollingFileAppender.setFile(RollingFileAppender.java:207)
at org.apache.log4j.FileAppender.(FileAppender.java:110)
at org.apache.log4j.RollingFileAppender.(RollingFileAppender.java:79)
at org.apache.velocity.runtime.log.Log4JLogChute.initAppender(Log4JLogChute.java:118)
... 29 more

this exception is not there when I start tomcat from CATALINA_HOME/bin directory.
I checked the file permission of velocity.log and it looks fine.

Below shows my script:

# Systemd unit file for tomcat
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target

[Service]
Type=forking

Environment=JRE_HOME=/usr
Environment=CATALINA_PID=/usr/share/apache-tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/usr/share/apache-tomcat
Environment=CATALINE_BASE=/usr/share/apache-tomcat
Environment='CATALINE_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.haedless=true -Djava.security.egd=file:/dev/./urandom'

ExecStart=/usr/share/apache-tomcat/bin/startup.sh
ExecStop=/bin/kill -15 $MAINPID

User=tomcat
Group=tomcat

[Install]
WantedBy=multi-user.target

Please advise!

@beuss
Copy link

beuss commented Aug 7, 2017

Just add WorkingDirectory=/usr/share/apache-tomcat to your service and you'll be fine (or use an absolute path on velocity.log)

Copy link

ghost commented Aug 10, 2017

@beuss Thanks man, it worked

@oers
Copy link

oers commented Jan 25, 2018

I had to use the following, because startup.sh returns immediatly and systemd.calls shutdown.sh.

My script uses catalina.sh run, which will run in the current window

[Unit]
Description=Tomcat
After=network.target

[Service]
User=tomcat
WorkingDirectory=/opt/tomcat
Environment=JRE_HOME=/usr/java/latest
Environment=JAVA_HOME=/usr/java/latest
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINE_BASE=/opt/tomcat
ExecStart=/opt/tomcat/bin/catalina.sh run
ExecStop=/opt/tomcat/bin/shutdown.sh
SyslogIdentifier=tomcat-%i

[Install]
WantedBy=multi-user.target 

@ShutUpMagda
Copy link

Thanks a lot @oers!

@crowmagnumb
Copy link

I had to use ExecStart=/opt/tomcat/bin/catalina.sh start.

Under upstart I had always used /opt/tomcat/bin/catalina.sh run. When I switched over to systemd I found that using this command made it so that systemd didn't properly start my service. The command systemctl start tomcat would not return back to the shell. Tomcat would start up fine but the service wasn't happy and would eventually timeout taking tomcat down with it. Using /opt/tomcat/bin/startup.sh worked but my set environment variables were ignored. I found that using /opt/tomcat/bin/catalina.sh start solved both of those problems.

@yateam
Copy link

yateam commented Dec 20, 2018

I had to use the following, because startup.sh returns immediately and systemd.calls shutdown.sh.

@oers Do you know why this happens?

I faced the same problem - and this workaround works, I am just trying to figure out why.

@yateam
Copy link

yateam commented Dec 20, 2018

@lvarela
Copy link

lvarela commented Jan 8, 2019

Only way to make tomcat 9.0.14 work with systemd units on Centos 7.6 was with oers example.
Here is what I use (with custom OPTS):

[Unit]
Description=Tomcat
After=network.target

[Service]
User=tomcat
WorkingDirectory=/opt/tomcat
Environment=JRE_HOME=/usr/lib/jvm/jre
Environment=JAVA_HOME=/usr/lib/jvm/jre
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINE_BASE=/opt/tomcat
Environment='CATALINA_OPTS=-Dfile.encoding=ISO-8859-1'
Environment='JAVA_OPTS=-server -Xms512M -Xmx1G -Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom  -XX:+UseConcMarkSweepGC -Djava.net.preferIPv4Stack=true -Dsun.net.inetaddr.ttl=0'
ExecStart=/opt/tomcat/bin/catalina.sh run
ExecStop=/opt/tomcat/bin/shutdown.sh
SyslogIdentifier=tomcat-%i

[Install]
WantedBy=multi-user.target

@mr-rycho
Copy link

mr-rycho commented Apr 2, 2019

Type=forking -> catalina.sh start or startup.sh
Type=simple (default?) -> catalina.sh run

@richardsonlima
Copy link

@mr-rycho In the Type=simple model, the process spawned by systemd is the dæmon

@ogronome
Copy link

catalinE ?! CATALINUS is much better )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment