Skip to content

Commit

Permalink
Do not suppress instrumentation exceptions but rather propagate them …
Browse files Browse the repository at this point in the history
…to mock maker that attempts instrumentation. Addresses #1005
  • Loading branch information
raphw committed Mar 30, 2017
1 parent 9b98d71 commit 503a291
Showing 1 changed file with 15 additions and 2 deletions.
Expand Up @@ -31,7 +31,6 @@
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
import java.util.Arrays;
Expand All @@ -41,6 +40,7 @@
import static net.bytebuddy.implementation.MethodDelegation.withDefaultConfiguration;
import static net.bytebuddy.implementation.bind.annotation.TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of;
import static net.bytebuddy.matcher.ElementMatchers.*;
import static org.mockito.internal.util.StringUtil.join;

public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTransformer {

Expand Down Expand Up @@ -68,6 +68,8 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran

private final BytecodeGenerator subclassEngine;

private volatile Throwable lastException;

public InlineBytecodeGenerator(Instrumentation instrumentation, WeakConcurrentMap<Object, MockMethodInterceptor> mocks) {
this.instrumentation = instrumentation;
byteBuddy = new ByteBuddy()
Expand Down Expand Up @@ -113,11 +115,21 @@ private <T> void triggerRetransformation(MockFeatures<T> features) {
if (!types.isEmpty()) {
try {
instrumentation.retransformClasses(types.toArray(new Class<?>[types.size()]));
} catch (UnmodifiableClassException exception) {
Throwable throwable = lastException;
if (throwable != null) {
throw new IllegalStateException(join("Byte Buddy could not instrument all classes within the mock's type hierarchy",
"",
"This problem should never occur for javac-compiled classes. This problem has been observed for classes that are:",
" - Compiled by older versions of scalac",
" - Classes that are part of the Android distribution"), throwable);
}
} catch (Exception exception) {
for (Class<?> failed : types) {
mocked.remove(failed);
}
throw new MockitoException("Could not modify all classes " + types, exception);
} finally {
lastException = null;
}
}
}
Expand Down Expand Up @@ -169,6 +181,7 @@ public byte[] transform(ClassLoader loader,
.make()
.getBytes();
} catch (Throwable throwable) {
lastException = throwable;
return null;
}
}
Expand Down

0 comments on commit 503a291

Please sign in to comment.