use of org.jetbrains.groovy.compiler.rt.ClassDependencyLoader in project intellij-community by JetBrains.
the class InProcessGroovyc method obtainParentLoader.
@Nullable
private static ClassLoader obtainParentLoader(Collection<String> compilationClassPath) throws MalformedURLException {
if (!"true".equals(System.getProperty("groovyc.reuse.compiler.classes", "true"))) {
return null;
}
List<String> groovyJars = ContainerUtil.findAll(compilationClassPath, s -> {
String fileName = StringUtil.getShortName(s, '/');
return GROOVY_ALL_JAR_PATTERN.matcher(fileName).matches() || GROOVY_JAR_PATTERN.matcher(fileName).matches();
});
LOG.debug("Groovy jars: " + groovyJars);
if (groovyJars.size() != 1 || !GROOVY_ALL_JAR_PATTERN.matcher(groovyJars.get(0)).matches()) {
// avoid complications caused by caching classes from several groovy versions in classpath
return null;
}
String groovyAll = groovyJars.get(0);
Pair<String, ClassLoader> pair = SoftReference.dereference(ourParentLoaderCache);
if (pair != null && pair.first.equals(groovyAll)) {
return pair.second;
}
final ClassDependencyLoader checkWellFormed = new ClassDependencyLoader() {
@Override
protected void loadClassDependencies(Class aClass) throws ClassNotFoundException {
if (!isCompilerCoreClass(aClass.getName()) || !(aClass.getClassLoader() instanceof UrlClassLoader)) {
super.loadClassDependencies(aClass);
}
}
private boolean isCompilerCoreClass(String name) {
if (name.startsWith("groovyjarjar")) {
return true;
}
if (name.startsWith("org.codehaus.groovy.")) {
String tail = name.substring("org.codehaus.groovy.".length());
if (tail.startsWith("ast") || tail.startsWith("classgen") || tail.startsWith("tools.javac") || tail.startsWith("antlr") || tail.startsWith("vmplugin") || tail.startsWith("reflection") || tail.startsWith("control")) {
return true;
}
if (tail.startsWith("runtime") && name.contains("GroovyMethods")) {
return true;
}
}
return false;
}
};
UrlClassLoader groovyAllLoader = UrlClassLoader.build().urls(toUrls(ContainerUtil.concat(GroovyBuilder.getGroovyRtRoots(), Collections.singletonList(groovyAll)))).allowLock().useCache(ourLoaderCachePool, new UrlClassLoader.CachingCondition() {
@Override
public boolean shouldCacheData(@NotNull URL url) {
return true;
}
}).get();
ClassLoader wrapper = new URLClassLoader(new URL[0], groovyAllLoader) {
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.startsWith("groovy.grape.")) {
// grape depends on Ivy which is not included in this class loader
throw new ClassNotFoundException(name);
}
try {
return checkWellFormed.loadDependencies(super.loadClass(name, resolve));
} catch (NoClassDefFoundError e) {
// For this to happen we should throw ClassNotFoundException
throw new ClassNotFoundException(name, e);
}
}
};
ourParentLoaderCache = new SoftReference<>(Pair.create(groovyAll, wrapper));
return wrapper;
}
Aggregations