Skip to content

Instantly share code, notes, and snippets.

@zengxs
Last active August 14, 2022 17:26
Show Gist options
  • Select an option

  • Save zengxs/a697d786b244d7b857d3d006213306a1 to your computer and use it in GitHub Desktop.

Select an option

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

ghost commented Jun 29, 2017

Copy link
Copy Markdown

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

beuss commented Aug 7, 2017

Copy link
Copy Markdown

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

ghost commented Aug 10, 2017

Copy link
Copy Markdown

@beuss Thanks man, it worked

@oers

oers commented Jan 25, 2018

Copy link
Copy Markdown

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
Copy Markdown

Thanks a lot @oers!

@crowmagnumb

Copy link
Copy Markdown

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.

@mitya-multiplayer

Copy link
Copy Markdown

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.

@mitya-multiplayer

Copy link
Copy Markdown

@lvarela

lvarela commented Jan 8, 2019

Copy link
Copy Markdown

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

mr-rycho commented Apr 2, 2019

Copy link
Copy Markdown

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

@richardsonlima

Copy link
Copy Markdown

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

@ogronome

Copy link
Copy Markdown

catalinE ?! CATALINUS is much better )

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