Skip to content

Commit 3e685aa

Browse files
committed
BAEL-2351 programmatically restart spring boot application
1 parent 7ddcb76 commit 3e685aa

File tree

8 files changed

+280
-2
lines changed

8 files changed

+280
-2
lines changed

spring-boot-ops/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@
8686
<version>${jquery.version}</version>
8787
</dependency>
8888

89+
<dependency>
90+
<groupId>org.springframework.cloud</groupId>
91+
<artifactId>spring-cloud-context</artifactId>
92+
<version>${springcloud.version}</version>
93+
</dependency>
94+
8995
</dependencies>
9096

9197
<build>
@@ -153,6 +159,7 @@
153159
<jpa.version>2.2</jpa.version>
154160
<guava.version>18.0</guava.version>
155161
<subethasmtp.version>3.1.7</subethasmtp.version>
162+
<springcloud.version>2.0.2.RELEASE</springcloud.version>
156163
</properties>
157164

158165
</project>

spring-boot-ops/pom.xml~

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<artifactId>spring-boot-ops</artifactId>
7+
<packaging>war</packaging>
8+
<name>spring-boot-ops</name>
9+
<description>Demo project for Spring Boot</description>
10+
11+
<parent>
12+
<artifactId>parent-boot-2</artifactId>
13+
<groupId>com.baeldung</groupId>
14+
<version>0.0.1-SNAPSHOT</version>
15+
<relativePath>../parent-boot-2</relativePath>
16+
</parent>
17+
18+
<dependencies>
19+
20+
<dependency>
21+
<groupId>org.springframework.boot</groupId>
22+
<artifactId>spring-boot-starter-web</artifactId>
23+
</dependency>
24+
25+
<dependency>
26+
<groupId>org.springframework.boot</groupId>
27+
<artifactId>spring-boot-starter-thymeleaf</artifactId>
28+
<scope>provided</scope>
29+
</dependency>
30+
31+
<dependency>
32+
<groupId>org.springframework.boot</groupId>
33+
<artifactId>spring-boot-starter-test</artifactId>
34+
<scope>test</scope>
35+
</dependency>
36+
37+
<dependency>
38+
<groupId>org.springframework.boot</groupId>
39+
<artifactId>spring-boot-starter-data-jpa</artifactId>
40+
</dependency>
41+
42+
<dependency>
43+
<groupId>org.springframework.boot</groupId>
44+
<artifactId>spring-boot-starter-mail</artifactId>
45+
</dependency>
46+
47+
<dependency>
48+
<groupId>org.springframework.boot</groupId>
49+
<artifactId>spring-boot-starter-actuator</artifactId>
50+
</dependency>
51+
52+
<dependency>
53+
<groupId>com.h2database</groupId>
54+
<artifactId>h2</artifactId>
55+
<scope>runtime</scope>
56+
</dependency>
57+
58+
<dependency>
59+
<groupId>javax.persistence</groupId>
60+
<artifactId>javax.persistence-api</artifactId>
61+
<version>${jpa.version}</version>
62+
</dependency>
63+
64+
<dependency>
65+
<groupId>com.google.guava</groupId>
66+
<artifactId>guava</artifactId>
67+
<version>${guava.version}</version>
68+
</dependency>
69+
70+
<dependency>
71+
<groupId>org.subethamail</groupId>
72+
<artifactId>subethasmtp</artifactId>
73+
<version>${subethasmtp.version}</version>
74+
<scope>test</scope>
75+
</dependency>
76+
77+
<dependency>
78+
<groupId>org.webjars</groupId>
79+
<artifactId>bootstrap</artifactId>
80+
<version>${bootstrap.version}</version>
81+
</dependency>
82+
83+
<dependency>
84+
<groupId>org.webjars</groupId>
85+
<artifactId>jquery</artifactId>
86+
<version>${jquery.version}</version>
87+
</dependency>
88+
89+
<dependency>
90+
<groupId>org.springframework.cloud</groupId>
91+
<artifactId>spring-cloud-context</artifactId>
92+
<version>${springcloud.version}</version>
93+
</dependency>
94+
95+
</dependencies>
96+
97+
<build>
98+
<finalName>${project.artifactId}</finalName>
99+
<plugins>
100+
<plugin>
101+
<groupId>org.springframework.boot</groupId>
102+
<artifactId>spring-boot-maven-plugin</artifactId>
103+
<executions>
104+
<execution>
105+
<goals>
106+
<goal>repackage</goal>
107+
</goals>
108+
<configuration>
109+
<mainClass>com.baeldung.webjar.WebjarsdemoApplication</mainClass>
110+
</configuration>
111+
</execution>
112+
</executions>
113+
</plugin>
114+
</plugins>
115+
</build>
116+
117+
<profiles>
118+
<profile>
119+
<id>autoconfiguration</id>
120+
<build>
121+
<plugins>
122+
<plugin>
123+
<groupId>org.apache.maven.plugins</groupId>
124+
<artifactId>maven-surefire-plugin</artifactId>
125+
<executions>
126+
<execution>
127+
<phase>integration-test</phase>
128+
<goals>
129+
<goal>test</goal>
130+
</goals>
131+
<configuration>
132+
<excludes>
133+
<exclude>**/*LiveTest.java</exclude>
134+
<exclude>**/*IntegrationTest.java</exclude>
135+
<exclude>**/*IntTest.java</exclude>
136+
</excludes>
137+
<includes>
138+
<include>**/AutoconfigurationTest.java</include>
139+
</includes>
140+
</configuration>
141+
</execution>
142+
</executions>
143+
<configuration>
144+
<systemPropertyVariables>
145+
<test.mime>json</test.mime>
146+
</systemPropertyVariables>
147+
</configuration>
148+
</plugin>
149+
</plugins>
150+
</build>
151+
</profile>
152+
</profiles>
153+
154+
<properties>
155+
<!-- The main class to start by executing java -jar -->
156+
<start-class>org.baeldung.boot.Application</start-class>
157+
<jquery.version>3.1.1</jquery.version>
158+
<bootstrap.version>3.3.7-1</bootstrap.version>
159+
<jpa.version>2.2</jpa.version>
160+
<guava.version>18.0</guava.version>
161+
<subethasmtp.version>3.1.7</subethasmtp.version>
162+
</properties>
163+
164+
</project>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.baeldung.restart;
2+
3+
import org.springframework.boot.ApplicationArguments;
4+
import org.springframework.boot.SpringApplication;
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
7+
import org.springframework.context.ConfigurableApplicationContext;
8+
9+
@SpringBootApplication
10+
public class Application extends SpringBootServletInitializer {
11+
12+
private static ConfigurableApplicationContext context;
13+
14+
public static void main(String[] args) {
15+
context = SpringApplication.run(Application.class, args);
16+
}
17+
18+
public static void restart() {
19+
ApplicationArguments args = context.getBean(ApplicationArguments.class);
20+
21+
Thread thread = new Thread(() -> {
22+
context.close();
23+
context = SpringApplication.run(Application.class, args.getSourceArgs());
24+
});
25+
26+
thread.setDaemon(false);
27+
thread.start();
28+
}
29+
30+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.baeldung.restart;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.web.bind.annotation.PostMapping;
5+
import org.springframework.web.bind.annotation.RestController;
6+
7+
@RestController
8+
public class RestartController {
9+
10+
@Autowired
11+
private RestartService restartService;
12+
13+
@PostMapping("/restart")
14+
public void restart() {
15+
Application.restart();
16+
}
17+
18+
@PostMapping("/restartApp")
19+
public void restartUsingActuator() {
20+
restartService.restartApp();
21+
}
22+
23+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.baeldung.restart;
2+
3+
import org.springframework.stereotype.Service;
4+
import org.springframework.beans.factory.annotation.Autowired;
5+
import org.springframework.cloud.context.restart.RestartEndpoint;
6+
7+
@Service
8+
public class RestartService {
9+
10+
@Autowired
11+
private RestartEndpoint restartEndpoint;
12+
13+
public void restartApp() {
14+
restartEndpoint.restart();
15+
}
16+
17+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
management.endpoints.web.exposure.include=*
22
management.metrics.enable.root=true
3-
management.metrics.enable.jvm=true
3+
management.metrics.enable.jvm=true
4+
management.endpoint.restart.enabled=true
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.baeldung.restart;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import org.junit.Test;
6+
import org.springframework.boot.test.web.client.TestRestTemplate;
7+
import org.springframework.http.HttpMethod;
8+
import org.springframework.http.ResponseEntity;
9+
10+
public class RestartApplicationIntegrationTest {
11+
12+
private TestRestTemplate template = new TestRestTemplate();
13+
14+
@Test
15+
public void givenBootApp_whenRestart_thenOk() throws Exception {
16+
Application.main(new String[0]);
17+
18+
ResponseEntity response = template.exchange("http://localhost:8080/restart",
19+
HttpMethod.POST, null, Object.class);
20+
21+
assertEquals(200, response.getStatusCode().value());
22+
}
23+
24+
@Test
25+
public void givenBootApp_whenRestartUsingActuator_thenOk() throws Exception {
26+
Application.main(new String[] { "--server.port=8090" });
27+
28+
ResponseEntity response = template.exchange("http://localhost:8090/restartApp",
29+
HttpMethod.POST, null, Object.class);
30+
31+
assertEquals(200, response.getStatusCode().value());
32+
}
33+
34+
}

spring-boot-ops/src/test/resources/application.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ spring.mail.properties.mail.smtp.auth=false
44

55
management.endpoints.web.exposure.include=*
66
management.endpoint.shutdown.enabled=true
7-
endpoints.shutdown.enabled=true
7+
endpoints.shutdown.enabled=true
8+
9+
management.endpoint.restart.enabled=true

0 commit comments

Comments
 (0)