xref: /JGit/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/SeparateClassloaderTestRunner.java (revision 9299df41cb941ab21b6c4bd835510305b7fd5382)
1 /*
2  * Copyright (C) 2019 Nail Samatov <sanail@yandex.ru> and others
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Distribution License v. 1.0 which is available at
6  * https://www.eclipse.org/org/documents/edl-v10.php.
7  *
8  * SPDX-License-Identifier: BSD-3-Clause
9  */
10 package org.eclipse.jgit.junit;
11 
12 import java.net.MalformedURLException;
13 import java.net.URL;
14 import java.net.URLClassLoader;
15 import java.nio.file.Paths;
16 
17 import org.junit.runners.BlockJUnit4ClassRunner;
18 import org.junit.runners.model.InitializationError;
19 
20 /**
21  * This class is used when it's required to load jgit classes in separate
22  * classloader for each test class. It can be needed to isolate static field
23  * initialization between separate tests.
24  */
25 public class SeparateClassloaderTestRunner extends BlockJUnit4ClassRunner {
26 
27 	/**
28 	 * Creates a SeparateClassloaderTestRunner to run {@code klass}.
29 	 *
30 	 * @param klass
31 	 *            test class to run.
32 	 * @throws InitializationError
33 	 *             if the test class is malformed or can't be found.
34 	 */
SeparateClassloaderTestRunner(Class<?> klass)35 	public SeparateClassloaderTestRunner(Class<?> klass)
36 			throws InitializationError {
37 		super(loadNewClass(klass));
38 	}
39 
loadNewClass(Class<?> klass)40 	private static Class<?> loadNewClass(Class<?> klass)
41 			throws InitializationError {
42 		try {
43 			String pathSeparator = System.getProperty("path.separator");
44 			String[] classPathEntries = System.getProperty("java.class.path")
45 					.split(pathSeparator);
46 			URL[] urls = new URL[classPathEntries.length];
47 			for (int i = 0; i < classPathEntries.length; i++) {
48 				urls[i] = Paths.get(classPathEntries[i]).toUri().toURL();
49 			}
50 			ClassLoader testClassLoader = new URLClassLoader(urls) {
51 
52 				@Override
53 				public Class<?> loadClass(String name)
54 						throws ClassNotFoundException {
55 					if (name.startsWith("org.eclipse.jgit.")) {
56 						return super.findClass(name);
57 					}
58 
59 					return super.loadClass(name);
60 				}
61 			};
62 			return Class.forName(klass.getName(), true, testClassLoader);
63 		} catch (ClassNotFoundException | MalformedURLException e) {
64 			throw new InitializationError(e);
65 		}
66 	}
67 }
68