package jetbrains.mps.core.tool.environment.classloading;
/*Generated by MPS */
import org.jetbrains.annotations.NonNls;
import java.lang.reflect.Field;
import java.util.HashMap;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import java.util.List;
import java.net.URL;
import jetbrains.mps.core.tool.environment.util.PathManager;
import java.net.MalformedURLException;
import java.util.regex.Pattern;
import java.util.Iterator;
import java.net.URLClassLoader;
import java.util.StringTokenizer;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import jetbrains.mps.core.tool.environment.common.StringUtil;
public class ClassloaderUtil {
@NonNls
/*package*/ static final String FILE_CACHE = "fileCache";
@NonNls
/*package*/ static final String URL_CACHE = "urlCache";
@NonNls
public static final String PROPERTY_IGNORE_CLASSPATH = "ignore.classpath";
@SuppressWarnings(value = {"HardCodedStringLiteral"})
private static final String ERROR = "Error";
private static Class[] EMPTY_CLASS_ARRAY = new Class[0];
private ClassloaderUtil() {
}
public static void clearJarURLCache() {
try {
// new URLConnection(null) {
// public void connect() throws IOException {
// throw new UnsupportedOperationException();
// }
// }.setDefaultUseCaches(false);
Class jarFileFactory = Class.forName("sun.net.www.protocol.jar.JarFileFactory");
Field fileCache = jarFileFactory.getDeclaredField(ClassloaderUtil.FILE_CACHE);
Field urlCache = jarFileFactory.getDeclaredField(ClassloaderUtil.URL_CACHE);
fileCache.setAccessible(true);
fileCache.set(null, new HashMap());
urlCache.setAccessible(true);
urlCache.set(null, new HashMap());
} catch (Exception e) {
System.err.println("Failed to clear URL cache");
// Do nothing.
}
}
public static Logger getLogger() {
return LogManager.getLogger("ClassloaderUtil");
}
public static UrlClassLoader initClassloader(final List<URL> classpathElements) {
PathManager.loadProperties();
try {
ClassloaderUtil.addParentClasspath(classpathElements);
ClassloaderUtil.addIDEALibraries(classpathElements);
ClassloaderUtil.addAdditionalClassPath(classpathElements);
} catch (IllegalArgumentException e) {
ClassloaderUtil.getLogger().error(null, e);
System.exit(1);
} catch (MalformedURLException e) {
ClassloaderUtil.getLogger().error(e.getMessage());
System.exit(1);
}
ClassloaderUtil.filterClassPath(classpathElements);
UrlClassLoader newClassLoader = null;
try {
newClassLoader = new UrlClassLoader(classpathElements, null, true, true);
// prepare plugins
Thread.currentThread().setContextClassLoader(newClassLoader);
} catch (Exception e) {
Logger logger = ClassloaderUtil.getLogger();
if (logger == null) {
e.printStackTrace(System.err);
} else {
logger.error(null, e);
}
}
return newClassLoader;
}
public static void filterClassPath(final List<URL> classpathElements) {
final String ignoreProperty = System.getProperty(ClassloaderUtil.PROPERTY_IGNORE_CLASSPATH);
if (ignoreProperty == null) {
return;
}
final Pattern pattern = Pattern.compile(ignoreProperty);
for (Iterator<URL> i = classpathElements.iterator(); i.hasNext();) {
URL url = i.next();
final String u = url.toExternalForm();
if (pattern.matcher(u).matches()) {
i.remove();
}
}
}
public static void addParentClasspath(List<URL> aClasspathElements) throws MalformedURLException {
final ClassLoader loader = ClassloaderUtil.class.getClassLoader();
if (loader instanceof URLClassLoader) {
URLClassLoader urlClassLoader = (URLClassLoader) loader;
ContainerUtil.addAll(aClasspathElements, urlClassLoader.getURLs());
} else {
try {
Class antClassLoaderClass = Class.forName("org.apache.tools.ant.AntClassLoader");
if (antClassLoaderClass.isInstance(loader) || loader.getClass().getName().equals("org.apache.tools.ant.AntClassLoader") || loader.getClass().getName().equals("org.apache.tools.ant.loader.AntClassLoader2")) {
// noinspection HardCodedStringLiteral
final String classpath = (String) antClassLoaderClass.getDeclaredMethod("getClasspath", ClassloaderUtil.EMPTY_CLASS_ARRAY).invoke(loader, ClassloaderUtil.EMPTY_CLASS_ARRAY);
final StringTokenizer tokenizer = new StringTokenizer(classpath, File.separator, false);
while (tokenizer.hasMoreTokens()) {
final String token = tokenizer.nextToken();
aClasspathElements.add(new File(token).toURI().toURL());
}
} else {
ClassloaderUtil.getLogger().warn("Unknown classloader: " + loader.getClass().getName());
}
} catch (ClassCastException e) {
ClassloaderUtil.getLogger().warn("Unknown classloader [CCE]: " + e.getMessage());
} catch (ClassNotFoundException e) {
ClassloaderUtil.getLogger().warn("Unknown classloader [CNFE]: " + loader.getClass().getName());
} catch (NoSuchMethodException e) {
ClassloaderUtil.getLogger().warn("Unknown classloader [NSME]: " + e.getMessage());
} catch (IllegalAccessException e) {
ClassloaderUtil.getLogger().warn("Unknown classloader [IAE]: " + e.getMessage());
} catch (InvocationTargetException e) {
ClassloaderUtil.getLogger().warn("Unknown classloader [ITE]: " + e.getMessage());
}
}
}
public static void addIDEALibraries(List<URL> classpathElements) {
final String ideaHomePath = PathManager.getHomePath();
ClassloaderUtil.addAllFromLibFolder(ideaHomePath, classpathElements);
}
@SuppressWarnings(value = {"HardCodedStringLiteral"})
public static void addAllFromLibFolder(final String aFolderPath, List<URL> classPath) {
try {
final Class<ClassloaderUtil> aClass = ClassloaderUtil.class;
final String selfRoot = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class");
final URL selfRootUrl = new File(selfRoot).getAbsoluteFile().toURI().toURL();
classPath.add(selfRootUrl);
final File libFolder = new File(aFolderPath + File.separator + "lib");
ClassloaderUtil.addLibraries(classPath, libFolder, selfRootUrl);
final File extLib = new File(libFolder, "ext");
ClassloaderUtil.addLibraries(classPath, extLib, selfRootUrl);
final File antLib = new File(new File(libFolder, "ant"), "lib");
ClassloaderUtil.addLibraries(classPath, antLib, selfRootUrl);
} catch (MalformedURLException e) {
ClassloaderUtil.getLogger().error(null, e);
}
}
public static void addLibraries(List<URL> classPath, File fromDir, final URL selfRootUrl) throws MalformedURLException {
final File[] files = fromDir.listFiles();
if (files != null) {
for (final File file : files) {
if (!(ClassloaderUtil.isJarOrZip(file))) {
continue;
}
final URL url = file.toURI().toURL();
if (selfRootUrl.equals(url)) {
continue;
}
classPath.add(url);
}
}
}
@SuppressWarnings(value = {"HardCodedStringLiteral"})
public static boolean isJarOrZip(File file) {
if (file.isDirectory()) {
return false;
}
final String name = file.getName();
return StringUtil.endsWithIgnoreCase(name, ".jar") || StringUtil.endsWithIgnoreCase(name, ".zip");
}
public static void addAdditionalClassPath(List<URL> classPath) {
try {
// noinspection HardCodedStringLiteral
final StringTokenizer tokenizer = new StringTokenizer(System.getProperty("idea.additional.classpath", ""), File.pathSeparator, false);
while (tokenizer.hasMoreTokens()) {
String pathItem = tokenizer.nextToken();
classPath.add(new File(pathItem).toURI().toURL());
}
} catch (MalformedURLException e) {
ClassloaderUtil.getLogger().error(null, e);
}
}
@SuppressWarnings(value = {"HardCodedStringLiteral"})
public static boolean isLoadingOfExternalPluginsDisabled() {
return !("true".equalsIgnoreCase(System.getProperty("idea.plugins.load", "true")));
}
}