Commit db0212b8 authored by Phillip Webb's avatar Phillip Webb

Allow spring-boot-devtools to work with JRebel

Update devtools to detect JRebel and disable application restarts. Other
features (such as LiveReload) can still be used.

Fixes gh-3095
parent acde5407
......@@ -105,7 +105,7 @@ public class LocalDevToolsAutoConfiguration {
public void onClassPathChanged(ClassPathChangedEvent event) {
if (event.isRestartRequired()) {
Restarter.getInstance().restart(
new FileWatchingFailureHandler(getFileSystemWatcherFactory()));
new FileWatchingFailureHandler(fileSystemWatcherFactory()));
}
}
......@@ -114,7 +114,7 @@ public class LocalDevToolsAutoConfiguration {
public ClassPathFileSystemWatcher classPathFileSystemWatcher() {
URL[] urls = Restarter.getInstance().getInitialUrls();
ClassPathFileSystemWatcher watcher = new ClassPathFileSystemWatcher(
getFileSystemWatcherFactory(), classPathRestartStrategy(), urls);
fileSystemWatcherFactory(), classPathRestartStrategy(), urls);
watcher.setStopWatcherOnRestart(true);
return watcher;
}
......@@ -127,7 +127,7 @@ public class LocalDevToolsAutoConfiguration {
}
@Bean
public FileSystemWatcherFactory getFileSystemWatcherFactory() {
public FileSystemWatcherFactory fileSystemWatcherFactory() {
return new FileSystemWatcherFactory() {
@Override
......
......@@ -22,6 +22,7 @@ import org.springframework.boot.devtools.filewatch.ChangedFile;
import org.springframework.boot.devtools.filewatch.ChangedFiles;
import org.springframework.boot.devtools.filewatch.FileChangeListener;
import org.springframework.boot.devtools.filewatch.FileSystemWatcher;
import org.springframework.boot.devtools.restart.AgentReloader;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.util.Assert;
......@@ -71,6 +72,9 @@ class ClassPathFileChangeListener implements FileChangeListener {
}
private boolean isRestartRequired(Set<ChangedFiles> changeSet) {
if (AgentReloader.isActive()) {
return false;
}
for (ChangedFiles changedFiles : changeSet) {
for (ChangedFile changedFile : changedFiles) {
if (this.restartStrategy.isRestartRequired(changedFile)) {
......
/*
* Copyright 2012-2015 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.devtools.restart;
import org.springframework.util.ClassUtils;
/**
* Utility to determine if an Java agent based reloader (e.g. JRebel) is being used.
*
* @author Phillip Webb
* @since 1.3.0
*/
public abstract class AgentReloader {
private AgentReloader() {
}
/**
* Determine if any agent reloader is active.
* @return true if agent reloading is active
*/
public static boolean isActive() {
return isJRebelActive();
}
/**
* Determine if JRebel is active.
* @return true if JRebel is active
*/
public static boolean isJRebelActive() {
return ClassUtils.isPresent("org.zeroturnaround.javarebel.ReloaderFactory", null);
}
}
......@@ -53,7 +53,10 @@ public class RestartApplicationListener implements ApplicationListener<Applicati
// users to disable restart using a System property.
String enabled = System.getProperty(ENABLED_PROPERTY);
if (enabled == null || Boolean.parseBoolean(enabled)) {
Restarter.initialize(event.getArgs());
String[] args = event.getArgs();
DefaultRestartInitializer initializer = new DefaultRestartInitializer();
boolean restartOnInitialize = !AgentReloader.isActive();
Restarter.initialize(args, false, initializer, restartOnInitialize);
}
else {
Restarter.disable();
......
......@@ -872,12 +872,16 @@ a very fast feedback loop for code changes. By default, any entry on the classpa
points to a folder will be monitored for changes.
NOTE: You can also start your application via the supported build plugins (i.e. Maven and
Gradle) as long as forking is enabled since DevTools need an isolated application classloader
to operate properly.
Gradle) as long as forking is enabled since DevTools need an isolated application
classloader to operate properly.
TIP: Automatic restart works very well when used with LiveReload.
<<using-boot-devtools-livereload,See below>> for details.
NOTE: If you use JRebel automatic restarts will be disabled in favor of dynamic class
reloading. Other devtools features (such as LiveReload and property overrides) can still
be used.
.Restart vs Reload
****
The restart technology provided by Spring Boot works by using two classloaders.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment