Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -29,6 +29,9 @@
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Set;
import java.util.stream.IntStream;
import jdk.jshell.spi.ExecutionControl;
import jdk.jshell.spi.SPIResolutionException;
Expand Down Expand Up @@ -335,10 +338,15 @@ private static boolean needsEscape(int idx, int cp) {
* @throws ExecutionControl.InternalException for internal problems
*/
protected String throwConvertedInvocationException(Throwable cause) throws RunException, InternalException {
throw asRunException(cause);
// Guard against recursive cause chains by
// using a Set with identity equality semantics.
Set<Throwable> dejaVu = Collections.newSetFromMap(new IdentityHashMap<>());
dejaVu.add(cause);

throw asRunException(cause, dejaVu);
}

private RunException asRunException(Throwable ex) {
private RunException asRunException(Throwable ex, Set<Throwable> dejaVu) {
if (ex instanceof SPIResolutionException) {
SPIResolutionException spire = (SPIResolutionException) ex;
return new ResolutionException(spire.id(), spire.getStackTrace());
Expand All @@ -347,7 +355,14 @@ private RunException asRunException(Throwable ex) {
ex.getClass().getName(),
ex.getStackTrace());
Throwable cause = ex.getCause();
ue.initCause(cause == null ? null : asRunException(cause));
if (cause != null) {
Throwable throwable = dejaVu.add(cause)
? asRunException(cause, dejaVu)
: new UserException("CIRCULAR REFERENCE!",
cause.getClass().getName(),
cause.getStackTrace());
ue.initCause(throwable);
}
return ue;
}
}
Expand Down
12 changes: 11 additions & 1 deletion test/langtools/jdk/jshell/ExceptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
/*
* @test
* @summary Tests for exceptions
* @bug 8198801 8212167 8210527
* @bug 8198801 8212167 8210527 8370175
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.javap
Expand Down Expand Up @@ -320,6 +320,16 @@ public void stackOverflow() {
assertExecuteException("f();", StackOverflowError.class);
}

@Test
public void recursiveCauses() {
assertEval("var one = new Throwable();");
assertEval("var two = new Error();");
assertEval("one.initCause(two);");
assertEval("two.initCause(one);");
assertExecuteException("throw one;", Throwable.class);
assertExecuteException("throw two;", Error.class);
}

private StackTraceElement newStackTraceElement(String className, String methodName, Snippet key, int lineNumber) {
return new StackTraceElement(className, methodName, "#" + key.id(), lineNumber);
}
Expand Down