![JAR search and dependency download from the Maven repository](/logo.png)
sbt.internal.BottomClassLoader Maven / Gradle / Ivy
Show all versions of main_2.12 Show documentation
/*
* sbt
* Copyright 2023, Scala center
* Copyright 2011 - 2022, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt.internal;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import sbt.util.Logger;
/**
* The bottom most layer in our layering hierarchy. This layer should never be cached. The
* dependency layer may need access to classes only available at this layer using java reflection.
* To make this work, we register this loader with the parent in its constructor. We also add the
* lookupClass method which gives ReverseLookupClassLoader a public interface to findClass.
*
* To improve performance, when loading classes from the parent, we call the loadClass method
* with the reverseLookup flag set to false. This prevents the ReverseLookupClassLoader from trying
* to call back into this loader when it can't find a particular class.
*/
final class BottomClassLoader extends ManagedClassLoader {
private final ReverseLookupClassLoaderHolder holder;
private final ReverseLookupClassLoader parent;
private final ClassLoadingLock classLoadingLock = new ClassLoadingLock();
BottomClassLoader(
final ReverseLookupClassLoaderHolder holder,
final URL[] dynamicClasspath,
final ReverseLookupClassLoader reverseLookupClassLoader,
final File tempDir,
final boolean close,
final boolean allowZombies,
final Logger logger) {
super(dynamicClasspath, reverseLookupClassLoader, close, allowZombies, logger);
setTempDir(tempDir);
this.holder = holder;
this.parent = reverseLookupClassLoader;
parent.setDescendant(this);
}
static {
ClassLoader.registerAsParallelCapable();
}
@Override
public Class> findClass(final String name) throws ClassNotFoundException {
return classLoadingLock.withLock(
name,
() -> {
final Class> prev = findLoadedClass(name);
if (prev != null) return prev;
return super.findClass(name);
});
}
@Override
protected Class> loadClass(final String name, final boolean resolve)
throws ClassNotFoundException {
try {
return parent.loadClass(name, resolve, false);
} catch (final ClassNotFoundException e) {
final Class> clazz = findClass(name);
if (resolve) resolveClass(clazz);
return clazz;
}
}
@Override
public void close() throws IOException {
holder.checkin(parent);
super.close();
}
}