@Override public TestResult invoke(final TestMethodExecutor testMethodExecutor) { try { if (testMethodExecutor == null) { throw new IllegalArgumentException("TestMethodExecutor must be specified"); } final String testClassName = testMethodExecutor.getInstance().getClass().getName(); Object testInstance = null; Class<?> testClass = null; try { final AddonRegistry addonRegistry = furnace.getAddonRegistry(); waitUntilStable(furnace); System.out.println("Searching for test [" + testClassName + "]"); for (Addon addon : addonRegistry.getAddons()) { if (addon.getStatus().isStarted()) { ServiceRegistry registry = addon.getServiceRegistry(); ExportedInstance<?> exportedInstance = registry.getExportedInstance(testClassName); if (exportedInstance != null) { if (testInstance == null) { testInstance = exportedInstance.get(); testClass = ClassLoaders.loadClass(addon.getClassLoader(), testClassName); } else { throw new IllegalStateException( "Multiple test classes found in deployed addons. " + "You must have only one @Deployment(testable=true\"); deployment"); } } } } } catch (Exception e) { String message = "Error launching test " + testMethodExecutor.getInstance().getClass().getName() + "." + testMethodExecutor.getMethod().getName() + "()"; System.out.println(message); throw new IllegalStateException(message, e); } if (testInstance != null) { try { TestResult result = null; try { try { testInstance = ClassLoaderAdapterBuilder.callingLoader(getClass().getClassLoader()) .delegateLoader(testInstance.getClass().getClassLoader()) .enhance(testInstance, testClass); } catch (Exception e) { System.out.println( "Could not enhance test class. Falling back to un-proxied invocation."); } Method method = testInstance.getClass().getMethod(testMethodExecutor.getMethod().getName()); Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { if ("org.junit.Ignore".equals(annotation.getClass().getName())) { result = new TestResult(Status.SKIPPED); } } if (result == null) { try { System.out.println( "Executing test method: " + testMethodExecutor.getInstance().getClass().getName() + "." + testMethodExecutor.getMethod().getName() + "()"); try { invokeBefore(testInstance.getClass(), testInstance); method.invoke(testInstance); result = new TestResult(Status.PASSED); } catch (Exception e) { Throwable rootCause = getRootCause(e); // FORGE-1677 if (rootCause != null && "org.junit.internal.AssumptionViolatedException" .equals(rootCause.getClass().getName())) { try { // Due to classloader and serialization restrictions, we need to create a new // instance // of this class Throwable thisClassloaderException = (Throwable) Class.forName("org.junit.internal.AssumptionViolatedException") .getConstructor(String.class) .newInstance(rootCause.getMessage()); thisClassloaderException.setStackTrace(rootCause.getStackTrace()); result = new TestResult(Status.SKIPPED, thisClassloaderException); } catch (Exception ex) { // ignore result = new TestResult(Status.SKIPPED); } } else { throw e; } } finally { invokeAfter(testInstance.getClass(), testInstance); } } catch (InvocationTargetException e) { if (e.getCause() != null && e.getCause() instanceof Exception) throw (Exception) e.getCause(); else throw e; } } } catch (AssertionError e) { result = new TestResult(Status.FAILED, e); } catch (Exception e) { result = new TestResult(Status.FAILED, e); Throwable cause = e.getCause(); while (cause != null) { if (cause instanceof AssertionError) { result = new TestResult(Status.FAILED, cause); break; } cause = cause.getCause(); } } return result; } catch (Exception e) { String message = "Error launching test " + testMethodExecutor.getInstance().getClass().getName() + "." + testMethodExecutor.getMethod().getName() + "()"; System.out.println(message); throw new IllegalStateException(message, e); } } else { throw new IllegalStateException( "Test runner could not locate test class [" + testClassName + "] in any deployed Addon."); } } finally { furnace = null; } }