MINOR: Catch InvocationTargetException explicitly and propagate underlying cause (#12230)

Catch InvocationTargetException explicitly and propagate underlying cause

Reviewers: Ismael Juma <mlists@juma.me.uk>, Matthew de Detrich <mdedetrich@gmail.com>, Kvicii, Luke Chen <showuon@gmail.com>
This commit is contained in:
Divij Vaidya 2022-08-23 11:34:39 +02:00 committed by GitHub
parent add4ca6c7f
commit 9aef992118
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 35 deletions

View File

@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
@ -75,8 +76,12 @@ public class LoggingSignalHandler {
private Object createSignalHandler(final Map<String, Object> jvmSignalHandlers) {
InvocationHandler invocationHandler = new InvocationHandler() {
private String getName(Object signal) throws ReflectiveOperationException {
return (String) signalGetNameMethod.invoke(signal);
private String getName(Object signal) throws Throwable {
try {
return (String) signalGetNameMethod.invoke(signal);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
private void handle(Object signalHandler, Object signal) throws ReflectiveOperationException {

View File

@ -463,8 +463,7 @@ public final class Utils {
throw new ClassNotFoundException(String.format("Unable to access " +
"constructor of %s", className), e);
} catch (InvocationTargetException e) {
throw new ClassNotFoundException(String.format("Unable to invoke " +
"constructor of %s", className), e);
throw new KafkaException(String.format("The constructor of %s threw an exception", className), e.getCause());
}
}

View File

@ -122,6 +122,14 @@ public class KafkaFutureTest {
assertEquals(CancellationException.class, cancellationException.getClass());
}
private Object invokeOrThrow(final Method method, final Object obj, final Object... args) throws Throwable {
try {
return method.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
@Test
public void testCompleteFutures() throws Exception {
KafkaFutureImpl<Integer> future123 = new KafkaFutureImpl<>();
@ -591,7 +599,7 @@ public class KafkaFutureTest {
@Test
@SuppressWarnings("unchecked")
public void testLeakCompletableFuture() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
public void testLeakCompletableFuture() throws Throwable {
final KafkaFutureImpl<String> kfut = new KafkaFutureImpl<>();
CompletableFuture<String> comfut = kfut.toCompletionStage().toCompletableFuture();
assertThrows(UnsupportedOperationException.class, () -> comfut.complete(""));
@ -600,44 +608,20 @@ public class KafkaFutureTest {
// so test reflectively
if (Java.IS_JAVA9_COMPATIBLE) {
Method completeOnTimeout = CompletableFuture.class.getDeclaredMethod("completeOnTimeout", Object.class, Long.TYPE, TimeUnit.class);
assertThrows(UnsupportedOperationException.class, () -> {
try {
completeOnTimeout.invoke(comfut, "", 1L, TimeUnit.MILLISECONDS);
} catch (InvocationTargetException e) {
throw e.getCause();
}
});
assertThrows(UnsupportedOperationException.class, () -> invokeOrThrow(completeOnTimeout, comfut, "", 1L, TimeUnit.MILLISECONDS));
Method completeAsync = CompletableFuture.class.getDeclaredMethod("completeAsync", Supplier.class);
assertThrows(UnsupportedOperationException.class, () -> {
try {
completeAsync.invoke(comfut, (Supplier<String>) () -> "");
} catch (InvocationTargetException e) {
throw e.getCause();
}
});
assertThrows(UnsupportedOperationException.class, () -> invokeOrThrow(completeAsync, comfut, (Supplier<String>) () -> ""));
Method obtrudeValue = CompletableFuture.class.getDeclaredMethod("obtrudeValue", Object.class);
assertThrows(UnsupportedOperationException.class, () -> {
try {
obtrudeValue.invoke(comfut, "");
} catch (InvocationTargetException e) {
throw e.getCause();
}
});
assertThrows(UnsupportedOperationException.class, () -> invokeOrThrow(obtrudeValue, comfut, ""));
Method obtrudeException = CompletableFuture.class.getDeclaredMethod("obtrudeException", Throwable.class);
assertThrows(UnsupportedOperationException.class, () -> {
try {
obtrudeException.invoke(comfut, new RuntimeException());
} catch (InvocationTargetException e) {
throw e.getCause();
}
});
assertThrows(UnsupportedOperationException.class, () -> invokeOrThrow(obtrudeException, comfut, new RuntimeException()));
// Check the CF from a minimal CompletionStage doesn't cause completion of the original KafkaFuture
Method minimal = CompletableFuture.class.getDeclaredMethod("minimalCompletionStage");
CompletionStage<String> cs = (CompletionStage<String>) minimal.invoke(comfut);
CompletionStage<String> cs = (CompletionStage<String>) invokeOrThrow(minimal, comfut);
cs.toCompletableFuture().complete("");
assertFalse(kfut.isDone());

View File

@ -78,7 +78,7 @@ public class RecordTestUtils {
}
}
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
throw new RuntimeException(e.getCause());
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}