mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Remove support for Spring Loaded
Closes gh-7978
This commit is contained in:
parent
1a84d41f80
commit
2e94fd4434
@ -160,7 +160,6 @@
|
||||
<spring-integration.version>5.0.0.M4</spring-integration.version>
|
||||
<spring-kafka.version>2.0.0.M2</spring-kafka.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-plugin.version>1.2.0.RELEASE</spring-plugin.version>
|
||||
<spring-restdocs.version>1.2.1.RELEASE</spring-restdocs.version>
|
||||
@ -2080,11 +2079,6 @@
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>springloaded</artifactId>
|
||||
<version>${spring-loaded.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.amqp</groupId>
|
||||
<artifactId>spring-amqp</artifactId>
|
||||
|
@ -2310,9 +2310,8 @@ for other Groovy customization options.
|
||||
=== Fast 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]
|
||||
or https://github.com/spring-projects/spring-loaded[Spring Loaded] it's usually
|
||||
significantly faster than a "`cold start`". You should probably give it a try before
|
||||
investigating some of the more complex reload options discussed below.
|
||||
it's usually significantly faster than a "`cold start`". You should probably give it a try
|
||||
before investigating some of the more complex reload options discussed below.
|
||||
|
||||
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
|
||||
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]]
|
||||
|
@ -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
|
||||
work out of the box. JVM hot swapping is somewhat limited with the bytecode that it can
|
||||
replace, for a more complete solution
|
||||
http://zeroturnaround.com/software/jrebel/[JRebel] or the
|
||||
https://github.com/spring-projects/spring-loaded[Spring Loaded] project can be used. The
|
||||
http://zeroturnaround.com/software/jrebel/[JRebel] can be used. The
|
||||
`spring-boot-devtools` module also includes support for quick application restarts.
|
||||
|
||||
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
|
||||
http://zeroturnaround.com/software/jrebel/[JRebel] from ZeroTurnaround. These work by
|
||||
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 {
|
||||
ext {
|
||||
springBootVersion = '2.0.0.BUILD-SNAPSHOT'
|
||||
springLoadedVersion = '1.2.4.RELEASE'
|
||||
}
|
||||
repositories {
|
||||
// NOTE: You should declare only repositories that you need here
|
||||
@ -13,7 +12,6 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
|
||||
classpath("org.springframework:springloaded:${springLoadedVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,6 +33,5 @@ repositories {
|
||||
dependencies {
|
||||
compile("org.springframework.boot:spring-boot-starter-web")
|
||||
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
|
||||
compile("org.hibernate:hibernate-validator")
|
||||
testCompile("org.springframework.boot:spring-boot-starter-test")
|
||||
}
|
||||
|
@ -40,11 +40,6 @@
|
||||
<artifactId>zt-zip</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>springloaded</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<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.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.CodeSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
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_LOADED_AGENT_CLASS_NAME = "org.springsource.loaded.agent.SpringLoadedAgent";
|
||||
|
||||
/**
|
||||
* The Maven project.
|
||||
* @since 1.0
|
||||
@ -87,7 +84,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
|
||||
* @since 1.0
|
||||
*/
|
||||
@Parameter(property = "run.noverify")
|
||||
private Boolean noverify;
|
||||
private boolean noverify = false;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
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)
|
||||
throws MojoExecutionException, MojoFailureException {
|
||||
findAgent();
|
||||
boolean fork = isFork();
|
||||
this.project.getProperties().setProperty("_spring.boot.fork.enabled",
|
||||
Boolean.toString(fork));
|
||||
|
Loading…
Reference in New Issue
Block a user