I am trying to programmatically restart my Spring Application without having the user to intervene.
Basically, I have a page which allows to switch the mode of the application (actually meaning switching the currently active profile) and as far as I understand I must restart the context.
Currently my code is very simple, it's just for the restarting bit (this is Kotlin by the way):
context.close()
application.setEnvironment(context.environment)
ClassUtils.overrideThreadContextClassLoader(application.javaClass.classLoader)
context = application.run(*argsArray)
However the moment I do context.close()
the JVM exists immediately. I have also tried context.refresh()
but that seems to simply kill Tomcat/Jetty (tried both just in case it was a Tomcat problem) and then nothing happens.
I have also seen Programmatically restart Spring Boot application but nothing seems to work for me from those answers. Furthermore, I looked into Spring Actuator which supposedly has the /restart
endpoint, but that doesn't seem to be there anymore?
You can use the
RestartEndPoint
(inspring-cloud-context
dependency) to restart the Spring Boot application programmatically:It works, even though it will throw an exception to inform you that this may lead to memory leaks:
The same answer was provided for this other question (worded differently): Call Spring actuator /restart endpoint from Spring boot using a java function
I've solved this issue by using Restarter from Spring Devtools. Add this to pom.xml:
Then use org.springframework.boot.devtools.restart.Restarter to call this:
It works for me. Hope this help.
Below restart method will work.
`@SpringBootApplication public class Application {
}`
Even though Alex's solution works, I don't believe in including 2 additional dependencies (
Actuator
andCloud Context
) just to be able to do one operation. Instead, I have combined his answer and modified my code in order to do what I wanted.So, first of all, it is crucial that the code is executed using
new Thread()
andsetDaemon(false);
. I have the following endpoint method that handles the restart:The
Thread.sleep(1000)
is not required, but I want my controller to output the view before actually restarting the application.SpringMain.restartToMode
has the following:Where
context
andapplication
come from themain
method upon starting the application:I am not entirely sure if this produces any problems. If there will be, I will update this answer. Hopefully this will be of any help to others.
In case it might help someone, here's a pura Java translation of Crembo's accepted answer.
Controller method:
Main class (significant bits only):