Update OSX Java 1.6 compatibility fix for plugins

Change the initial fix for OSX Java 1.6 compatibility by removing the
need for a direct `tools.jar` dependency.

It appears that `system` dependencies are always pulled in when
used in a Maven plugin. This makes the the dependency on `tools.jar`
particularly brittle since we need to make assumptions about where
the jar is located.

Since the tools jar is *only* needed for Spring Loaded support, the
plugin has now been updated to locate the jar programmatically and
call it via reflection. This should reduce the risk of problems when
using the plugin and at the very least isolate them to Spring Loaded
support.

(See original commit b8c4720)

Fixes gh-497
This commit is contained in:
Phillip Webb 2014-03-18 12:05:35 -07:00
parent 913b6020d6
commit e23bcdbe29
5 changed files with 117 additions and 68 deletions

View File

@ -11,39 +11,8 @@
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<profiles>
<profile>
<id>standard-jdk</id>
<activation>
<file>
<exists>${java.home}/../lib/tools.jar</exists>
</file>
</activation>
<properties>
<tools-jar>${java.home}/../lib/tools.jar</tools-jar>
</properties>
</profile>
<profile>
<id>apple-jdk</id>
<activation>
<file>
<exists>${java.home}/../Classes/classes.jar</exists>
</file>
</activation>
<properties>
<tools-jar>${java.home}/../Classes/classes.jar</tools-jar>
</properties>
</profile>
</profiles>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>${java.version}</version>
<scope>system</scope>
<systemPath>${tools-jar}</systemPath>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>

View File

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

View File

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

View File

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

View File

@ -12,28 +12,6 @@
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<profiles>
<profile>
<id>standard-jdk</id>
<activation>
<file>
<exists>${java.home}/../lib/tools.jar</exists>
</file>
</activation>
<properties>
<tools-jar>${java.home}/../lib/tools.jar</tools-jar>
</properties>
</profile>
<profile>
<id>apple-jdk</id>
<activation>
<file>
<exists>${java.home}/../Classes/classes.jar</exists>
</file>
</activation>
<properties>
<tools-jar>${java.home}/../Classes/classes.jar</tools-jar>
</properties>
</profile>
<profile>
<id>integration</id>
<activation>
@ -68,13 +46,6 @@
</profiles>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>${java.version}</version>
<scope>system</scope>
<systemPath>${tools-jar}</systemPath>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-loader-tools</artifactId>