Fix remote DevTools restart when a previously added class is then changed

Previously, if a class was added and then changed, a restart would be triggered
and things would behave as if the class had been deleted. This occurred
because, when looking for additional classes that were not on the original
classpath, only files that had been added were considered. The subsequent
change to the class was noticed as a modified rather than an addition,
resulting in the class being skipped.

This commit updates the resource resolver to only ignore deleted files and
consider both added files and modified files when looking for additional
resources.

Closes gh-14205
pull/14582/head
Andy Wilkinson 6 years ago
parent 6910ee6231
commit bff93a67ce

@ -130,7 +130,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) {
String name = entry.getKey();
ClassLoaderFile file = entry.getValue();
if (file.getKind() == Kind.ADDED
if (entry.getValue().getKind() != Kind.DELETED
&& this.antPathMatcher.match(trimmedLocationPattern, name)) {
URL url = new URL("reloaded", null, -1, "/" + name,
new ClassLoaderFileURLStreamHandler(file));

@ -125,6 +125,53 @@ public class DevToolsIntegrationTests {
}
@Test
public void createAControllerAndThenAddARequestMapping() throws Exception {
TestRestTemplate template = new TestRestTemplate();
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(template.getForObject(urlBase + "/one", String.class))
.isEqualTo("one");
assertThat(template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
controller("com.example.ControllerTwo").withRequestMapping("two").build();
assertThat(template.getForObject(urlBase + "/one", String.class))
.isEqualTo("one");
assertThat(template.getForObject("http://localhost:" + awaitServerPort() + "/two",
String.class)).isEqualTo("two");
controller("com.example.ControllerTwo").withRequestMapping("two")
.withRequestMapping("three").build();
assertThat(template.getForObject(
"http://localhost:" + awaitServerPort() + "/three", String.class))
.isEqualTo("three");
}
@Test
public void createAControllerAndThenAddARequestMappingToAnExistingController()
throws Exception {
TestRestTemplate template = new TestRestTemplate();
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(template.getForObject(urlBase + "/one", String.class))
.isEqualTo("one");
assertThat(template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
controller("com.example.ControllerTwo").withRequestMapping("two").build();
assertThat(template.getForObject(urlBase + "/one", String.class))
.isEqualTo("one");
assertThat(template.getForObject("http://localhost:" + awaitServerPort() + "/two",
String.class)).isEqualTo("two");
controller("com.example.ControllerOne").withRequestMapping("one")
.withRequestMapping("three").build();
int port = awaitServerPort();
assertThat(
template.getForObject("http://localhost:" + port + "/one", String.class))
.isEqualTo("one");
assertThat(
template.getForObject("http://localhost:" + port + "/two", String.class))
.isEqualTo("two");
assertThat(template.getForObject("http://localhost:" + port + "/three",
String.class)).isEqualTo("three");
}
@Test
public void deleteAController() throws Exception {
TestRestTemplate template = new TestRestTemplate();
@ -137,6 +184,25 @@ public class DevToolsIntegrationTests {
}
@Test
public void createAControllerAndThenDeleteIt() throws Exception {
TestRestTemplate template = new TestRestTemplate();
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(template.getForObject(urlBase + "/one", String.class))
.isEqualTo("one");
assertThat(template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
controller("com.example.ControllerTwo").withRequestMapping("two").build();
assertThat(template.getForObject(urlBase + "/one", String.class))
.isEqualTo("one");
assertThat(template.getForObject("http://localhost:" + awaitServerPort() + "/two",
String.class)).isEqualTo("two");
assertThat(new File(this.launchedApplication.getClassesDirectory(),
"com/example/ControllerTwo.class").delete()).isTrue();
assertThat(template.getForEntity("http://localhost:" + awaitServerPort() + "/two",
String.class).getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
}
private int awaitServerPort() throws Exception {
long end = System.currentTimeMillis() + 30000;
while (this.serverPortFile.length() == 0) {

Loading…
Cancel
Save