RFR: jsr166 jdk9 integration wave 2

Jason Mehrens jason_mehrens at hotmail.com
Thu Dec 3 17:54:53 UTC 2015


Hi Peter,

I've done this trick before to perform Throwable cloning.  You have to hunt for the constructors in this order:
1. Walk the type of the cause and super types by calling getConstructor(String, type of cause). (java.io.WriteAbortedException and javax.mail.MessagingException)
2. Walk the type of the cause and super types by calling getConstructor(type of cause, String)  (I've seen this but, I can't seem to find an example)
3. getConstructor(String) + initCause (java.io.InvalidObjectException)
4. Walk the type of the cause and super types by calling getConstructor(type of cause). (java.awt.print.PrinterIOException)
5. getConstructor() + initCause.  (java.nio.BufferOverflowException)
6. Look at the return type of methods declared in the cause type and assume there is a constructor matching the type or no repeating types. (java.nio.charset.MalformedInputException, java.lang.EnumConstantNotPresentException, java.util.regex.PatternSyntaxException)

In the end all of that can still fail.  Exceptions can be private subclasses of public classes so that gets interesting with reflection too.

Jason


===========
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