This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 06cc126dc9 Fix intermittent test failure on Java 21
06cc126dc9 is described below

commit 06cc126dc990b731fa5f0cec618a4f0c95b911e9
Author: James Bognar <[email protected]>
AuthorDate: Fri Feb 6 08:12:00 2026 -0500

    Fix intermittent test failure on Java 21
---
 .../main/java/org/apache/juneau/commons/utils/Utils.java | 12 +++++++-----
 .../java/org/apache/juneau/commons/utils/Utils_Test.java | 16 ++++++++++++----
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/Utils.java
 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/Utils.java
index c280f71292..93ff36076a 100644
--- 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/Utils.java
+++ 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/Utils.java
@@ -1809,12 +1809,13 @@ public class Utils {
         * @param s The supplier that may throw an exception.
         * @return The result of the supplier execution.
         */
+       @SuppressWarnings("java:S1181") // Need to catch Throwable to handle 
all exception types including Error
        public static <T> T safe(ThrowingSupplier<T> s) {
                try {
                        return s.get();
                } catch (RuntimeException e) {
                        throw e;
-               } catch (Exception e) {
+               } catch (Exception | Error e) {
                        throw rex(e);
                }
        }
@@ -1840,16 +1841,17 @@ public class Utils {
         *
         * @param <T> The return type.
         * @param s The supplier that may throw an exception.
-        * @param exceptionMapper A function that converts the thrown exception 
into a runtime exception.
+        * @param exceptionMapper A function that converts the thrown exception 
or error into a runtime exception.
         * @return The result of the supplier execution.
-        * @throws RuntimeException The exception returned by the exception 
mapper if the supplier throws an exception.
+        * @throws RuntimeException The exception returned by the exception 
mapper if the supplier throws an exception or error.
         */
-       public static <T> T safe(ThrowingSupplier<T> s, Function<Exception, 
RuntimeException> exceptionMapper) {
+       @SuppressWarnings("java:S1181") // Need to catch Throwable to handle 
all exception types including Error
+       public static <T> T safe(ThrowingSupplier<T> s, Function<Throwable, 
RuntimeException> exceptionMapper) {
                try {
                        return s.get();
                } catch (RuntimeException e) {
                        throw e;
-               } catch (Exception e) {
+               } catch (Exception | Error e) {
                        throw exceptionMapper.apply(e);
                }
        }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/utils/Utils_Test.java 
b/juneau-utest/src/test/java/org/apache/juneau/commons/utils/Utils_Test.java
index 10449d24f4..966f59e4d0 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/commons/utils/Utils_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/commons/utils/Utils_Test.java
@@ -934,13 +934,13 @@ class Utils_Test extends TestBase {
        }
 
        
//====================================================================================================
-       // safe(ThrowingSupplier<T>, Function<Exception, RuntimeException>)
+       // safe(ThrowingSupplier<T>, Function<Throwable, RuntimeException>)
        
//====================================================================================================
        @Test
        void a051_safe_ThrowingSupplier_withExceptionMapper() {
                // Test normal execution
                ThrowingSupplier<String> supplier1 = () -> "result";
-               Function<Exception, RuntimeException> mapper1 = e -> new 
RuntimeException("mapped: " + e.getMessage());
+               Function<Throwable, RuntimeException> mapper1 = e -> new 
RuntimeException("mapped: " + e.getMessage());
                String result = Utils.safe(supplier1, mapper1);
                assertEquals("result", result);
 
@@ -948,7 +948,7 @@ class Utils_Test extends TestBase {
                ThrowingSupplier<String> supplier2 = () -> {
                        throw new RuntimeException("original");
                };
-               Function<Exception, RuntimeException> mapper2 = e -> new 
RuntimeException("mapped: " + e.getMessage());
+               Function<Throwable, RuntimeException> mapper2 = e -> new 
RuntimeException("mapped: " + e.getMessage());
                var re = assertThrows(RuntimeException.class, () -> 
Utils.safe(supplier2, mapper2));
                assertEquals("original", re.getMessage());
 
@@ -956,11 +956,19 @@ class Utils_Test extends TestBase {
                ThrowingSupplier<String> supplier3 = () -> {
                        throw new Exception("test exception");
                };
-               Function<Exception, RuntimeException> mapper3 = e -> new 
IllegalArgumentException("custom: " + e.getMessage());
+               Function<Throwable, RuntimeException> mapper3 = e -> new 
IllegalArgumentException("custom: " + e.getMessage());
                var mapped = assertThrows(RuntimeException.class, () -> 
Utils.safe(supplier3, mapper3));
                assertEquals("custom: test exception", mapped.getMessage());
                assertTrue(mapped instanceof IllegalArgumentException);
 
+               // Test Error (e.g., InternalError from Java 21+ reflection 
operations) is mapped
+               ThrowingSupplier<String> supplier4 = () -> {
+                       throw new InternalError("test error");
+               };
+               Function<Throwable, RuntimeException> mapper4 = e -> new 
RuntimeException("error mapped: " + e.getMessage());
+               var errorMapped = assertThrows(RuntimeException.class, () -> 
Utils.safe(supplier4, mapper4));
+               assertEquals("error mapped: test error", 
errorMapped.getMessage());
+
                // Test with custom exception type
                @SuppressWarnings("serial")
                class CustomRuntimeException extends RuntimeException {

Reply via email to