1 package top.infra.test.classloader.exclude;
2
3 import com.google.common.collect.ImmutableList;
4
5 import lombok.extern.slf4j.Slf4j;
6
7 import java.net.URL;
8 import java.net.URLClassLoader;
9 import java.util.Collection;
10
11
12
13
14 @Slf4j
15 public class ExcludeClassesClassLoader extends URLClassLoader {
16
17 private final ClassLoader parentClassLoader;
18 private Collection<String> excludes;
19
20 public ExcludeClassesClassLoader(
21 final ClassLoader parentClassLoader, final URL[] urls, final Collection<String> excludes) {
22
23 super(urls, null);
24
25 log.info("ExcludeClassesClassLoader parentClassLoader " + parentClassLoader);
26
27 this.setExcludes(excludes);
28 this.parentClassLoader = parentClassLoader;
29 }
30
31 @Override
32 public synchronized Class<?> loadClass(final String name) throws ClassNotFoundException {
33
34
35 if (!this.excludes.contains(name)) {
36
37
38 if (!name.startsWith("java.")
39 && !name.startsWith("javax.")
40 && !name.startsWith("org.junit.")
41 && !name.startsWith("org.xml.")
42 && !name.startsWith("org.w3c.")
43 && !name.startsWith("sun.")
44 && !"top.infra.test.classloader.exclude.ExcludeClasses".equals(name)
45 ) {
46 final Class<?> result;
47 final Class<?> loadedClass = this.findLoadedClass(name);
48 if (loadedClass == null) {
49 result = this.findClass(name);
50 } else {
51 result = loadedClass;
52 }
53 return result;
54 }
55
56 return this.parentClassLoader.loadClass(name);
57 } else {
58 throw new ClassNotFoundException("class " + name + " is excluded from classpath");
59 }
60 }
61
62 public void setExcludes(final Collection<String> excludes) {
63 this.excludes = excludes != null ? excludes : ImmutableList.of();
64 }
65 }