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