Skip to content

Commit

Permalink
Fix Mockito meta test issue by clearing ObjenesisBase instantiator ca…
Browse files Browse the repository at this point in the history
…che when replacing the classloader
  • Loading branch information
martinmladenov committed Jul 14, 2024
1 parent b1526bb commit ec6611c
Showing 1 changed file with 25 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
import nl.tudelft.cse1110.andy.config.DirectoryConfiguration;
import nl.tudelft.cse1110.andy.execution.ExecutionStep;
import nl.tudelft.cse1110.andy.result.ResultBuilder;
import org.objenesis.ObjenesisStd;

import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
* This step replaces the classloader with one that sees the folder
Expand All @@ -26,6 +29,7 @@ public void execute(Context ctx, ResultBuilder result) {
String pathToAddToClassloader = dirCfg.getWorkingDir();
replaceClassloader(ctx, pathToAddToClassloader);
ctx.setClassloaderWithStudentsCode(Thread.currentThread().getContextClassLoader());
clearMockitoObjenesisInstantiatorCache();
} catch (Exception e) {
result.genericFailure(this, e);
}
Expand All @@ -40,6 +44,27 @@ private void replaceClassloader(Context ctx, String pathToAddToClassloader) {
Thread.currentThread().setContextClassLoader(customClassLoader);
}

private void clearMockitoObjenesisInstantiatorCache() throws ReflectiveOperationException {
Class<?> defaultInstantiatorProviderClass = Class.forName(
"org.mockito.internal.creation.instance.DefaultInstantiatorProvider");
Field objenesisInstantiatorField = defaultInstantiatorProviderClass.getDeclaredField("INSTANCE");
objenesisInstantiatorField.setAccessible(true);

// org.mockito.internal.creation.instance.ObjenesisInstantiator
Object objenesisInstantiator = objenesisInstantiatorField.get(null);
Field objenesisStdField = objenesisInstantiator.getClass().getDeclaredField("objenesis");
objenesisStdField.setAccessible(true);

// org.objenesis.ObjenesisStd extends ObjenesisBase
ObjenesisStd objenesisStd = (ObjenesisStd) objenesisStdField.get(objenesisInstantiator);
Field objenesisBaseCacheField = objenesisStd.getClass().getSuperclass().getDeclaredField("cache");
objenesisBaseCacheField.setAccessible(true);

// clear instantiator cache
ConcurrentHashMap<?, ?> cache = (ConcurrentHashMap<?, ?>) objenesisBaseCacheField.get(objenesisStd);
cache.clear();
}

private URL toURL(Path path) {
try {
return path.toUri().toURL();
Expand Down

0 comments on commit ec6611c

Please sign in to comment.