Remove support for Spring Loaded

Closes gh-7978
This commit is contained in:
Stephane Nicoll 2017-05-15 14:18:06 +03:00
parent 1a84d41f80
commit 2e94fd4434
9 changed files with 4 additions and 288 deletions

View File

@ -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>

View File

@ -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]]

View File

@ -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.
****

View File

@ -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")
}

View File

@ -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>

View File

@ -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");
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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));