With Apache httpd, it is possible to ask it to re-reads its configuration files (kill -USR1) without restarting. A typical scenario is when you are using Let’s Encrypt SSL and you just renewed the SSL certificate, therefore there is a new certificate pem file and you would like httpd to start using it but without causing an outage/restart.
In Tomcat this is desirable but there is no such signal (like USR1) that can be sent to the java process that runs Tomcat that will cause it to re-read its configuration files.
People on the internet have advised to not bother with this but instead run a reverse proxy or a load balancer (e.g. AWS Elastic Load Balancer) in between the users and Tomcat, whereby the SSL certificate will be installed on the reverse proxy/load balancer, and the reverse proxy/load balancer is communicating with Tomcat in plain http. The reverse proxy/load balancer is assumed to be able to re-read its configuration files (i.e. renew its certificate) without a restart/outage.
However, if you do want/need/insist of using just Tomcat, there is a way to achieve this via JMX. A more comprehensive guide on JMX can be found here. Please read that guide first if you are not familiar with JMX.
The method is to find the ProtocolHandler for the https connection in Tomcat in JMX and ask it to reload.
Considering a server.xml file like this
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="TERMINATE">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="universe-server-xml" type="javax.sql.DataSource" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="80" protocol="HTTP/1.1"
maxThreads="200"
connectionTimeout="20000"
redirectPort="443"
compression="on"
compressionMinSize="2048"
compressibleMimeType="text/html,text/xml,text/plain,text/css,application/json,application/javascript" />
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200"
SSLEnabled="true"
relaxedPathChars="^"
compression="on"
compressionMinSize="2048"
compressibleMimeType="text/html,text/xml,text/plain,text/css,application/json,application/javascript">
<SSLHostConfig protocols="TLSv1.2, TLSv1.3">
<Certificate certificateKeyFile="/system/pki/privkey.pem"
certificateFile="/system/pki/cert.pem"
certificateChainFile="/system/pki/chain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
<Engine name="Catalina" defaultHost="default">
<Host name="default" autoDeploy="false" appBase="/system/site/default">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs/default" prefix="access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b %{User-Agent}i" />
</Host>
</Engine>
</Service>
</Server>
What is to note here is the service name defined in server.xml, here it is Catalina.
Create a text file reload-tomcat.txt with this content, change Catalina to your service name in server.xml if it is different.
bean Catalina:port=443,type=ProtocolHandler
run reloadSslHostConfigs
exit
Download the latest jmxterm uber jar from https://github.com/jiaqi/jmxterm. At the time of writing, the latest is version 1.0.4 https://github.com/jiaqi/jmxterm/releases/tag/v1.0.4
Run jmxterm like so, where 192.168.1.127:8880 is where your Tomcat is listening for JMX connection.
java -jar jmxterm-1.0.4-uber.jar -i reload-tomcat.txt -n -l 192.168.1.127:8880
On my system it looks like this
# java -jar jmxterm-1.0.4-uber.jar -i reload-tomcat.txt -n -l 192.168.1.127:8880
Welcome to JMX terminal. Type "help" for available commands.
#bean is set to Catalina:port=443,type=ProtocolHandler
#calling operation reloadSslHostConfigs of mbean Catalina:port=443,type=ProtocolHandler with params []
#operation returns:
null
#bye
Once reloadSslHostConfigs has been executed, Tomcat would have read the new certificate.