Skip to content

Commit

Permalink
Add isParentFirst method to QuarkusClassLoader
Browse files Browse the repository at this point in the history
    This can be used by extensions to determine if a class
    would be loaded parent first or not.
    Relates to: quarkusio/quarkus#16576 (comment)
  • Loading branch information
Luca Di Grazia committed Sep 4, 2022
1 parent 804e47f commit 2f7a841
Showing 1 changed file with 47 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public class QuarkusClassLoader extends ClassLoader implements Closeable {
private volatile boolean driverLoaded;

private QuarkusClassLoader(Builder builder) {
super(builder.parent);
super(new GetPackageBlockingClassLoader(builder.parent));
this.name = builder.name;
this.elements = builder.elements;
this.bannedElements = builder.bannedElements;
Expand Down Expand Up @@ -117,6 +117,32 @@ private String sanitizeName(String name) {
return name;
}

/**
* Returns true if the supplied class is a class that would be loaded parent-first
*/
public boolean isParentFirst(String name) {
if (name.startsWith(JAVA)) {
return true;
}

//even if the thread is interrupted we still want to be able to load classes
//if the interrupt bit is set then we clear it and restore it at the end
boolean interrupted = Thread.interrupted();
try {
ClassLoaderState state = getState();
synchronized (getClassLoadingLock(name)) {
String resourceName = sanitizeName(name).replace(".", "/") + ".class";
return parentFirst(resourceName, state);
}

} finally {
if (interrupted) {
//restore interrupt state
Thread.currentThread().interrupt();
}
}
}

private boolean parentFirst(String name, ClassLoaderState state) {
return parentFirst || state.parentFirstResources.contains(name);
}
Expand Down Expand Up @@ -354,7 +380,7 @@ public InputStream getResourceAsStream(String unsanitisedName) {
* @param name
* @return
*/
@Override
//@Override
protected Class<?> findClass(String moduleName, String name) {
try {
return loadClass(name, false);
Expand Down Expand Up @@ -706,4 +732,23 @@ static final class ClassLoaderState {
}
}

/**
* Horrible JDK8 hack
*
* getPackage() on JDK8 will always delegate to the parent, so QuarkusClassLoader will never define a package,
* which can cause issues if you then try and read package annotations as they will be from the wrong ClassLoader.
*
* We add this ClassLoader into the mix to block the getPackage() delegation.
*/
private static class GetPackageBlockingClassLoader extends ClassLoader {

protected GetPackageBlockingClassLoader(ClassLoader parent) {
super(parent);
}

@Override
protected Package getPackage(String name) {
return null;
}
}
}

0 comments on commit 2f7a841

Please sign in to comment.