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 091c0e022135..44f714182bb0 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 @@ 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 @@ private void performUpload(ClassLoaderFiles classLoaderFiles, byte[] bytes) 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 05fed152147c..5a637a8ecebb 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.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 void sendsClassLoaderFiles() throws Exception { } @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);