RFR: jsr166 jdk9 integration wave 2
Peter Levart
peter.levart at gmail.com
Thu Dec 3 09:22:02 UTC 2015
Hi Martin,
On 12/03/2015 01:51 AM, Martin Buchholz wrote:
> We're stuck. Peter wants to make Throwables cloneable, I want to
> reverse the order of throwables and add the past Throwable as a
> suppressed exception to the exception of a dependent action, and Doug
> wants the current webrev behavior of adding the dependent action as a
> suppressed exception of the source.
>
> I'm willing to accept the small incompatibility of throwing a
> different exception when everything fails; the existing spec doesn't
> promise what happens in this case.
As said in the other thread, I don't want to delay the changes to
CompletableFuture with the support for cloning of exception. If this
ever gets accepted (and probably won't) the CompletableFuture and
ForkJoinTask could be revisited.
I see we have 3 options now for CompletableFuture:
- do nothing (ignore whenComplete exception when previous stage
completes exceptionally too)
- add whenComplete exception to the exception from previous stage (as
proposed currently in wave 2) which is thread-safe, but modifies the
exceptional outcome of previous stage after it has already completed and
thus could non-deterministically change the behavior of existing code
(very unlikely, but possible).
- add the exception from previous stage to whenComplete exception (as
endorsed by Martin) which changes the behavior and bends the spec. a little
What about the 4th option (keep current behavior, but try the
best-effort with reflection to make new exception of the same type):
...
} catch (Throwable ex) {
if (x == null) {
x = ex;
} else {
// try to create new exception with same:
// type, cause, suppressed exceptions and
stack-trace...
Throwable nx;
Class<?> xClass = x.getClass();
try {
Constructor<?> xConstr =
xClass.getConstructor(Throwable.class);
nx = (Throwable) xConstr.newInstance(x.getCause());
} catch (Exception e1) {
try {
nx = (Throwable) xClass.newInstance();
nx.initCause(x.getCause());
} catch (Exception e2) {
// no luck
nx = null;
}
}
if (nx != null) {
// inherit stack-trace of original exception
nx.setStackTrace(x.getStackTrace());
// inherit suppressed exceptions
for (Throwable sx : x.getSuppressed()) {
nx.addSuppressed(sx);
}
// add 'ex' as a final suppressed exception
nx.addSuppressed(ex);
x = nx;
}
}
}
completeThrowable(x, r);
...
Note that such code and similar code in
ForkJoinTask.getThrowableException will probably have to be modified for
jigsaw to include dynamic addition of read-edge to the module of
exception class...
Regards, Peter
More information about the core-libs-dev
mailing list