private static RemoteExceptionCause of(Throwable t, IdentityHashMap<Throwable, RemoteExceptionCause> seen) { if (t == null) return null; if (t instanceof RemoteExceptionCause) { return (RemoteExceptionCause) t; } else { final RemoteExceptionCause existing = seen.get(t); if (existing != null) { return existing; } final RemoteExceptionCause e = new RemoteExceptionCause(t.getMessage(), t.getClass().getName(), fieldGetterValue.get(t.getClass()).apply(t)); e.setStackTrace(t.getStackTrace()); seen.put(t, e); final Throwable cause = t.getCause(); if (cause != null) e.initCause(of(cause, seen)); for (Throwable throwable : t.getSuppressed()) { e.addSuppressed(of(throwable, seen)); } return e; } }
private int writeThrowable(final DataOutput output, final Throwable throwable, final IdentityIntMap<Object> seen, final HashMap<String, String> stringCache, final int cnt) throws IOException { if (throwable == null) { output.write(ST_NULL); return cnt; } else { final int idx = seen.get(throwable, - 1); final int distance = cnt - idx; if (idx == - 1 || distance >= 0x4000) { RemoteExceptionCause nested; if (throwable instanceof RemoteExceptionCause) { nested = (RemoteExceptionCause) throwable; } else { seen.put(throwable, cnt); // do not increment yet nested = of(throwable); } return nested.writeToStream(output, seen, stringCache, cnt); // this will increment it } else { if (distance < 127) { output.writeByte(ST_BACKREF_NEAR | distance); } else { assert distance <= 0x3fff; output.writeByte(ST_BACKREF_FAR | distance >> 8); output.writeByte(distance); } return cnt; } } }
private int writeToStream(DataOutput output, IdentityIntMap<Object> seen, HashMap<String, String> stringCache, int cnt) throws IOException { // register in cycle map seen.put(this, cnt++); // write the header byte output.writeByte(ST_NEW_EXCEPTION_CAUSE); // first write class name cnt = writeString(output, exceptionClassName, seen, stringCache, cnt); // null or message cnt = writeString(output, getMessage(), seen, stringCache, cnt); // stack trace cnt = writeStackTrace(output, getStackTrace(), seen, stringCache, cnt); // fields cnt = writeFields(output, fields, seen, stringCache, cnt); // caused-by cnt = writeThrowable(output, getCause(), seen, stringCache, cnt); // suppressed final Throwable[] suppressed = getSuppressed(); writePackedInt(output, suppressed.length); for (final Throwable t : suppressed) { cnt = writeThrowable(output, t, seen, stringCache, cnt); } return cnt; }
/** * Convert this remote exception cause to a plain throwable for sending to peers which use serialization and do not * have this class present. Note that this does not recursively apply; normally, a serialization framework will * handle the recursive application of this operation through object resolution. * * @return the throwable (not {@code null}) */ public Throwable toPlainThrowable() { final Throwable throwable = new Throwable(toString(), getCause()); throwable.setStackTrace(getStackTrace()); for (Throwable s : getSuppressed()) { throwable.addSuppressed(s); } return throwable; }
Object writeReplace() { final Throwable[] origSuppressed = getSuppressed(); final int length = origSuppressed.length; final RemoteExceptionCause[] suppressed; if (length == 0) { suppressed = NO_REMOTE_EXCEPTION_CAUSES; } else { suppressed = new RemoteExceptionCause[length]; for (int i = 0; i < length; i ++) { suppressed[i] = of(origSuppressed[i]); } } String[] fieldArray; final int size = fields.size(); if (size == 0) { fieldArray = NO_STRINGS; } else { fieldArray = new String[size << 1]; int i = 0; for (Map.Entry<String, String> entry : fields.entrySet()) { fieldArray[i++] = entry.getKey(); fieldArray[i++] = entry.getValue(); } } return new Serialized(getMessage(), exceptionClassName, of(getCause()), suppressed, getStackTrace(), fieldArray); }
String exClassName = readObject(input, String.class, cache, false); String exMessage = readObject(input, String.class, cache, true); int length = readPackedInt(input); StackTraceElement[] stackTrace; if (length == 0) { stackTrace = new StackTraceElement[length]; for (int i = 0; i < length; i++) { stackTrace[i] = readObject(input, StackTraceElement.class, cache, false); length = readPackedInt(input); if (length == 0) { fields = Collections.emptyMap(); } else if (length == 1) { fields = Collections.singletonMap(readObject(input, String.class, cache, false), readObject(input, String.class, cache, false)); } else { fields = new HashMap<>(length); for (int i = 0; i < length; i++) { fields.put(readObject(input, String.class, cache, false), readObject(input, String.class, cache, false)); final RemoteExceptionCause result = new RemoteExceptionCause(exMessage, null, exClassName, fields, false); cache.set(idx, result); RemoteExceptionCause causedBy = readObject(input, RemoteExceptionCause.class, cache, true); result.initCause(causedBy); length = readPackedInt(input); result.setStackTrace(stackTrace); for (int i = 0; i < length; i++) { result.addSuppressed(readObject(input, RemoteExceptionCause.class, cache, false));
Object readResolve() { final Map<String, String> fields; if (f == null) { fields = Collections.emptyMap(); } else { final int fl = f.length; if ((fl & 1) != 0) { throw CommonMessages.msg.invalidOddFields(); } else if (fl == 0) { fields = Collections.emptyMap(); } else if (fl == 2) { fields = Collections.singletonMap(f[0], f[1]); } else { final TreeMap<String, String> map = new TreeMap<>(); for (int i = 0; i < fl; i += 2) { map.put(f[i], f[i + 1]); } fields = Collections.unmodifiableMap(map); } } final RemoteExceptionCause ex = new RemoteExceptionCause(m, c, cn, fields, false); ex.setStackTrace(st); final RemoteExceptionCause[] suppressed = s; if (suppressed != null) for (RemoteExceptionCause c : suppressed) { ex.addSuppressed(c); } return ex; } }
statusRef.set(Status.STATUS_UNKNOWN); final HeuristicMixedException e = Log.log.peerHeuristicMixedException(); e.initCause(RemoteExceptionCause.readFromStream(is)); throw e; } else if (id == Protocol.P_UT_HRE_EXC) { statusRef.set(Status.STATUS_UNKNOWN); final HeuristicRollbackException e = Log.log.peerHeuristicRollbackException(); e.initCause(RemoteExceptionCause.readFromStream(is)); throw e; } else if (id == Protocol.P_UT_IS_EXC) { statusRef.set(Status.STATUS_UNKNOWN); final IllegalStateException e = Log.log.peerIllegalStateException(); e.initCause(RemoteExceptionCause.readFromStream(is)); throw e; } else if (id == Protocol.P_UT_RB_EXC) { statusRef.set(Status.STATUS_ROLLEDBACK); final RollbackException e = Log.log.transactionRolledBackByPeer(); e.initCause(RemoteExceptionCause.readFromStream(is)); throw e; } else if (id == Protocol.P_UT_SYS_EXC) { final SystemException e = Log.log.peerSystemException(); e.errorCode = is.readInt(); e.initCause(RemoteExceptionCause.readFromStream(is)); throw e; } else if (id == Protocol.P_SEC_EXC) { statusRef.set(oldVal); final SecurityException e = Log.log.peerSecurityException(); e.initCause(RemoteExceptionCause.readFromStream(is));
/** * Write this remote exception cause to the given stream, without using serialization. * * @param output the output stream (must not be {@code null}) * @throws IOException if an error occurs writing the data */ public void writeToStream(DataOutput output) throws IOException { Assert.checkNotNullParam("output", output); writeToStream(output, new IdentityIntMap<Object>(), new HashMap<String,String>(), 0); }
/** * Get a remote exception cause for the given {@link Throwable}. All of the cause and suppressed exceptions will * also be converted. * * @param t the throwable, or {@code null} * @return the remote exception cause, or {@code null} if {@code null} was passed in */ public static RemoteExceptionCause of(Throwable t) { return of(t, new IdentityHashMap<>()); }
/** * Get a string representation of this exception. The representation will return an indication of the fact that * this was a remote exception, the remote exception type, and optionally details of the exception content, followed * by the exception message. * * @return the string representation of the exception */ public String toString() { final String toString = this.toString; if (toString == null) { final String message = getMessage(); StringBuilder b = new StringBuilder(); b.append(message == null ? CommonMessages.msg.remoteException(exceptionClassName) : CommonMessages.msg.remoteException(exceptionClassName, message)); Iterator<Map.Entry<String, String>> iterator = fields.entrySet().iterator(); if (iterator.hasNext()) { b.append("\n\tPublic fields:"); do { final Map.Entry<String, String> entry = iterator.next(); b.append('\n').append('\t').append('\t').append(entry.getKey()).append('=').append(entry.getValue()); } while (iterator.hasNext()); } return this.toString = b.toString(); } return toString; }
RemoteExceptionCause(final String msg, final RemoteExceptionCause cause, final String exceptionClassName, final Map<String, String> fields, boolean cloneFields) { super(msg); if (cause != null) { initCause(cause);
String exClassName = readObject(input, String.class, cache, false); String exMessage = readObject(input, String.class, cache, true); int length = readPackedInt(input); StackTraceElement[] stackTrace; if (length == 0) { stackTrace = new StackTraceElement[length]; for (int i = 0; i < length; i++) { stackTrace[i] = readObject(input, StackTraceElement.class, cache, false); length = readPackedInt(input); if (length == 0) { fields = Collections.emptyMap(); } else if (length == 1) { fields = Collections.singletonMap(readObject(input, String.class, cache, false), readObject(input, String.class, cache, false)); } else { fields = new HashMap<>(length); for (int i = 0; i < length; i++) { fields.put(readObject(input, String.class, cache, false), readObject(input, String.class, cache, false)); final RemoteExceptionCause result = new RemoteExceptionCause(exMessage, null, exClassName, fields, false); cache.set(idx, result); RemoteExceptionCause causedBy = readObject(input, RemoteExceptionCause.class, cache, true); result.initCause(causedBy); length = readPackedInt(input); result.setStackTrace(stackTrace); for (int i = 0; i < length; i++) { result.addSuppressed(readObject(input, RemoteExceptionCause.class, cache, false));
Object writeReplace() { final Throwable[] origSuppressed = getSuppressed(); final int length = origSuppressed.length; final RemoteExceptionCause[] suppressed; if (length == 0) { suppressed = NO_REMOTE_EXCEPTION_CAUSES; } else { suppressed = new RemoteExceptionCause[length]; for (int i = 0; i < length; i ++) { suppressed[i] = of(origSuppressed[i]); } } String[] fieldArray; final int size = fields.size(); if (size == 0) { fieldArray = NO_STRINGS; } else { fieldArray = new String[size << 1]; int i = 0; for (Map.Entry<String, String> entry : fields.entrySet()) { fieldArray[i++] = entry.getKey(); fieldArray[i++] = entry.getValue(); } } return new Serialized(getMessage(), exceptionClassName, of(getCause()), suppressed, getStackTrace(), fieldArray); }
/** * Convert this remote exception cause to a plain throwable for sending to peers which use serialization and do not * have this class present. Note that this does not recursively apply; normally, a serialization framework will * handle the recursive application of this operation through object resolution. * * @return the throwable (not {@code null}) */ public Throwable toPlainThrowable() { final Throwable throwable = new Throwable(toString(), getCause()); throwable.setStackTrace(getStackTrace()); for (Throwable s : getSuppressed()) { throwable.addSuppressed(s); } return throwable; }
Object readResolve() { final Map<String, String> fields; if (f == null) { fields = Collections.emptyMap(); } else { final int fl = f.length; if ((fl & 1) != 0) { throw CommonMessages.msg.invalidOddFields(); } else if (fl == 0) { fields = Collections.emptyMap(); } else if (fl == 2) { fields = Collections.singletonMap(f[0], f[1]); } else { final TreeMap<String, String> map = new TreeMap<>(); for (int i = 0; i < fl; i += 2) { map.put(f[i], f[i + 1]); } fields = Collections.unmodifiableMap(map); } } final RemoteExceptionCause ex = new RemoteExceptionCause(m, c, cn, fields, false); ex.setStackTrace(st); final RemoteExceptionCause[] suppressed = s; if (suppressed != null) for (RemoteExceptionCause c : suppressed) { ex.addSuppressed(c); } return ex; } }
statusRef.set(Status.STATUS_UNKNOWN); final IllegalStateException e = Log.log.peerIllegalStateException(); e.initCause(RemoteExceptionCause.readFromStream(is)); throw e; } else if (id == Protocol.P_UT_SYS_EXC) { final SystemException e = Log.log.peerSystemException(); e.errorCode = is.readInt(); e.initCause(RemoteExceptionCause.readFromStream(is)); throw e; } else if (id == Protocol.P_SEC_EXC) { statusRef.set(oldVal); final SecurityException e = Log.log.peerSecurityException(); e.initCause(RemoteExceptionCause.readFromStream(is)); throw e; } else {
/** * Write this remote exception cause to the given stream, without using serialization. * * @param output the output stream (must not be {@code null}) * @throws IOException if an error occurs writing the data */ public void writeToStream(DataOutput output) throws IOException { Assert.checkNotNullParam("output", output); writeToStream(output, new IdentityIntMap<Object>(), new HashMap<String,String>(), 0); }
/** * Get a remote exception cause for the given {@link Throwable}. All of the cause and suppressed exceptions will * also be converted. * * @param t the throwable, or {@code null} * @return the remote exception cause, or {@code null} if {@code null} was passed in */ public static RemoteExceptionCause of(Throwable t) { return of(t, new IdentityHashMap<>()); }
/** * Get a string representation of this exception. The representation will return an indication of the fact that * this was a remote exception, the remote exception type, and optionally details of the exception content, followed * by the exception message. * * @return the string representation of the exception */ public String toString() { final String toString = this.toString; if (toString == null) { final String message = getMessage(); StringBuilder b = new StringBuilder(); b.append(message == null ? CommonMessages.msg.remoteException(exceptionClassName) : CommonMessages.msg.remoteException(exceptionClassName, message)); Iterator<Map.Entry<String, String>> iterator = fields.entrySet().iterator(); if (iterator.hasNext()) { b.append("\n\tPublic fields:"); do { final Map.Entry<String, String> entry = iterator.next(); b.append('\n').append('\t').append('\t').append(entry.getKey()).append('=').append(entry.getValue()); } while (iterator.hasNext()); } return this.toString = b.toString(); } return toString; }