parent
1a84d41f80
commit
2e94fd4434
|
@ -160,7 +160,6 @@
|
||||||
<spring-integration.version>5.0.0.M4</spring-integration.version>
|
<spring-integration.version>5.0.0.M4</spring-integration.version>
|
||||||
<spring-kafka.version>2.0.0.M2</spring-kafka.version>
|
<spring-kafka.version>2.0.0.M2</spring-kafka.version>
|
||||||
<spring-ldap.version>2.3.1.RELEASE</spring-ldap.version>
|
<spring-ldap.version>2.3.1.RELEASE</spring-ldap.version>
|
||||||
<spring-loaded.version>1.2.7.RELEASE</spring-loaded.version>
|
|
||||||
<spring-mobile.version>2.0.0.M1</spring-mobile.version>
|
<spring-mobile.version>2.0.0.M1</spring-mobile.version>
|
||||||
<spring-plugin.version>1.2.0.RELEASE</spring-plugin.version>
|
<spring-plugin.version>1.2.0.RELEASE</spring-plugin.version>
|
||||||
<spring-restdocs.version>1.2.1.RELEASE</spring-restdocs.version>
|
<spring-restdocs.version>1.2.1.RELEASE</spring-restdocs.version>
|
||||||
|
@ -2080,11 +2079,6 @@
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>springloaded</artifactId>
|
|
||||||
<version>${spring-loaded.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.amqp</groupId>
|
<groupId>org.springframework.amqp</groupId>
|
||||||
<artifactId>spring-amqp</artifactId>
|
<artifactId>spring-amqp</artifactId>
|
||||||
|
|
|
@ -2310,9 +2310,8 @@ for other Groovy customization options.
|
||||||
=== Fast application restarts
|
=== Fast application restarts
|
||||||
The `spring-boot-devtools` module includes support for automatic application restarts.
|
The `spring-boot-devtools` module includes support for automatic application restarts.
|
||||||
Whilst not as fast a technologies such as http://zeroturnaround.com/software/jrebel/[JRebel]
|
Whilst not as fast a technologies such as http://zeroturnaround.com/software/jrebel/[JRebel]
|
||||||
or https://github.com/spring-projects/spring-loaded[Spring Loaded] it's usually
|
it's usually significantly faster than a "`cold start`". You should probably give it a try
|
||||||
significantly faster than a "`cold start`". You should probably give it a try before
|
before investigating some of the more complex reload options discussed below.
|
||||||
investigating some of the more complex reload options discussed below.
|
|
||||||
|
|
||||||
For more details see the <<using-spring-boot.adoc#using-boot-devtools>> section.
|
For more details see the <<using-spring-boot.adoc#using-boot-devtools>> section.
|
||||||
|
|
||||||
|
@ -2323,78 +2322,6 @@ Modern IDEs (Eclipse, IDEA, etc.) all support hot swapping of bytecode, so if yo
|
||||||
change that doesn't affect class or method signatures it should reload cleanly with no
|
change that doesn't affect class or method signatures it should reload cleanly with no
|
||||||
side effects.
|
side effects.
|
||||||
|
|
||||||
https://github.com/spring-projects/spring-loaded[Spring Loaded] goes a little further in
|
|
||||||
that it can reload class definitions with changes in the method signatures. With some
|
|
||||||
customization it can force an `ApplicationContext` to refresh itself (but there is no
|
|
||||||
general mechanism to ensure that would be safe for a running application anyway, so it
|
|
||||||
would only ever be a development time trick probably).
|
|
||||||
|
|
||||||
|
|
||||||
[[howto-reload-springloaded-maven]]
|
|
||||||
==== Configuring Spring Loaded for use with Maven
|
|
||||||
To use Spring Loaded with the Maven command line, just add it as a dependency in the
|
|
||||||
Spring Boot plugin declaration, e.g.
|
|
||||||
|
|
||||||
[source,xml,indent=0]
|
|
||||||
----
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>springloaded</artifactId>
|
|
||||||
<version>1.2.6.RELEASE</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</plugin>
|
|
||||||
----
|
|
||||||
|
|
||||||
This normally works pretty well with Eclipse and IntelliJ IDEA as long as they have their
|
|
||||||
build configuration aligned with the Maven defaults (Eclipse m2e does this out of the
|
|
||||||
box).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[howto-reload-springloaded-gradle-and-intellij-idea]]
|
|
||||||
==== Configuring Spring Loaded for use with Gradle and IntelliJ IDEA
|
|
||||||
You need to jump through a few hoops if you want to use Spring Loaded in combination with
|
|
||||||
Gradle and IntelliJ IDEA. By default, IntelliJ IDEA will compile classes into a different
|
|
||||||
location than Gradle, causing Spring Loaded monitoring to fail.
|
|
||||||
|
|
||||||
To configure IntelliJ IDEA correctly you can use the `idea` Gradle plugin:
|
|
||||||
|
|
||||||
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
||||||
----
|
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath 'org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}'
|
|
||||||
classpath 'org.springframework:springloaded:1.2.6.RELEASE'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'idea'
|
|
||||||
|
|
||||||
idea {
|
|
||||||
module {
|
|
||||||
inheritOutputDirs = false
|
|
||||||
outputDir = file("$buildDir/classes/main/")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ...
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
NOTE: IntelliJ IDEA must be configured to use the same Java version as the command line
|
|
||||||
Gradle task and `springloaded` *must* be included as a `buildscript` dependency.
|
|
||||||
|
|
||||||
You can also additionally enable '`Make Project Automatically`' inside IntelliJ IDEA to
|
|
||||||
automatically compile your code whenever a file is saved.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[howto-build]]
|
[[howto-build]]
|
||||||
|
|
|
@ -664,8 +664,7 @@ You might also want to use this useful operating system environment variable:
|
||||||
Since Spring Boot applications are just plain Java applications, JVM hot-swapping should
|
Since Spring Boot applications are just plain Java applications, JVM hot-swapping should
|
||||||
work out of the box. JVM hot swapping is somewhat limited with the bytecode that it can
|
work out of the box. JVM hot swapping is somewhat limited with the bytecode that it can
|
||||||
replace, for a more complete solution
|
replace, for a more complete solution
|
||||||
http://zeroturnaround.com/software/jrebel/[JRebel] or the
|
http://zeroturnaround.com/software/jrebel/[JRebel] can be used. The
|
||||||
https://github.com/spring-projects/spring-loaded[Spring Loaded] project can be used. The
|
|
||||||
`spring-boot-devtools` module also includes support for quick application restarts.
|
`spring-boot-devtools` module also includes support for quick application restarts.
|
||||||
|
|
||||||
See the <<using-boot-devtools>> section below and the
|
See the <<using-boot-devtools>> section below and the
|
||||||
|
@ -791,8 +790,6 @@ If you find that restarts aren't quick enough for your applications, or you enco
|
||||||
classloading issues, you could consider reloading technologies such as
|
classloading issues, you could consider reloading technologies such as
|
||||||
http://zeroturnaround.com/software/jrebel/[JRebel] from ZeroTurnaround. These work by
|
http://zeroturnaround.com/software/jrebel/[JRebel] from ZeroTurnaround. These work by
|
||||||
rewriting classes as they are loaded to make them more amenable to reloading.
|
rewriting classes as they are loaded to make them more amenable to reloading.
|
||||||
https://github.com/spring-projects/spring-loaded[Spring Loaded] provides another option,
|
|
||||||
however it doesn't support as many frameworks and it isn't commercially supported.
|
|
||||||
****
|
****
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
buildscript {
|
buildscript {
|
||||||
ext {
|
ext {
|
||||||
springBootVersion = '2.0.0.BUILD-SNAPSHOT'
|
springBootVersion = '2.0.0.BUILD-SNAPSHOT'
|
||||||
springLoadedVersion = '1.2.4.RELEASE'
|
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
// NOTE: You should declare only repositories that you need here
|
// NOTE: You should declare only repositories that you need here
|
||||||
|
@ -13,7 +12,6 @@ buildscript {
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
|
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
|
||||||
classpath("org.springframework:springloaded:${springLoadedVersion}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +33,5 @@ repositories {
|
||||||
dependencies {
|
dependencies {
|
||||||
compile("org.springframework.boot:spring-boot-starter-web")
|
compile("org.springframework.boot:spring-boot-starter-web")
|
||||||
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
|
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
|
||||||
compile("org.hibernate:hibernate-validator")
|
|
||||||
testCompile("org.springframework.boot:spring-boot-starter-test")
|
testCompile("org.springframework.boot:spring-boot-starter-test")
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,6 @@
|
||||||
<artifactId>zt-zip</artifactId>
|
<artifactId>zt-zip</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>springloaded</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012-2014 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.loader.tools;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class to attach an instrumentation agent to the running JVM.
|
|
||||||
*
|
|
||||||
* @author Dave Syer
|
|
||||||
*/
|
|
||||||
public abstract class AgentAttacher {
|
|
||||||
|
|
||||||
private static final String VIRTUAL_MACHINE_CLASS_NAME = "com.sun.tools.attach.VirtualMachine";
|
|
||||||
|
|
||||||
public static void attach(File agent) {
|
|
||||||
try {
|
|
||||||
String name = ManagementFactory.getRuntimeMXBean().getName();
|
|
||||||
String pid = name.substring(0, name.indexOf('@'));
|
|
||||||
ClassLoader classLoader = JvmUtils.getToolsClassLoader();
|
|
||||||
Class<?> vmClass = classLoader.loadClass(VIRTUAL_MACHINE_CLASS_NAME);
|
|
||||||
Method attachMethod = vmClass.getDeclaredMethod("attach", String.class);
|
|
||||||
Object vm = attachMethod.invoke(null, pid);
|
|
||||||
Method loadAgentMethod = vmClass.getDeclaredMethod("loadAgent", String.class);
|
|
||||||
loadAgentMethod.invoke(vm, agent.getAbsolutePath());
|
|
||||||
vmClass.getDeclaredMethod("detach").invoke(vm);
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
throw new RuntimeException("Unable to attach agent to the JVM", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> commandLineArguments() {
|
|
||||||
return ManagementFactory.getRuntimeMXBean().getInputArguments();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean hasNoVerify() {
|
|
||||||
return commandLineArguments().contains("-Xverify:none");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012-2014 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.loader.tools;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Java Virtual Machine Utils.
|
|
||||||
*
|
|
||||||
* @author Phillip Webb
|
|
||||||
*/
|
|
||||||
abstract class JvmUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Various search locations for tools, including the odd Java 6 OSX jar.
|
|
||||||
*/
|
|
||||||
private static final String[] TOOLS_LOCATIONS = { "lib/tools.jar", "../lib/tools.jar",
|
|
||||||
"../Classes/classes.jar" };
|
|
||||||
|
|
||||||
public static ClassLoader getToolsClassLoader() {
|
|
||||||
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
|
|
||||||
return new URLClassLoader(new URL[] { getToolsJarUrl() }, systemClassLoader);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static URL getToolsJarUrl() {
|
|
||||||
String javaHome = getJavaHome();
|
|
||||||
for (String location : TOOLS_LOCATIONS) {
|
|
||||||
try {
|
|
||||||
URL url = new URL(javaHome + "/" + location);
|
|
||||||
if (new File(url.toURI()).exists()) {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
// Ignore and try the next location
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Unable to locate tools.jar");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getJavaHome() {
|
|
||||||
try {
|
|
||||||
return new File(System.getProperty("java.home")).toURI().toURL()
|
|
||||||
.toExternalForm();
|
|
||||||
}
|
|
||||||
catch (MalformedURLException e) {
|
|
||||||
throw new IllegalStateException("Cannot locate java.home", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012-2016 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.loader.tools;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for {@link JvmUtils}.
|
|
||||||
*
|
|
||||||
* @author Phillip Webb
|
|
||||||
*/
|
|
||||||
public class JvmUtilsTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getToolsJar() throws Exception {
|
|
||||||
URL jarUrl = JvmUtils.getToolsJarUrl();
|
|
||||||
assertThat(jarUrl.toString()).endsWith(".jar");
|
|
||||||
assertThat(new File(jarUrl.toURI()).exists()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -21,7 +21,6 @@ import java.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.security.CodeSource;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -54,8 +53,6 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
|
||||||
|
|
||||||
private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication";
|
private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication";
|
||||||
|
|
||||||
private static final String SPRING_LOADED_AGENT_CLASS_NAME = "org.springsource.loaded.agent.SpringLoadedAgent";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Maven project.
|
* The Maven project.
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
|
@ -87,7 +84,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
@Parameter(property = "run.noverify")
|
@Parameter(property = "run.noverify")
|
||||||
private Boolean noverify;
|
private boolean noverify = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current working directory to use for the application. If not specified, basedir
|
* Current working directory to use for the application. If not specified, basedir
|
||||||
|
@ -211,33 +208,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
|
||||||
return this.workingDirectory != null;
|
return this.workingDirectory != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findAgent() {
|
|
||||||
try {
|
|
||||||
if (this.agent == null || this.agent.length == 0) {
|
|
||||||
Class<?> loaded = Class.forName(SPRING_LOADED_AGENT_CLASS_NAME);
|
|
||||||
if (loaded != null) {
|
|
||||||
if (this.noverify == null) {
|
|
||||||
this.noverify = true;
|
|
||||||
}
|
|
||||||
CodeSource source = loaded.getProtectionDomain().getCodeSource();
|
|
||||||
if (source != null) {
|
|
||||||
this.agent = new File[] {
|
|
||||||
new File(source.getLocation().getFile()) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException ex) {
|
|
||||||
// ignore;
|
|
||||||
}
|
|
||||||
if (this.noverify == null) {
|
|
||||||
this.noverify = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void run(String startClassName)
|
private void run(String startClassName)
|
||||||
throws MojoExecutionException, MojoFailureException {
|
throws MojoExecutionException, MojoFailureException {
|
||||||
findAgent();
|
|
||||||
boolean fork = isFork();
|
boolean fork = isFork();
|
||||||
this.project.getProperties().setProperty("_spring.boot.fork.enabled",
|
this.project.getProperties().setProperty("_spring.boot.fork.enabled",
|
||||||
Boolean.toString(fork));
|
Boolean.toString(fork));
|
||||||
|
|
Loading…
Reference in New Issue