Can't pass exceptions with Java 7 : java.lang.Throwable.suppressedExceptions
Thomas Leonard <tal-v5nx5w6akNyLE8xUarVfuPLx9OUvmyODWmv/[email protected]> Mon, 14 May 2012 15:54:56 +0100
| Newsgroups | gmane.comp.lang.e.general |
|---|---|
| Message-ID | <[email protected]> |
With Java 7, Throwables can no longer be sent successfully over CapTP. The
error is:
=== 2012-05-14T14:44:15.109Z
(CapTPConnection.whyNoDeliverOnlyOp:CapTPConnection.java:837) WRN
captp: whyNoDeliverOnlyOp(4, run, java.lang.ClassCastException: cannot
assign instance of org.erights.e.elib.ref.OldFarRef to field
java.lang.Throwable.suppressedExceptions of type java.util.List in instance
of java.lang.ClassCastException)
--vvvv--
cannot assign instance of org.erights.e.elib.ref.OldFarRef to field
java.lang.Throwable.suppressedExceptions of type java.util.List in instance
of java.lang.ClassCastException
java.lang.ClassCastException: cannot assign instance of
org.erights.e.elib.ref.OldFarRef to field
java.lang.Throwable.suppressedExceptions of type java.util.List in instance
of java.lang.ClassCastException
at
java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2063)
at
java.io.ObjectStreamClass.setObjFieldValues(ObjectStreamClass.java:1241)
at
java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1970)
at
java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:498)
at java.lang.Throwable.readObject(Throwable.java:913)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at
java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1004)
at
java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
at
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at
java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at
java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1685)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1341)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at net.captp.jcomm.CapTPConnection.receiveMsg(CapTPConnection.java:741)
at
net.captp.jcomm.CapTPConnection.processMessage(CapTPConnection.java:724)
at
net.vattp.data.VatTPConnection.newIncomingMsg(VatTPConnection.java:727)
at net.vattp.data.DataPath.newIncomingMsg(DataPath.java:699)
at net.vattp.data.DataCommThunk.run(DataCommThunk.java:207)
at org.erights.e.elib.vat.PendingCall.innerRun(PendingCall.java:75)
at org.erights.e.elib.vat.PendingEvent.run(PendingEvent.java:74)
at org.erights.e.elib.vat.HeadlessRunner.run(HeadlessRunner.java:174)
at java.lang.Thread.run(Thread.java:722)
--^^^^--
The problem seems to be the new list of "suppressed" exceptions attached to
each Throwable:
http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#getSuppressed%28%29
CapTPReplacer turns this into a far ref (presumably on the assumption that
the list may be mutable), but the Throwable created at the destination needs
a List, not a far ref.
I assume there's some mechanism to handle things like this (since
getStackTrace(), which also returns an array, works fine).
This hack fixes it, but I'm not sure it's right in general ("unmodifiable"
seems to mean "read-only" rather than "const"):
(in CapTPReplacer.substitute)
if (ref.getClass().getName().equals("java.util.Collections$UnmodifiableList")) {
return null;
}
Suggestions?
--
Dr Thomas Leonard
IT Innovation Centre
Gamma House, Enterprise Road,
Southampton SO16 7NS, UK
tel: +44 23 8059 8866
mailto:tal-v5nx5w6akNyLE8xUarVfuPLx9OUvmyODWmv/[email protected]
http://www.it-innovation.soton.ac.uk/