Search in sources :

Example 1 with ClassDependencyLoader

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;
}
Also used : NotNull(org.jetbrains.annotations.NotNull) URL(java.net.URL) URLClassLoader(java.net.URLClassLoader) UrlClassLoader(com.intellij.util.lang.UrlClassLoader) URLClassLoader(java.net.URLClassLoader) ClassDependencyLoader(org.jetbrains.groovy.compiler.rt.ClassDependencyLoader) UrlClassLoader(com.intellij.util.lang.UrlClassLoader) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

UrlClassLoader (com.intellij.util.lang.UrlClassLoader)1 URL (java.net.URL)1 URLClassLoader (java.net.URLClassLoader)1 NotNull (org.jetbrains.annotations.NotNull)1 Nullable (org.jetbrains.annotations.Nullable)1 ClassDependencyLoader (org.jetbrains.groovy.compiler.rt.ClassDependencyLoader)1