From 1be794fe651b597a8c4187b1d4c5a238e7a3c822 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 14 Feb 2019 14:42:50 +0000 Subject: [PATCH] Retry upload for any SocketException not just a ConnectException Previously, DevTools would retry the upload of the changes to an application in the event of a ConnectException. If a different network-level failure occurred, it would not be retried and would cause the file watching thread to die. This commit attempts to make things more robust by retrying all SocketExceptions and not just ConnectExceptions. A warning is logged when a failure occurs. A separate debug message that includes the exception is also logged. Closes gh-10317 --- .../devtools/remote/client/ClassPathChangeUploader.java | 9 +++++---- .../remote/client/ClassPathChangeUploaderTests.java | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java index 091c0e0221..44f714182b 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,8 @@ package org.springframework.boot.devtools.remote.client; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; -import java.net.ConnectException; import java.net.MalformedURLException; +import java.net.SocketException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; @@ -117,9 +117,10 @@ public class ClassPathChangeUploader logUpload(classLoaderFiles); return; } - catch (ConnectException ex) { - logger.warn("Failed to connect when uploading to " + this.uri + catch (SocketException ex) { + logger.warn("A failure occurred when uploading to " + this.uri + ". Upload will be retried in 2 seconds"); + logger.debug("Upload failure", ex); Thread.sleep(2000); } } diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploaderTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploaderTests.java index 05fed15214..5a637a8ece 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploaderTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploaderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; -import java.net.ConnectException; +import java.net.SocketException; import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashSet; @@ -111,10 +111,10 @@ public class ClassPathChangeUploaderTests { } @Test - public void retriesOnConnectException() throws Exception { + public void retriesOnSocketException() throws Exception { File sourceFolder = this.temp.newFolder(); ClassPathChangedEvent event = createClassPathChangedEvent(sourceFolder); - this.requestFactory.willRespond(new ConnectException()); + this.requestFactory.willRespond(new SocketException()); this.requestFactory.willRespond(HttpStatus.OK); this.uploader.onApplicationEvent(event); assertThat(this.requestFactory.getExecutedRequests()).hasSize(2);