Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2023 BSI Business Systems Integration AG
* Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand All @@ -21,6 +21,7 @@
import org.eclipse.scout.rt.testing.platform.runner.statement.AssertNoRunningJobsStatement;
import org.eclipse.scout.rt.testing.platform.runner.statement.BeanAnnotationsCleanupStatement;
import org.eclipse.scout.rt.testing.platform.runner.statement.BeanAnnotationsInitStatement;
import org.eclipse.scout.rt.testing.platform.runner.statement.CleanupStaticFieldsStatement;
import org.eclipse.scout.rt.testing.platform.runner.statement.ClearThreadInterruptionStatusStatement;
import org.eclipse.scout.rt.testing.platform.runner.statement.PlatformStatement;
import org.eclipse.scout.rt.testing.platform.runner.statement.RegisterBeanStatement;
Expand Down Expand Up @@ -161,11 +162,18 @@ protected Statement methodBlock(final FrameworkMethod method) {
}

protected Statement interceptBeforeClassStatement(Statement beforeClassStatement, Class<?> javaClass) {
return interceptClassLevelStatement(beforeClassStatement, javaClass);
final Statement s2 = new SubjectStatement(beforeClassStatement, javaClass.getAnnotation(RunWithSubject.class));
final Statement s1 = new RegisterBeanStatement(s2, new BeanMetaData(JUnitExceptionHandler.class).withReplace(true).withOrder(-1000)); // exception handler to not silently swallow handled exceptions.

return s1;
}

protected Statement interceptAfterClassStatement(Statement beforeClassStatement, Class<?> javaClass) {
return interceptClassLevelStatement(beforeClassStatement, javaClass);
protected Statement interceptAfterClassStatement(Statement afterClassStatement, Class<?> javaClass) {
final Statement s3 = new CleanupStaticFieldsStatement(afterClassStatement, javaClass);
final Statement s2 = new SubjectStatement(s3, javaClass.getAnnotation(RunWithSubject.class));
final Statement s1 = new RegisterBeanStatement(s2, new BeanMetaData(JUnitExceptionHandler.class).withReplace(true).withOrder(-1000)); // exception handler to not silently swallow handled exceptions.

return s1;
}

protected Statement interceptBeforeStatement(final Statement next, final Class<?> testClass, final Method testMethod) {
Expand Down Expand Up @@ -208,7 +216,10 @@ protected Statement interceptAfterStatement(final Statement next, final Class<?>
* @return the head of the chain to be invoked first.
*/
protected Statement interceptClassLevelStatement(final Statement next, final Class<?> testClass) {
final Statement s2 = new SubjectStatement(next, testClass.getAnnotation(RunWithSubject.class));
final List<FrameworkMethod> afters = getTestClass().getAnnotatedMethods(AfterClass.class);

final Statement s3 = afters.isEmpty() ? new CleanupStaticFieldsStatement(next, testClass) : next;
final Statement s2 = new SubjectStatement(s3, testClass.getAnnotation(RunWithSubject.class));
final Statement s1 = new RegisterBeanStatement(s2, new BeanMetaData(JUnitExceptionHandler.class).withReplace(true).withOrder(-1000)); // exception handler to not silently swallow handled exceptions.

return s1;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.scout.rt.testing.platform.runner.statement;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import org.junit.runners.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CleanupStaticFieldsStatement extends Statement {

private static final Logger LOG = LoggerFactory.getLogger(CleanupStaticFieldsStatement.class);

private final Statement m_next;
private final Class<?> m_testClass;

public CleanupStaticFieldsStatement(Statement next, Class<?> testClass) {
m_next = next;
m_testClass = testClass;
}

@Override
public void evaluate() throws Throwable {
try {
m_next.evaluate();
}
finally {
Class<?> currentClass = m_testClass;
while (currentClass != null) {
for (Field field : currentClass.getDeclaredFields()) {
int modifiers = field.getModifiers();
boolean staticField = Modifier.isStatic(modifiers);
boolean finalField = Modifier.isFinal(modifiers);

if (!staticField || finalField) {
continue;
}

if (field.getType().isPrimitive()) {
continue;
}

LOG.info("{}#{}: setting static field to null after test is finished", currentClass.getName(), field.getName());

field.setAccessible(true);
field.set(null, null);
}

currentClass = currentClass.getSuperclass();
}
}
}
}