diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/UserCodeException.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/UserCodeException.java index 14443a43f9da..ad1cd8bd85b7 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/UserCodeException.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/UserCodeException.java @@ -62,13 +62,17 @@ private UserCodeException(Throwable t) { * of the current thread. */ private void truncateStackTrace(Throwable t) { - StackTraceElement[] currentStack = Thread.currentThread().getStackTrace(); StackTraceElement[] throwableStack = t.getStackTrace(); int currentStackSize = currentStack.length; int throwableStackSize = throwableStack.length; + if (throwableStackSize == 0) { + // Nothing to truncate. + return; + } + int commonFrames = 0; while (framesEqual(currentStack[currentStackSize - commonFrames - 1], throwableStack[throwableStackSize - commonFrames - 1])) { diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/util/UserCodeExceptionTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/util/UserCodeExceptionTest.java index 614c72f913a8..3be114605928 100644 --- a/sdks/java/core/src/test/java/org/apache/beam/sdk/util/UserCodeExceptionTest.java +++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/util/UserCodeExceptionTest.java @@ -96,6 +96,13 @@ public void testWrapIfReturnsSourceRuntimeExceptionWhenFalse() { assertEquals(runtimeException, wrapped); } + @Test + public void robustAgainstEmptyStackTrace() { + RuntimeException runtimeException = new RuntimeException("empty stack"); + runtimeException.setStackTrace(new StackTraceElement[0]); + RuntimeException wrapped = UserCodeException.wrap(runtimeException); + assertEquals(runtimeException, wrapped.getCause()); + } private void throwUserCodeException() { try {