To overcome command length limits on Windows, IntelliJ IDEA may launch
an application with a single jar on the classpath that contains that
application's actual classpath in the Class-Path attribute of its
manifest. This would prevent DevTools restarts from working as it
only considered the single jar's URL when identifying changeable URLs
and ignored the URLs added to the classpath via the jar's manifest.
This commit updates ChangeableUrls when it is created from a
URLClassLoader to consider the Class-Path manifest attribute of any
jars in the class loader's URLs. This allows the full classpath to
be considered when identifying URLs that are changeable and that
need to be monitored for restart triggering.
Closes gh-5127
Shutdown handling has been improved so that it will run after any
EntityManagerFactory beans have been closed. This ensures that Hibernate
can, if configured to do so, drop its schema during restart processing.
Without this change, a benign exception could be logged if the database
was shutdown before Hibernate.
Closes gh-5305
Previously, if DataSourceAutoConfiguration had been explicitly excluded,
DevToolsDataSourceAutoConfiguration would cause refresh to fail due to
a missing DataSourceProperties bean. This commit corrects the condition
so that the auto-configuration is conditional on a DataSource bean and
a DataSourceProperties bean rather than only being conditional on one or
the other.
Closes gh-5269
Previously, if an application had been started without remote
debugging enabled, an attempt to connect to it via
RemoteSpringApplication and the HTTP tunnel would result in the
application being hammered by connection attempts for 30 seconds.
This commit updates the tunnel server to respond with Service
Unavailable (503) when a connection attempt is made and the JVM
does not have remote debugging enabled. When the client receives a
503 response, it now logs a warning message describing the possible
problem before closing the connection.
The client has also been updated to provide improved diagnostics when
a connection to the tunnel server cannot be established, for example
because the remote URL is incorrect, or the remote application isn't
running.
Lastly, the client has been updated so that it continues to accept
connections when a connection to the server is closed. This allows
the user to correct a problem with the remote application, such as
restarting it with remote debugging enabled, without having to also
restart the process that's running RemoteSpringApplication.
Closes gh-5021
Previously an in-memory database that wasn’t pooled (an
EmbeddedDatabase) would be shutdown when the context restarted, but
an in-memory database wrapped in a connection pool was not. This meant
that the former would be be wiped clean after each restart, whereas the
latter would not. In addition to being inconsistent, this also
caused problems with schema.sql and data.sql scripts when using
DevTools. If you were using an in-memory database wrapped in a
connection pool, a failure may occur during a restart as the scripts
were not being run against in clean database.
This commit adds an auto-configured bean to DevTools that, when the
context is being closed, will execute “SHUTDOWN” if it identifies that
the DataSource is not an EmbeddedDatabase and is for an in-memory
database.
Closes gh-4699
Previously, when Spring Session 1.1.0.M1 and DevTools were declared as
dependencies the application failed to start, because
sessionRedisTemplate could not be resolved.
This commit relaxes the dependency for sessionRedisTemplate in
restartCompatibleRedisSerializerConfigurer from
RedisTemplate<String, ExpiringSession> to RedisTemplate<?, ?> and uses
the bean name in a @Qualifer to ensure that the right RedisTemplate
bean gets injected.
Fixes gh-4895
Closes gh-4896
In Spring Boot 1.3.1 the class 'org.apache.logging.log4j.LogManager'
is used to check which logging backend is in use. But this class is
part of the log4j-api.jar and not part of the log4j-core.jar.
That means the check is invalid, as it does not detect the actual
core implementation of Log4j2 correctly.
When you want to redirect Log4j2 logging via SLF4J, a NPE occurs
each time the application is reloaded by the devtools, because the
class Log4j2RestartListener tries to shutdown Log4j2 resources.
This is done by accessing some internal shutdown method via
reflection. The method that is being looked for does not exist
when the log4j-api.jar is available only on the classpath,
resulting in a NPE. This causes the application to stop,
disappearing from the Spring Boot Dashboard in Eclipse
Closes gh-4831
Previously, ServerThread would check for a disconnect as soon as it
had been started. This raced with it handling its first connection. If
the check for disconnect won the race it would incorrectly determine
that the disconnect timeout had been reached and wouldn’t respond to
the connection.
This commit updates ServerThread so that it only checks the disconnect
timeout once it’s handled at least one connection.
Closes gh-4668
Previously, when a session attribute that had been stored in Redis was
being deserialized, the app class loader would be used. This would
result in a ClassCastException if the attribute was an instance of a
class visible to the restart class loader.
This commit auto-configures Spring Session’s RedisTemplate to use a
custom deserializer that uses the restart class loader when
deserializing session attributes.
Closes gh-3805
Previously, ServerThread.lastHttpRequestTime was written while
synchronized on this.httpConnections but was read without
synchronization. This could lead to a read of the field producing the
wrong value and cause premature connection timeout.
This commit moves the call to checkNotDisconnected into a block that
sychronizes on this.httpConnections, thereby ensuring that
lastHttpRequestTime can be read safely.
Closes gh-4668
Allow `META-INF/spring-devtools.properties` files to be used by
application developers to declare is specific jars should be included
or excluded from the RestartClassLoader.
A typical example where this might be used is a company that develops
it's own set of internal JARs that are used by developers but not
usually imported into their IDE.
See gh-3316
Update SpringApplication so that startup exceptions are only logged
once. A custom UncaughtExceptionHandler is now used when running in
the main thread to suppress errors that have already been logged.
Fixes gh-4423
During a restart, the Restarter runs all registered shutdown hooks. This
breaks Log4J2 as it leaves it in a shutdown state that leaves logging
switched off such that no output it produced when the application starts
up again.
This commit introduces a new RestartListener abstraction.
RestartListeners are notified prior to the application being restarted.
A Log4J2-specific implementation is provided that prepares Log4J2 for
restart by removing any shutdown callbacks from its shutdown callback
registry. This prevents the restart from shutting down Log4J2, ensuring
that it still functions when the application restarts.
Closes gh-4279
Previously, ConfigFileApplicationListener was listed in spring.factories
as both an EnvironmentPostProcessor and an ApplicationListener. This
was problematic as ConfigFileApplicationListener is stateful and listing
it twice lead to two separate instances with separate state.
This commit restore ConfigFileApplicationListener to only being an
ApplicationListener. The driving of EnvironmentPostProcessors that was
performed by EnvironmentPostProcessingApplicationListener is now
performed by ConfigFileApplicationListener which adds itself as an
EnvironmentPostProcessor. This ensures that there’s only a single
instance of ConfigFileApplicationListener, allowing its state to be
managed correctly.
Closes gh-4258
Previously, the auto-configuration of DevTools’ debug, restart, and
health handlers assumed that the server was running on its default
context path and, if server.context-path was set to a non-default value,
the handlers would not work as expected.
This commit updates the auto-configuration of the three handlers to
consider the server’s context path when configuring their URIs. Now,
when a custom server context path is used, no further configuration is
required other than the inclusion of that context path when providing
the remote URL as an argument to RemoteSpringApplication.
Closes gh-4301
Replace the custom Base64Encoder class with Spring's Base64Utils which
since 4.2 can encode bytes using Java 8's encoder, commons-digest or
Java 6's JAX-B encoder.
Closes gh-4189
Spring HATEOAS’s DummyInvocationUtils, that is used by
ControllerLinkBuilder, uses Objenesis. By default, Objenesis caches
the instances that it creates and uses the class name as the cache key.
This is problematic when DevTools’ restart support is enabled as the
class loader changes with each restart and ClassCastExceptions occur
due to Objenesis returning a cached instance that was created by an
old restart class loader.
This commit works around the problem described above by auto-configuring
a bean that uses reflection to replace DummyInvocationUtils’ default
Objenesis instance with one that has caching disabled.
Closes gh-3784