I'm trying to setup remote spring-boot environment using spring devtools, docker and IntelliJ. All started with this article. Unfortunately it randomly fails with an exception. Below the configuration:
Dockerfile
FROM java:8
EXPOSE 8888
WORKDIR /app
ADD build.gradle /app/build.gradle
ADD gradlew /app/gradlew
ADD gradle /app/gradle
ADD src /app/src
RUN ["chmod", "+x", "/app/gradlew"]
docker-compose.yml
backend:
build: .
env_file: environment
ports:
- "8888:8888"
volumes:
- ./.gradle-docker:/root/.gradle
command: "/app/gradlew clean bootRun"
links:
- db
db:
image: postgres:9.5.3
env_file: environment
ports:
- "5454:5432"
The whole application is started from command line with: docker-compose build
and docker-compose up
commands.
In IntelliJ I've prepared the following java application configuration:
where docker:8888
is the IP of the docker-machine and port that is used by spring application. After the configuration is run is the following output:
/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: (v1.3.5.RELEASE)
2016-07-06 12:48:51.997 INFO 17731 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication v1.3.5.RELEASE on opal-mac.local with PID 17731 (/Users/opal/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-devtools/1.3.5.RELEASE/ab035bdc1e6297ff4c8676edd93ed307b11353c2/spring-boot-devtools-1.3.5.RELEASE.jar started by opal in /Users/opal/projects/backend)
2016-07-06 12:48:52.013 INFO 17731 --- [ main] o.s.b.devtools.RemoteSpringApplication : No active profile set, falling back to default profiles: default
2016-07-06 12:48:52.106 INFO 17731 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@441772e: startup date [Wed Jul 06 12:48:52 CEST 2016]; root of context hierarchy
2016-07-06 12:48:54.016 WARN 17731 --- [ main] o.s.b.d.r.c.RemoteClientConfiguration : The connection to http://docker:8888 is insecure. You should use a URL starting with 'https://'.
2016-07-06 12:48:54.419 WARN 17731 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : Unable to start LiveReload server
2016-07-06 12:48:54.499 INFO 17731 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 3.793 seconds (JVM running for 5.004)
Unfortunately after some change is made to the code, the following exception occurs:
2016-07-06 12:49:29.141 INFO 17731 --- [ File Watcher] o.s.b.d.r.c.ClassPathChangeUploader : Uploaded 1 class resource
2016-07-06 12:49:31.056 INFO 17731 --- [ File Watcher] o.s.b.d.r.c.ClassPathChangeUploader : Uploaded 1 class resource
Exception in thread "File Watcher" java.lang.IllegalStateException: java.net.ConnectException: Connection refused
at org.springframework.boot.devtools.remote.client.ClassPathChangeUploader.onApplicationEvent(ClassPathChangeUploader.java:107)
at org.springframework.boot.devtools.remote.client.ClassPathChangeUploader.onApplicationEvent(ClassPathChangeUploader.java:56)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:166)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:381)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:335)
at org.springframework.boot.devtools.classpath.ClassPathFileChangeListener.publishEvent(ClassPathFileChangeListener.java:68)
at org.springframework.boot.devtools.classpath.ClassPathFileChangeListener.onChange(ClassPathFileChangeListener.java:64)
at org.springframework.boot.devtools.filewatch.FileSystemWatcher.fireListeners(FileSystemWatcher.java:230)
at org.springframework.boot.devtools.filewatch.FileSystemWatcher.updateSnapshots(FileSystemWatcher.java:223)
at org.springframework.boot.devtools.filewatch.FileSystemWatcher.scan(FileSystemWatcher.java:183)
at org.springframework.boot.devtools.filewatch.FileSystemWatcher.access$100(FileSystemWatcher.java:41)
at org.springframework.boot.devtools.filewatch.FileSystemWatcher$1.run(FileSystemWatcher.java:150)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at sun.net.NetworkClient.doConnect(NetworkClient.java:180)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:432)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:527)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:211)
at sun.net.www.http.HttpClient.New(HttpClient.java:308)
at sun.net.www.http.HttpClient.New(HttpClient.java:326)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1169)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1105)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:999)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:933)
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:80)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:93)
at org.springframework.boot.devtools.remote.client.HttpHeaderInterceptor.intercept(HttpHeaderInterceptor.java:57)
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:85)
at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:69)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.boot.devtools.remote.client.ClassPathChangeUploader.onApplicationEvent(ClassPathChangeUploader.java:102)
... 12 more
In docker and IntelliJ:
2016-07-06 12:49:29.141 INFO 17731 --- [ File Watcher] o.s.b.d.r.c.ClassPathChangeUploader : Uploaded 1 class resource
logs I see that the context is reloaded. What may be the problem?
There's a bug in Spring boot's DevTools which means that if you make a change to your application while the restart that was triggered by the previous change is still in progress, the attempt to upload the changes will fail. I think we probably need to update DevTools to retry the upload attempt.
In the meantime, the only "solution" is to stop and restart your
RemoteSpringApplication
whenever you see the failure due tojava.net.ConnectException: Connection refused
.