From 2fcc3292b4a094da2fa7e98bcd80e20f23c462f2 Mon Sep 17 00:00:00 2001 From: sancar Date: Tue, 14 Jul 2020 11:14:57 +0300 Subject: [PATCH 1/2] Add caller stacktrace to rethrown RuntimeException We have lots of places that we use the following pattern ``` try { invocationFuture.get() }catch(Exception e){ throw retrhow(e); } ``` If the exception is RuntimeException, it is not wrapped and thrown directly. In that case, we can not follow where the exception is thrown from. Here is an example of a put from a member. ``` java.lang.RuntimeException: here comes the bug at com.hazelcast.map.impl.operation.PutOperation.runInternal(PutOperation.java:36) at com.hazelcast.map.impl.operation.MapOperation.run(MapOperation.java:112) at com.hazelcast.spi.impl.operationservice.Operation.call(Operation.java:184) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.call(OperationRunnerImpl.java:227) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:216) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:422) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:166) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:136) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.executeRun(OperationThread.java:123) at com.hazelcast.internal.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:102) ``` : ``` try { invocationFuture.get() }catch(Exception e){ throw retrhow(e); } ``` If the exception is RuntimeException, it is not wrapped and thrown directly. In that case, we can not follow where the exception is thrown from. Here is an example of a put from a member. ``` java.lang.RuntimeException: here comes the bug at com.hazelcast.map.impl.operation.PutOperation.runInternal(PutOperation.java:36) at com.hazelcast.map.impl.operation.MapOperation.run(MapOperation.java:112) at com.hazelcast.spi.impl.operationservice.Operation.call(Operation.java:184) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.call(OperationRunnerImpl.java:227) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:216) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:422) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:166) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:136) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.executeRun(OperationThread.java:123) at com.hazelcast.internal.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:102) ``` Same problem on the client side: ``` java.lang.RuntimeException: here comes the bug at com.hazelcast.map.impl.operation.PutOperation.runInternal(PutOperation.java:36) at com.hazelcast.map.impl.operation.MapOperation.run(MapOperation.java:112) at com.hazelcast.spi.impl.operationservice.Operation.call(Operation.java:184) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.call(OperationRunnerImpl.java:227) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:216) at com.hazelcast.spi.impl.operationexecutor.impl.OperationExecutorImpl.run(OperationExecutorImpl.java:411) at com.hazelcast.spi.impl.operationexecutor.impl.OperationExecutorImpl.runOrExecute(OperationExecutorImpl.java:438) at com.hazelcast.spi.impl.operationservice.impl.Invocation.doInvokeLocal(Invocation.java:597) at com.hazelcast.spi.impl.operationservice.impl.Invocation.doInvoke(Invocation.java:582) at com.hazelcast.spi.impl.operationservice.impl.Invocation.invoke0(Invocation.java:541) at com.hazelcast.spi.impl.operationservice.impl.Invocation.invoke(Invocation.java:238) at com.hazelcast.spi.impl.operationservice.impl.InvocationBuilderImpl.invoke(InvocationBuilderImpl.java:59) at com.hazelcast.client.impl.protocol.task.AbstractPartitionMessageTask.processInternal(AbstractPartitionMessageTask.java:51) at com.hazelcast.client.impl.protocol.task.AbstractAsyncMessageTask.processMessage(AbstractAsyncMessageTask.java:71) at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.initializeAndProcessMessage(AbstractMessageTask.java:153) at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.run(AbstractMessageTask.java:116) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:180) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:172) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:140) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.executeRun(OperationThread.java:123) at com.hazelcast.internal.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:102) ``` These exceptions should contain the stack trace of the caller as well. But they only have the remote stack trace. To fix this, the tryWrapInSameClass is moved to ExceptionUtil to be used by rethrow. AbstractInvocationFuture uses methods from the ExceptionUtil. After the fix, the stacktrace of the same run for the member: ``` java.lang.RuntimeException: here comes the bug at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627) at com.hazelcast.internal.util.ExceptionUtil.tryWrapInSameClass(ExceptionUtil.java:233) at com.hazelcast.internal.util.ExceptionUtil.wrapException(ExceptionUtil.java:138) at com.hazelcast.internal.util.ExceptionUtil.peel(ExceptionUtil.java:114) at com.hazelcast.internal.util.ExceptionUtil.peel(ExceptionUtil.java:120) at com.hazelcast.internal.util.ExceptionUtil.peel(ExceptionUtil.java:73) at com.hazelcast.internal.util.ExceptionUtil.rethrow(ExceptionUtil.java:148) at com.hazelcast.map.impl.proxy.MapProxySupport.invokeOperation(MapProxySupport.java:484) at com.hazelcast.map.impl.proxy.MapProxySupport.putInternal(MapProxySupport.java:411) at com.hazelcast.map.impl.proxy.MapProxyImpl.put(MapProxyImpl.java:130) at com.hazelcast.map.impl.proxy.MapProxyImpl.put(MapProxyImpl.java:120) at XNode.onliteMember(XNode.java:28) at XNode.main(XNode.java:14) Caused by: java.lang.RuntimeException: here comes the bug at com.hazelcast.map.impl.operation.PutOperation.runInternal(PutOperation.java:36) at com.hazelcast.map.impl.operation.MapOperation.run(MapOperation.java:112) at com.hazelcast.spi.impl.operationservice.Operation.call(Operation.java:184) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.call(OperationRunnerImpl.java:227) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:216) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:422) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:166) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:136) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.executeRun(OperationThread.java:123) at com.hazelcast.internal.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:102) ``` And the stacktrace of the same run for the client: ``` java.lang.RuntimeException: here comes the bug at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627) at com.hazelcast.internal.util.ExceptionUtil.tryWrapInSameClass(ExceptionUtil.java:233) at com.hazelcast.internal.util.ExceptionUtil.wrapException(ExceptionUtil.java:138) at com.hazelcast.internal.util.ExceptionUtil.peel(ExceptionUtil.java:114) at com.hazelcast.internal.util.ExceptionUtil.peel(ExceptionUtil.java:120) at com.hazelcast.internal.util.ExceptionUtil.peel(ExceptionUtil.java:73) at com.hazelcast.internal.util.ExceptionUtil.rethrow(ExceptionUtil.java:148) at com.hazelcast.client.impl.spi.ClientProxy.invokeOnPartition(ClientProxy.java:190) at com.hazelcast.client.impl.spi.ClientProxy.invoke(ClientProxy.java:182) at com.hazelcast.client.impl.proxy.ClientMapProxy.putInternal(ClientMapProxy.java:529) at com.hazelcast.client.impl.proxy.ClientMapProxy.put(ClientMapProxy.java:261) at XNode.onClient(XNode.java:41) at XNode.main(XNode.java:15) Caused by: java.lang.RuntimeException: here comes the bug at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627) at com.hazelcast.internal.util.ExceptionUtil.tryWrapInSameClass(ExceptionUtil.java:233) at com.hazelcast.internal.util.ExceptionUtil.wrapException(ExceptionUtil.java:138) at com.hazelcast.internal.util.ExceptionUtil.peel(ExceptionUtil.java:114) at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.peelIfNeeded(AbstractMessageTask.java:348) at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.encodeException(AbstractMessageTask.java:275) at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.sendClientMessage(AbstractMessageTask.java:269) at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.handleProcessingFailure(AbstractMessageTask.java:194) at com.hazelcast.client.impl.protocol.task.AbstractAsyncMessageTask.sendResponseOrHandleFailure(AbstractAsyncMessageTask.java:84) at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774) at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750) at java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:456) at com.hazelcast.internal.util.ConcurrencyUtil$1.execute(ConcurrencyUtil.java:39) at java.util.concurrent.CompletableFuture$UniCompletion.claim(CompletableFuture.java:543) at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:765) at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750) at java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:795) at java.util.concurrent.CompletableFuture.whenCompleteAsync(CompletableFuture.java:2163) at com.hazelcast.client.impl.protocol.task.AbstractAsyncMessageTask.processMessage(AbstractAsyncMessageTask.java:73) at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.initializeAndProcessMessage(AbstractMessageTask.java:153) at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.run(AbstractMessageTask.java:116) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:180) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:172) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:140) at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.executeRun(OperationThread.java:123) at com.hazelcast.internal.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:102) Caused by: java.lang.RuntimeException: here comes the bug at com.hazelcast.map.impl.operation.PutOperation.runInternal(PutOperation.java:36) at com.hazelcast.map.impl.operation.MapOperation.run(MapOperation.java:112) at com.hazelcast.spi.impl.operationservice.Operation.call(Operation.java:184) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.call(OperationRunnerImpl.java:227) at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:216) at com.hazelcast.spi.impl.operationexecutor.impl.OperationExecutorImpl.run(OperationExecutorImpl.java:411) at com.hazelcast.spi.impl.operationexecutor.impl.OperationExecutorImpl.runOrExecute(OperationExecutorImpl.java:438) at com.hazelcast.spi.impl.operationservice.impl.Invocation.doInvokeLocal(Invocation.java:597) at com.hazelcast.spi.impl.operationservice.impl.Invocation.doInvoke(Invocation.java:582) at com.hazelcast.spi.impl.operationservice.impl.Invocation.invoke0(Invocation.java:541) at com.hazelcast.spi.impl.operationservice.impl.Invocation.invoke(Invocation.java:238) at com.hazelcast.spi.impl.operationservice.impl.InvocationBuilderImpl.invoke(InvocationBuilderImpl.java:59) at com.hazelcast.client.impl.protocol.task.AbstractPartitionMessageTask.processInternal(AbstractPartitionMessageTask.java:51) at com.hazelcast.client.impl.protocol.task.AbstractAsyncMessageTask.processMessage(AbstractAsyncMessageTask.java:71) ... 7 more ``` fixes https://github.com/hazelcast/hazelcast/issues/17202 (cherry picked from commit 5b225d0ae19571c74ba35decc321fa97c81a7ed6) --- .../internal/util/ExceptionUtil.java | 59 ++++++++++++++++++- .../spi/impl/AbstractInvocationFuture.java | 52 ++-------------- 2 files changed, 60 insertions(+), 51 deletions(-) diff --git a/hazelcast/src/main/java/com/hazelcast/internal/util/ExceptionUtil.java b/hazelcast/src/main/java/com/hazelcast/internal/util/ExceptionUtil.java index 80eb3fb414e8..5d0903b404a4 100644 --- a/hazelcast/src/main/java/com/hazelcast/internal/util/ExceptionUtil.java +++ b/hazelcast/src/main/java/com/hazelcast/internal/util/ExceptionUtil.java @@ -19,10 +19,14 @@ import com.hazelcast.core.HazelcastException; import com.hazelcast.instance.impl.OutOfMemoryErrorDispatcher; import com.hazelcast.logging.ILogger; +import com.hazelcast.spi.impl.operationservice.WrappableException; import javax.annotation.Nonnull; import java.io.PrintWriter; import java.io.StringWriter; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.InvocationTargetException; import java.util.concurrent.ExecutionException; import java.util.function.BiConsumer; @@ -33,6 +37,14 @@ */ public final class ExceptionUtil { + private static final MethodHandles.Lookup LOOKUP = MethodHandles.publicLookup(); + // new Throwable(String message, Throwable cause) + private static final MethodType MT_INIT_STRING_THROWABLE = MethodType.methodType(void.class, String.class, Throwable.class); + // new Throwable(Throwable cause) + private static final MethodType MT_INIT_THROWABLE = MethodType.methodType(void.class, Throwable.class); + // new Throwable(String message) + private static final MethodType MT_INIT_STRING = MethodType.methodType(void.class, String.class); + private static final BiFunction HAZELCAST_EXCEPTION_WRAPPER = (throwable, message) -> { if (message != null) { return new HazelcastException(message, throwable); @@ -99,7 +111,7 @@ public static Throwable peel(final Throwable t, Class a public static Throwable peel(final Throwable t, Class allowedType, String message, BiFunction exceptionWrapper) { if (t instanceof RuntimeException) { - return t; + return wrapException(t, message, exceptionWrapper); } if (t instanceof ExecutionException || t instanceof InvocationTargetException) { @@ -118,7 +130,20 @@ public static Throwable peel(final Throwable t, Class Throwable wrapException(Throwable t, String message, + BiFunction exceptionWrapper) { + if (t instanceof WrappableException) { + return ((WrappableException) t).wrap(); + } + Throwable wrapped = tryWrapInSameClass(t); + return wrapped == null ? exceptionWrapper.apply(t, message) : wrapped; + } + + public static RuntimeException wrapException(RuntimeException t) { + return (RuntimeException) wrapException(t, null, HAZELCAST_EXCEPTION_WRAPPER); + } + + public static RuntimeException rethrow(final Throwable t) { rethrowIfError(t); throw peel(t); } @@ -151,10 +176,15 @@ public static void rethrowIfError(final Throwable t) { if (t instanceof OutOfMemoryError) { OutOfMemoryErrorDispatcher.onOutOfMemory((OutOfMemoryError) t); } - throw (Error) t; + throw wrapError((Error) t); } } + public static Error wrapError(Error cause) { + Error result = tryWrapInSameClass(cause); + return result == null ? cause : result; + } + public static RuntimeException rethrowAllowInterrupted(final Throwable t) throws InterruptedException { return rethrow(t, InterruptedException.class); } @@ -194,4 +224,27 @@ public static RuntimeException sneakyThrow(@Nonnull Throwa } }; } + + public static T tryWrapInSameClass(T cause) { + Class exceptionClass = cause.getClass(); + MethodHandle constructor; + try { + constructor = LOOKUP.findConstructor(exceptionClass, MT_INIT_STRING_THROWABLE); + return (T) constructor.invokeWithArguments(cause.getMessage(), cause); + } catch (Throwable ignored) { + } + try { + constructor = LOOKUP.findConstructor(exceptionClass, MT_INIT_THROWABLE); + return (T) constructor.invokeWithArguments(cause); + } catch (Throwable ignored) { + } + try { + constructor = LOOKUP.findConstructor(exceptionClass, MT_INIT_STRING); + T result = (T) constructor.invokeWithArguments(cause.getMessage()); + result.initCause(cause); + return result; + } catch (Throwable ignored) { + } + return null; + } } diff --git a/hazelcast/src/main/java/com/hazelcast/spi/impl/AbstractInvocationFuture.java b/hazelcast/src/main/java/com/hazelcast/spi/impl/AbstractInvocationFuture.java index 35e9e77830d0..690eb886224d 100644 --- a/hazelcast/src/main/java/com/hazelcast/spi/impl/AbstractInvocationFuture.java +++ b/hazelcast/src/main/java/com/hazelcast/spi/impl/AbstractInvocationFuture.java @@ -22,15 +22,10 @@ import com.hazelcast.instance.impl.OutOfMemoryErrorDispatcher; import com.hazelcast.internal.util.executor.UnblockableThread; import com.hazelcast.logging.ILogger; -import com.hazelcast.spi.impl.operationservice.WrappableException; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodHandles.Lookup; -import java.lang.invoke.MethodType; import java.lang.reflect.InvocationTargetException; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; @@ -51,6 +46,8 @@ import static com.hazelcast.internal.util.ConcurrencyUtil.DEFAULT_ASYNC_EXECUTOR; import static com.hazelcast.internal.util.ExceptionUtil.sneakyThrow; +import static com.hazelcast.internal.util.ExceptionUtil.wrapError; +import static com.hazelcast.internal.util.ExceptionUtil.wrapException; import static java.util.Objects.requireNonNull; import static java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater; import static java.util.concurrent.locks.LockSupport.park; @@ -59,6 +56,7 @@ /** * Custom implementation of {@link java.util.concurrent.CompletableFuture}. + * * @param */ @SuppressFBWarnings(value = "DLS_DEAD_STORE_OF_CLASS_LITERAL", justification = "Recommended way to prevent classloading bug") @@ -71,13 +69,6 @@ public String toString() { return "UNRESOLVED"; } }; - private static final Lookup LOOKUP = MethodHandles.publicLookup(); - // new Throwable(String message, Throwable cause) - private static final MethodType MT_INIT_STRING_THROWABLE = MethodType.methodType(void.class, String.class, Throwable.class); - // new Throwable(Throwable cause) - private static final MethodType MT_INIT_THROWABLE = MethodType.methodType(void.class, Throwable.class); - // new Throwable(String message) - private static final MethodType MT_INIT_STRING = MethodType.methodType(void.class, String.class); private static final AtomicReferenceFieldUpdater STATE_UPDATER = newUpdater(AbstractInvocationFuture.class, Object.class, "state"); @@ -1912,7 +1903,7 @@ static Throwable wrapOrPeel(Throwable cause) { return cause; } if (cause instanceof RuntimeException) { - return wrapRuntimeException((RuntimeException) cause); + return wrapException((RuntimeException) cause); } if ((cause instanceof ExecutionException || cause instanceof InvocationTargetException) && cause.getCause() != null) { @@ -1927,39 +1918,4 @@ static Throwable wrapOrPeel(Throwable cause) { return new HazelcastException(cause); } - private static RuntimeException wrapRuntimeException(RuntimeException cause) { - if (cause instanceof WrappableException) { - return ((WrappableException) cause).wrap(); - } - RuntimeException wrapped = tryWrapInSameClass(cause); - return wrapped == null ? new HazelcastException(cause) : wrapped; - } - - private static Error wrapError(Error cause) { - Error result = tryWrapInSameClass(cause); - return result == null ? cause : result; - } - - private static T tryWrapInSameClass(T cause) { - Class exceptionClass = cause.getClass(); - MethodHandle constructor; - try { - constructor = LOOKUP.findConstructor(exceptionClass, MT_INIT_STRING_THROWABLE); - return (T) constructor.invokeWithArguments(cause.getMessage(), cause); - } catch (Throwable ignored) { - } - try { - constructor = LOOKUP.findConstructor(exceptionClass, MT_INIT_THROWABLE); - return (T) constructor.invokeWithArguments(cause); - } catch (Throwable ignored) { - } - try { - constructor = LOOKUP.findConstructor(exceptionClass, MT_INIT_STRING); - T result = (T) constructor.invokeWithArguments(cause.getMessage()); - result.initCause(cause); - return result; - } catch (Throwable ignored) { - } - return null; - } } From 31783560bca6566ed621e7ec5bf8942244c24808 Mon Sep 17 00:00:00 2001 From: sancar Date: Tue, 14 Jul 2020 13:01:35 +0300 Subject: [PATCH 2/2] test fixes (cherry picked from commit da89fbac81f3ce024f27843ecf64c69b0d0973ef) --- .../client/HazelcastClientOfflineException.java | 4 ++++ .../ringbuffer/StaleSequenceException.java | 11 ++++++++++- .../ClientUserCodeDeploymentExceptionTest.java | 13 +++---------- .../hazelcast/internal/util/ExceptionUtilTest.java | 6 ++++-- ...WriteBehind_whenNoCoalescingQueueIsFullTest.java | 2 -- .../impl/DistributedObjectFutureTest.java | 2 +- 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/hazelcast/src/main/java/com/hazelcast/client/HazelcastClientOfflineException.java b/hazelcast/src/main/java/com/hazelcast/client/HazelcastClientOfflineException.java index f3e2366a08d2..96d5b66d80c0 100644 --- a/hazelcast/src/main/java/com/hazelcast/client/HazelcastClientOfflineException.java +++ b/hazelcast/src/main/java/com/hazelcast/client/HazelcastClientOfflineException.java @@ -24,4 +24,8 @@ public class HazelcastClientOfflineException extends IllegalStateException { public HazelcastClientOfflineException() { super("No connection found to cluster"); } + + public HazelcastClientOfflineException(Throwable cause) { + super(cause); + } } diff --git a/hazelcast/src/main/java/com/hazelcast/ringbuffer/StaleSequenceException.java b/hazelcast/src/main/java/com/hazelcast/ringbuffer/StaleSequenceException.java index 2039004fb54f..0c2b130ca5e4 100644 --- a/hazelcast/src/main/java/com/hazelcast/ringbuffer/StaleSequenceException.java +++ b/hazelcast/src/main/java/com/hazelcast/ringbuffer/StaleSequenceException.java @@ -17,13 +17,15 @@ package com.hazelcast.ringbuffer; import com.hazelcast.spi.exception.SilentException; +import com.hazelcast.spi.impl.operationservice.WrappableException; /** * An {@link RuntimeException} that is thrown when accessing an item in the {@link Ringbuffer} using a sequence that is smaller * than the current head sequence and that the ringbuffer store is disabled. This means that the item isn't available in the * ringbuffer and it cannot be loaded from the store either, thus being completely unavailable. */ -public class StaleSequenceException extends RuntimeException implements SilentException { +public class StaleSequenceException extends RuntimeException + implements SilentException, WrappableException { private final long headSeq; @@ -47,4 +49,11 @@ public StaleSequenceException(String message, long headSeq) { public long getHeadSeq() { return headSeq; } + + @Override + public StaleSequenceException wrap() { + StaleSequenceException staleSequenceException = new StaleSequenceException(getMessage(), headSeq); + staleSequenceException.initCause(this); + return staleSequenceException; + } } diff --git a/hazelcast/src/test/java/com/hazelcast/client/usercodedeployment/ClientUserCodeDeploymentExceptionTest.java b/hazelcast/src/test/java/com/hazelcast/client/usercodedeployment/ClientUserCodeDeploymentExceptionTest.java index d4b945f10384..55b5b1d4f6c3 100644 --- a/hazelcast/src/test/java/com/hazelcast/client/usercodedeployment/ClientUserCodeDeploymentExceptionTest.java +++ b/hazelcast/src/test/java/com/hazelcast/client/usercodedeployment/ClientUserCodeDeploymentExceptionTest.java @@ -22,13 +22,13 @@ import com.hazelcast.config.Config; import com.hazelcast.core.HazelcastException; import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.internal.util.FilteringClassLoader; import com.hazelcast.map.IMap; import com.hazelcast.nio.serialization.HazelcastSerializationException; import com.hazelcast.test.HazelcastParallelClassRunner; import com.hazelcast.test.HazelcastTestSupport; import com.hazelcast.test.annotation.ParallelJVMTest; import com.hazelcast.test.annotation.QuickTest; -import com.hazelcast.internal.util.FilteringClassLoader; import org.junit.After; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -38,8 +38,6 @@ import java.io.FileNotFoundException; import static java.util.Collections.singletonList; -import static junit.framework.TestCase.fail; -import static org.junit.Assert.assertEquals; @RunWith(HazelcastParallelClassRunner.class) @Category({QuickTest.class, ParallelJVMTest.class}) @@ -52,7 +50,7 @@ public void tearDown() throws Exception { factory.terminateAll(); } - @Test + @Test(expected = HazelcastSerializationException.class) public void testUserCodeDeploymentIsDisabledByDefaultOnClient() { // this test also validate the EP is filtered locally and has to be loaded from the other member ClientConfig clientConfig = new ClientConfig(); @@ -64,12 +62,7 @@ public void testUserCodeDeploymentIsDisabledByDefaultOnClient() { HazelcastInstance client = factory.newHazelcastClient(clientConfig); IMap map = client.getMap(randomName()); - try { - map.executeOnEntries(incrementingEntryProcessor); - fail(); - } catch (HazelcastSerializationException e) { - assertEquals(ClassNotFoundException.class, e.getCause().getClass()); - } + map.executeOnEntries(incrementingEntryProcessor); } private Config createNodeConfig() { diff --git a/hazelcast/src/test/java/com/hazelcast/internal/util/ExceptionUtilTest.java b/hazelcast/src/test/java/com/hazelcast/internal/util/ExceptionUtilTest.java index 3af582c9b19e..30a980364405 100644 --- a/hazelcast/src/test/java/com/hazelcast/internal/util/ExceptionUtilTest.java +++ b/hazelcast/src/test/java/com/hazelcast/internal/util/ExceptionUtilTest.java @@ -54,14 +54,16 @@ public void testToString() { public void testPeel_whenThrowableIsRuntimeException_thenReturnOriginal() { RuntimeException result = ExceptionUtil.peel(throwable); - assertEquals(throwable, result); + assertEquals(throwable.getMessage(), result.getMessage()); + assertEquals(throwable.getClass(), result.getClass()); } @Test public void testPeel_whenThrowableIsExecutionException_thenReturnCause() { RuntimeException result = ExceptionUtil.peel(new ExecutionException(throwable)); - assertEquals(throwable, result); + assertEquals(throwable.getMessage(), result.getMessage()); + assertEquals(throwable.getClass(), result.getClass()); } @Test diff --git a/hazelcast/src/test/java/com/hazelcast/map/impl/mapstore/writebehind/TransactionsWithWriteBehind_whenNoCoalescingQueueIsFullTest.java b/hazelcast/src/test/java/com/hazelcast/map/impl/mapstore/writebehind/TransactionsWithWriteBehind_whenNoCoalescingQueueIsFullTest.java index 845d11957ffe..cc1e99b137a3 100644 --- a/hazelcast/src/test/java/com/hazelcast/map/impl/mapstore/writebehind/TransactionsWithWriteBehind_whenNoCoalescingQueueIsFullTest.java +++ b/hazelcast/src/test/java/com/hazelcast/map/impl/mapstore/writebehind/TransactionsWithWriteBehind_whenNoCoalescingQueueIsFullTest.java @@ -55,7 +55,6 @@ import static com.hazelcast.transaction.TransactionOptions.TransactionType.ONE_PHASE; import static com.hazelcast.transaction.TransactionOptions.TransactionType.TWO_PHASE; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.hamcrest.core.Is.isA; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -69,7 +68,6 @@ public class TransactionsWithWriteBehind_whenNoCoalescingQueueIsFullTest extends @Test public void prepare_step_throws_reached_max_size_exception_when_two_phase() { expectedException.expect(TransactionException.class); - expectedException.expectCause(isA(ReachedMaxSizeException.class)); String mapName = "map"; long maxWbqCapacity = 100; diff --git a/hazelcast/src/test/java/com/hazelcast/spi/impl/proxyservice/impl/DistributedObjectFutureTest.java b/hazelcast/src/test/java/com/hazelcast/spi/impl/proxyservice/impl/DistributedObjectFutureTest.java index fead90f3e1c7..8599559ee075 100644 --- a/hazelcast/src/test/java/com/hazelcast/spi/impl/proxyservice/impl/DistributedObjectFutureTest.java +++ b/hazelcast/src/test/java/com/hazelcast/spi/impl/proxyservice/impl/DistributedObjectFutureTest.java @@ -89,7 +89,7 @@ public void get_throwsGivenException_whenUncheckedExceptionSet() throws Exceptio try { future.get(); } catch (Exception e) { - assertSame(error, e); + assertSame(error.getClass(), e.getClass()); } }