1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockito.internal.creation.jmock; 6 7 import static java.lang.Thread.*; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 /** 13 * Thanks to jMock guys for this ClassLoader. 14 */ 15 public class SearchingClassLoader extends ClassLoader { 16 private final ClassLoader nextToSearch; 17 18 public SearchingClassLoader(ClassLoader parent, ClassLoader nextToSearch) { 19 super(parent); 20 this.nextToSearch = nextToSearch; 21 } 22 23 public static ClassLoader combineLoadersOf(Class<?>... classes) { 24 return combineLoadersOf(classes[0], classes); 25 } 26 27 private static ClassLoader combineLoadersOf(Class<?> first, Class<?>... others) { 28 List<ClassLoader> loaders = new ArrayList<ClassLoader>(); 29 30 addIfNewElement(loaders, first.getClassLoader()); 31 for (Class<?> c : others) { 32 addIfNewElement(loaders, c.getClassLoader()); 33 } 34 35 // To support Eclipse Plug-in tests. 36 // In an Eclipse plug-in, jMock itself will not be on the system class loader 37 // but in the class loader of the plug-in. 38 // 39 // Note: I've been unable to reproduce the error in jMock's test suite. 40 addIfNewElement(loaders, SearchingClassLoader.class.getClassLoader()); 41 42 // To support the Maven Surefire plugin. 43 // Note: I've been unable to reproduce the error in jMock's test suite. 44 addIfNewElement(loaders, currentThread().getContextClassLoader()); 45 46 //Had to comment that out because it didn't work with in-container Spring tests 47 //addIfNewElement(loaders, ClassLoader.getSystemClassLoader()); 48 49 return combine(loaders); 50 } 51 52 private static ClassLoader combine(List<ClassLoader> parentLoaders) { 53 ClassLoader loader = parentLoaders.get(parentLoaders.size()-1); 54 55 for (int i = parentLoaders.size()-2; i >= 0; i--) { 56 loader = new SearchingClassLoader(parentLoaders.get(i), loader); 57 } 58 59 return loader; 60 } 61 62 private static void addIfNewElement(List<ClassLoader> loaders, ClassLoader c) { 63 if (c != null && !loaders.contains(c)) { 64 loaders.add(c); 65 } 66 } 67 68 @Override 69 protected Class<?> findClass(String name) throws ClassNotFoundException { 70 if (nextToSearch != null) { 71 return nextToSearch.loadClass(name); 72 } else { 73 return super.findClass(name); // will throw ClassNotFoundException 74 } 75 } 76 }