View Javadoc
1   package top.infra.test.classloader.exclude;
2   
3   import lombok.SneakyThrows;
4   
5   import org.junit.runner.Runner;
6   import org.junit.runners.BlockJUnit4ClassRunner;
7   import org.junit.runners.Suite;
8   import org.junit.runners.model.InitializationError;
9   
10  import java.net.URLClassLoader;
11  import java.util.ArrayList;
12  import java.util.Arrays;
13  import java.util.List;
14  
15  import top.infra.test.classloader.ClassLoaderChangerRunner;
16  import top.infra.test.classloader.ClassUtils;
17  
18  public class ExcludeClassJunitRunner extends Suite {
19  
20      private static URLClassLoader currentClassLoader;
21      private static ExcludeClassesClassLoader customClassLoader;
22  
23      static {
24          currentClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
25          customClassLoader = new ExcludeClassesClassLoader(
26              currentClassLoader,
27              currentClassLoader.getURLs(),
28              null
29          );
30      }
31  
32      public ExcludeClassJunitRunner(final Class<?> klass) throws InitializationError {
33          super(
34              ClassUtils.loadFromCustomClassloader(customClassLoader, klass),
35              buildRunners(ClassUtils.loadFromCustomClassloader(customClassLoader, klass)));
36      }
37  
38      // Runs junit tests in a separate thread using the custom class loader
39  //    @Override
40  //    public void run(final org.junit.runner.notification.RunNotifier notifier) {
41  //        final Runnable runnable = () -> {
42  //            super.run(notifier);
43  //        };
44  //        final Thread thread = new Thread(runnable);
45  //        thread.setContextClassLoader(customClassLoader);
46  //        thread.start();
47  //        try {
48  //            thread.join();
49  //        } catch (final InterruptedException ex) {
50  //            Thread.currentThread().interrupt();
51  //        }
52  //    }
53  
54      @SneakyThrows
55      private static List<Runner> buildRunners(final Class<?> klass) {
56          final ExcludeClasses excludeClasses = klass.getAnnotation(ExcludeClasses.class);
57          if (excludeClasses == null) throw new IllegalArgumentException("Class " + klass + " is missing ExcludeClasses annotation");
58  
59          customClassLoader.setExcludes(Arrays.asList(excludeClasses.excludesClasses()));
60  
61          final Class<?> testClass = customClassLoader.loadClass(klass.getName());
62  
63          final Class<?> runnerClass = excludeClasses.runner();
64          final BlockJUnit4ClassRunner junit4Runner =
65              (BlockJUnit4ClassRunner) runnerClass.getConstructor(Class.class).newInstance(testClass);
66  
67          final List<Runner> runners = new ArrayList<>();
68          runners.add(new ClassLoaderChangerRunner(currentClassLoader, customClassLoader, junit4Runner));
69          return runners;
70      }
71  }