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

Reply via email to