001
014
015 package com.liferay.portal.kernel.test;
016
017 import com.liferay.portal.kernel.process.ClassPathUtil;
018 import com.liferay.portal.kernel.util.MethodCache;
019 import com.liferay.portal.kernel.util.MethodKey;
020
021 import java.lang.reflect.InvocationTargetException;
022 import java.lang.reflect.Method;
023
024 import java.net.MalformedURLException;
025 import java.net.URL;
026 import java.net.URLClassLoader;
027
028 import java.util.ArrayList;
029 import java.util.List;
030
031 import org.junit.After;
032 import org.junit.Before;
033 import org.junit.runner.manipulation.Sorter;
034 import org.junit.runners.BlockJUnit4ClassRunner;
035 import org.junit.runners.model.FrameworkMethod;
036 import org.junit.runners.model.InitializationError;
037 import org.junit.runners.model.Statement;
038 import org.junit.runners.model.TestClass;
039
040
043 public class NewClassLoaderJUnitTestRunner extends BlockJUnit4ClassRunner {
044
045 public NewClassLoaderJUnitTestRunner(Class<?> clazz)
046 throws InitializationError {
047
048 super(clazz);
049
050 sort(new Sorter(new DescriptionComparator()));
051 }
052
053 protected ClassLoader createClassLoader(FrameworkMethod frameworkMethod) {
054 String jvmClassPath = ClassPathUtil.getJVMClassPath(true);
055
056 URL[] urls = null;
057
058 try {
059 urls = ClassPathUtil.getClassPathURLs(jvmClassPath);
060 }
061 catch (MalformedURLException murle) {
062 throw new RuntimeException(murle);
063 }
064
065 return new URLClassLoader(urls, null);
066 }
067
068 @Override
069 protected Statement methodBlock(FrameworkMethod frameworkMethod) {
070 TestClass testClass = getTestClass();
071
072 List<FrameworkMethod> beforeFrameworkMethods =
073 testClass.getAnnotatedMethods(Before.class);
074
075 List<FrameworkMethod> afterFrameworkMethods =
076 testClass.getAnnotatedMethods(After.class);
077
078 Class<?> clazz = testClass.getJavaClass();
079
080 return new RunInNewClassLoaderStatement(
081 clazz, beforeFrameworkMethods, frameworkMethod,
082 afterFrameworkMethods);
083 }
084
085 private class RunInNewClassLoaderStatement extends Statement {
086
087 public RunInNewClassLoaderStatement(
088 Class<?> testClass, List<FrameworkMethod> beforeFrameworkMethods,
089 FrameworkMethod testFrameworkMethod,
090 List<FrameworkMethod> afterFrameworkMethods) {
091
092 _testClassName = testClass.getName();
093
094 _beforeMethodKeys = new ArrayList<MethodKey>(
095 beforeFrameworkMethods.size());
096
097 for (FrameworkMethod frameworkMethod : beforeFrameworkMethods) {
098 _beforeMethodKeys.add(
099 new MethodKey(frameworkMethod.getMethod()));
100 }
101
102 _testMethodKey = new MethodKey(testFrameworkMethod.getMethod());
103
104 _afterMethodKeys = new ArrayList<MethodKey>(
105 afterFrameworkMethods.size());
106
107 for (FrameworkMethod frameworkMethod : afterFrameworkMethods) {
108 _afterMethodKeys.add(
109 new MethodKey(frameworkMethod.getMethod()));
110 }
111
112 _newClassLoader = createClassLoader(testFrameworkMethod);
113 }
114
115 @Override
116 public void evaluate() throws Throwable {
117 MethodCache.reset();
118
119 Thread currentThread = Thread.currentThread();
120
121 ClassLoader contextClassLoader =
122 currentThread.getContextClassLoader();
123
124 currentThread.setContextClassLoader(_newClassLoader);
125
126 try {
127 Class<?> clazz = _newClassLoader.loadClass(_testClassName);
128
129 Object object = clazz.newInstance();
130
131 for (MethodKey beforeMethodKey : _beforeMethodKeys) {
132 _invoke(beforeMethodKey, object);
133 }
134
135 _invoke(_testMethodKey, object);
136
137 for (MethodKey afterMethodKey : _afterMethodKeys) {
138 _invoke(afterMethodKey, object);
139 }
140 }
141 catch (InvocationTargetException ite) {
142 throw ite.getTargetException();
143 }
144 finally {
145 currentThread.setContextClassLoader(contextClassLoader);
146 }
147 }
148
149 private void _invoke(MethodKey methodKey, Object object)
150 throws Exception {
151
152 methodKey = methodKey.transform(_newClassLoader);
153
154 Method method = methodKey.getMethod();
155
156 method.invoke(object);
157 }
158
159 private List<MethodKey> _afterMethodKeys;
160 private List<MethodKey> _beforeMethodKeys;
161 private ClassLoader _newClassLoader;
162 private String _testClassName;
163 private MethodKey _testMethodKey;
164
165 }
166
167 }