org.jolokia.jvmagent.client.util.ToolsClassFinder Maven / Gradle / Ivy
package org.jolokia.jvmagent.client.util;
/*
* Copyright 2009-2013 Roland Huss
*
* 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.
*/
import java.io.File;
import java.net.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* Utility class for looking up a class within tools.jar
*
* @author roland
* @since 07.10.11
*/
public final class ToolsClassFinder {
private ToolsClassFinder() {}
private static final String JAVA_HOME = System.getProperty("java.home");
// Location to look for tools.jar
private static final File[] TOOLS_JAR_LOCATIONS = new File[] {
new File(JAVA_HOME + "/../lib/tools.jar"),
new File(JAVA_HOME + "/lib/tools.jar")
};
/**
* Lookup a class and return its definition. This is first tried by the current classloader (which
* has loaded this class) and if this fails by searching for a tools.jar in various places.
*
* @param pClassName class name to lookup
* @return the found class
* @throws ClassNotFoundException if no class could be found
*/
public static Class lookupClass(String pClassName) throws ClassNotFoundException {
try {
return Class.forName(pClassName);
} catch (ClassNotFoundException exp) {
return lookupInToolsJar(pClassName);
}
}
/**
* Searches for tools.jar
in various locations and uses an {@link URLClassLoader} for
* loading a class from this files. If the class could not be found in any, then a {@link ClassNotFoundException}
* is thrown. The locations used for lookup are (in this order)
*
*
* - $JAVA_HOME/../lib/tools.jar
* - $JAVA_HOME/lib/tools.jar
*
*
* $JAVA_HOME
here is the value of the system property java.home
*
* @param pClassName class to lookup
* @return the found class
* @throws ClassNotFoundException if no class could be found
*/
public static Class lookupInToolsJar(String pClassName) throws ClassNotFoundException {
// Try to look up tools.jar within $java.home, otherwise give up
String extraInfo;
if (JAVA_HOME != null) {
extraInfo = "JAVA_HOME is " + JAVA_HOME;
for (File toolsJar : TOOLS_JAR_LOCATIONS) {
try {
if (toolsJar.exists()) {
ClassLoader loader = createClassLoader(toolsJar);
return loader.loadClass(pClassName);
}
} catch (MalformedURLException e) {
// Cannot happen because the URL comes from a File.
// And if, we throws an class not found exception.
extraInfo = "Cannot create URL from " + toolsJar;
}
}
} else {
extraInfo = "No JAVA_HOME set";
}
throw new ClassNotFoundException("No tools.jar found (" + extraInfo + ")");
}
// Create a classloader and respect a security manager if installed
private static ClassLoader createClassLoader(File toolsJar) throws MalformedURLException {
final URL urls[] = new URL[] {toolsJar.toURI().toURL() };
if (System.getSecurityManager() == null) {
return new URLClassLoader(urls, getParentClassLoader());
} else {
return AccessController.doPrivileged(new PrivilegedAction() {
/** {@inheritDoc} */
public ClassLoader run() {
return new URLClassLoader(urls, getParentClassLoader());
}
});
}
}
private static ClassLoader getParentClassLoader() {
ClassLoader loader = ToolsClassFinder.class.getClassLoader();
return loader == null ? ClassLoader.getSystemClassLoader() : loader;
}
}