blob: c5e04bfcea8852d7575a1661ef8c93e35a6352d3 [file] [log] [blame]
// Copyright 2020 The Bazel Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.testing.junit.runner;
import com.google.common.hash.HashCode;
import java.net.URL;
import java.net.URLClassLoader;
/**
* A custom classloader used by the persistent test runner.
*
* <p>Each classloader stores the combined hash code for the loaded jars.
*/
final class PersistentTestRunnerClassLoader extends URLClassLoader {
private final HashCode checksum;
private PersistentTestRunnerClassLoader child;
public PersistentTestRunnerClassLoader(URL[] urls, ClassLoader parent, HashCode checksum) {
super(urls, parent);
this.checksum = checksum;
}
void setChild(PersistentTestRunnerClassLoader child) {
this.child = child;
}
HashCode getChecksum() {
return checksum;
}
/**
* Loads the class with the specified name and resolves it if required.
*
* <p>If the classloader has a child: check if the class was already loaded by the child if the
* current classloader did not succeed in loading the class.
*
* <p>If the classloader doesn't have a child: use the default class loading logic.
*/
@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (child == null) {
return super.loadClass(name, resolve);
}
synchronized (this.getClassLoadingLock(name)) {
Class<?> result;
try {
result = super.loadClass(name, resolve);
} catch (ClassNotFoundException e) {
result = child.findLoadedClass(name);
}
if (result == null) {
throw new ClassNotFoundException("Could not find " + name);
}
return result;
}
}
}