diff --git a/spring-boot-tools/spring-boot-loader-tools/pom.xml b/spring-boot-tools/spring-boot-loader-tools/pom.xml index 40f93dd0b70..2045dfbc2d2 100644 --- a/spring-boot-tools/spring-boot-loader-tools/pom.xml +++ b/spring-boot-tools/spring-boot-loader-tools/pom.xml @@ -11,39 +11,8 @@ ${basedir}/../.. - - - standard-jdk - - - ${java.home}/../lib/tools.jar - - - - ${java.home}/../lib/tools.jar - - - - apple-jdk - - - ${java.home}/../Classes/classes.jar - - - - ${java.home}/../Classes/classes.jar - - - - - com.sun - tools - ${java.version} - system - ${tools-jar} - org.springframework spring-core diff --git a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AgentAttacher.java b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AgentAttacher.java index b6fe50e8a60..ea66a001853 100644 --- a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AgentAttacher.java +++ b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AgentAttacher.java @@ -18,10 +18,9 @@ package org.springframework.boot.loader.tools; import java.io.File; import java.lang.management.ManagementFactory; +import java.lang.reflect.Method; import java.util.List; -import com.sun.tools.attach.VirtualMachine; - /** * Utility class to attach an instrumentation agent to the running JVM. * @@ -29,16 +28,22 @@ import com.sun.tools.attach.VirtualMachine; */ public abstract class AgentAttacher { + private static final String VIRTUAL_MACHINE_CLASSNAME = "com.sun.tools.attach.VirtualMachine"; + public static void attach(File agent) { - String name = ManagementFactory.getRuntimeMXBean().getName(); - String pid = name.substring(0, name.indexOf('@')); try { - VirtualMachine vm = VirtualMachine.attach(pid); - vm.loadAgent(agent.getAbsolutePath()); - vm.detach(); + String name = ManagementFactory.getRuntimeMXBean().getName(); + String pid = name.substring(0, name.indexOf('@')); + ClassLoader classLoader = JvmUtils.getToolsClassLoader(); + Class vmClass = classLoader.loadClass(VIRTUAL_MACHINE_CLASSNAME); + 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(ex); + throw new RuntimeException("Unable to attach Spring Loaded to the JVM", ex); } } diff --git a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/JvmUtils.java b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/JvmUtils.java new file mode 100644 index 00000000000..e96a01baf8d --- /dev/null +++ b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/JvmUtils.java @@ -0,0 +1,61 @@ +/* + * 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.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("file://" + 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() { + return System.getProperty("java.home"); + } + +} diff --git a/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/JvmUtilsTests.java b/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/JvmUtilsTests.java new file mode 100644 index 00000000000..690a70e4afb --- /dev/null +++ b/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/JvmUtilsTests.java @@ -0,0 +1,43 @@ +/* + * 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.URL; + +import org.junit.Test; + +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +/** + * Tests for {@link JvmUtils}. + * + * @author Phillip Webb + */ +public class JvmUtilsTests { + + @Test + public void getToolsJar() throws Exception { + URL jarUrl = JvmUtils.getToolsJarUrl(); + System.out.println(jarUrl); + assertThat(jarUrl.toString(), endsWith(".jar")); + assertThat(new File(jarUrl.toURI()).exists(), equalTo(true)); + } + +} diff --git a/spring-boot-tools/spring-boot-maven-plugin/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/pom.xml index 2796c6af5fb..a8ec9898268 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/pom.xml +++ b/spring-boot-tools/spring-boot-maven-plugin/pom.xml @@ -12,28 +12,6 @@ ${basedir}/../.. - - standard-jdk - - - ${java.home}/../lib/tools.jar - - - - ${java.home}/../lib/tools.jar - - - - apple-jdk - - - ${java.home}/../Classes/classes.jar - - - - ${java.home}/../Classes/classes.jar - - integration @@ -68,13 +46,6 @@ - - com.sun - tools - ${java.version} - system - ${tools-jar} - ${project.groupId} spring-boot-loader-tools