6911258: Project Coin: Add essential API support for Automatic Resource Management (ARM) blocks
6911261: Project Coin: Retrofit Automatic Resource Management (ARM) support onto platform APIs 6962571: Infinite loop in printing out Throwable stack traces with circular references Reviewed-by: darcy, alanb
This commit is contained in:
parent
af32180a74
commit
50f960454d
@ -30,6 +30,7 @@
|
||||
#
|
||||
JAVA_JAVA_java = \
|
||||
java/lang/Object.java \
|
||||
java/lang/AutoCloseable.java \
|
||||
java/lang/Class.java \
|
||||
java/lang/Thread.java \
|
||||
java/lang/Character.java \
|
||||
|
@ -28,14 +28,14 @@ package java.io;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A <tt>Closeable</tt> is a source or destination of data that can be closed.
|
||||
* A {@code Closeable} is a source or destination of data that can be closed.
|
||||
* The close method is invoked to release resources that the object is
|
||||
* holding (such as open files).
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
|
||||
public interface Closeable {
|
||||
public interface Closeable extends AutoCloseable {
|
||||
|
||||
/**
|
||||
* Closes this stream and releases any system resources associated
|
||||
@ -45,5 +45,4 @@ public interface Closeable {
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public void close() throws IOException;
|
||||
|
||||
}
|
||||
|
47
jdk/src/share/classes/java/lang/AutoCloseable.java
Normal file
47
jdk/src/share/classes/java/lang/AutoCloseable.java
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang;
|
||||
|
||||
/**
|
||||
* A resource that must be closed when it is no longer needed.
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface AutoCloseable {
|
||||
/**
|
||||
* Close this resource, relinquishing any underlying resources.
|
||||
* This method is invoked automatically by the automatic resource
|
||||
* management block construct.
|
||||
*
|
||||
* <p>Classes implementing this method are strongly encouraged to
|
||||
* be declared to throw more specific exceptions (or no exception
|
||||
* at all, if the close cannot fail).
|
||||
*
|
||||
* @throws Exception if this resource cannot be closed
|
||||
*/
|
||||
void close() throws Exception;
|
||||
}
|
@ -25,6 +25,7 @@
|
||||
|
||||
package java.lang;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The <code>Throwable</code> class is the superclass of all errors and
|
||||
@ -102,7 +103,7 @@ import java.io.*;
|
||||
* lowLevelOp();
|
||||
* } catch (LowLevelException le) {
|
||||
* throw (HighLevelException)
|
||||
new HighLevelException().initCause(le); // Legacy constructor
|
||||
* new HighLevelException().initCause(le); // Legacy constructor
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
@ -192,6 +193,24 @@ public class Throwable implements Serializable {
|
||||
* nulled out when fillInStackTrace is called.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The list of suppressed exceptions, as returned by
|
||||
* {@link #getSuppressedExceptions()}.
|
||||
*
|
||||
* @serial
|
||||
* @since 1.7
|
||||
*/
|
||||
private List<Throwable> suppressedExceptions = Collections.emptyList();
|
||||
|
||||
/** Message for trying to suppress a null exception. */
|
||||
private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
|
||||
|
||||
/** Caption for labeling causative exception stack traces */
|
||||
private static final String CAUSE_CAPTION = "Caused by: ";
|
||||
|
||||
/** Caption for labeling suppressed exception stack traces */
|
||||
private static final String SUPPRESSED_CAPTION = "Suppressed: ";
|
||||
|
||||
/**
|
||||
* Constructs a new throwable with <code>null</code> as its detail message.
|
||||
* The cause is not initialized, and may subsequently be initialized by a
|
||||
@ -469,6 +488,52 @@ public class Throwable implements Serializable {
|
||||
* class LowLevelException extends Exception {
|
||||
* }
|
||||
* </pre>
|
||||
* As of release 7, the platform supports the notion of
|
||||
* <i>suppressed exceptions</i> (in conjunction with automatic
|
||||
* resource management blocks). Any exceptions that were
|
||||
* suppressed in order to deliver an exception are printed out
|
||||
* beneath the stack trace. The format of this information
|
||||
* depends on the implementation, but the following example may be
|
||||
* regarded as typical:
|
||||
*
|
||||
* <pre>
|
||||
* Exception in thread "main" java.lang.Exception: Something happened
|
||||
* at Foo.bar(Foo.java:10)
|
||||
* at Foo.main(Foo.java:5)
|
||||
* Suppressed: Resource$CloseFailException: Resource ID = 0
|
||||
* at Resource.close(Resource.java:26)
|
||||
* at Foo.bar(Foo.java:9)
|
||||
* ... 1 more
|
||||
* </pre>
|
||||
* Note that the "... n more" notation is used on suppressed exceptions
|
||||
* just at it is used on causes. Unlike causes, suppressed exceptions are
|
||||
* indented beyond their "containing exceptions."
|
||||
*
|
||||
* <p>An exception can have both a cause and one or more suppressed
|
||||
* exceptions:
|
||||
* <pre>
|
||||
* Exception in thread "main" java.lang.Exception: Main block
|
||||
* at Foo3.main(Foo3.java:7)
|
||||
* Suppressed: Resource$CloseFailException: Resource ID = 2
|
||||
* at Resource.close(Resource.java:26)
|
||||
* at Foo3.main(Foo3.java:5)
|
||||
* Suppressed: Resource$CloseFailException: Resource ID = 1
|
||||
* at Resource.close(Resource.java:26)
|
||||
* at Foo3.main(Foo3.java:5)
|
||||
* Caused by: java.lang.Exception: I did it
|
||||
* at Foo3.main(Foo3.java:8)
|
||||
* </pre>
|
||||
* Likewise, a suppressed exception can have a cause:
|
||||
* <pre>
|
||||
* Exception in thread "main" java.lang.Exception: Main block
|
||||
* at Foo4.main(Foo4.java:6)
|
||||
* Suppressed: Resource2$CloseFailException: Resource ID = 1
|
||||
* at Resource2.close(Resource2.java:20)
|
||||
* at Foo4.main(Foo4.java:5)
|
||||
* Caused by: java.lang.Exception: Rats, you caught me
|
||||
* at Resource2$CloseFailException.<init>(Resource2.java:45)
|
||||
* ... 2 more
|
||||
* </pre>
|
||||
*/
|
||||
public void printStackTrace() {
|
||||
printStackTrace(System.err);
|
||||
@ -480,44 +545,71 @@ public class Throwable implements Serializable {
|
||||
* @param s <code>PrintStream</code> to use for output
|
||||
*/
|
||||
public void printStackTrace(PrintStream s) {
|
||||
synchronized (s) {
|
||||
printStackTrace(new WrappedPrintStream(s));
|
||||
}
|
||||
|
||||
private void printStackTrace(PrintStreamOrWriter s) {
|
||||
Set<Throwable> dejaVu = new HashSet<Throwable>();
|
||||
dejaVu.add(this);
|
||||
|
||||
synchronized (s.lock()) {
|
||||
// Print our stack trace
|
||||
s.println(this);
|
||||
StackTraceElement[] trace = getOurStackTrace();
|
||||
for (int i=0; i < trace.length; i++)
|
||||
s.println("\tat " + trace[i]);
|
||||
for (StackTraceElement traceElement : trace)
|
||||
s.println("\tat " + traceElement);
|
||||
|
||||
// Print suppressed exceptions, if any
|
||||
for (Throwable se : suppressedExceptions)
|
||||
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
|
||||
|
||||
// Print cause, if any
|
||||
Throwable ourCause = getCause();
|
||||
if (ourCause != null)
|
||||
ourCause.printStackTraceAsCause(s, trace);
|
||||
ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print our stack trace as a cause for the specified stack trace.
|
||||
* Print our stack trace as an enclosed exception for the specified
|
||||
* stack trace.
|
||||
*/
|
||||
private void printStackTraceAsCause(PrintStream s,
|
||||
StackTraceElement[] causedTrace)
|
||||
{
|
||||
// assert Thread.holdsLock(s);
|
||||
private void printEnclosedStackTrace(PrintStreamOrWriter s,
|
||||
StackTraceElement[] enclosingTrace,
|
||||
String caption,
|
||||
String prefix,
|
||||
Set<Throwable> dejaVu) {
|
||||
assert Thread.holdsLock(s.lock());
|
||||
if (dejaVu.contains(this)) {
|
||||
s.println("\t[CIRCULAR REFERENCE:" + this + "]");
|
||||
} else {
|
||||
dejaVu.add(this);
|
||||
// Compute number of frames in common between this and enclosing trace
|
||||
StackTraceElement[] trace = getOurStackTrace();
|
||||
int m = trace.length - 1;
|
||||
int n = enclosingTrace.length - 1;
|
||||
while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
|
||||
m--; n--;
|
||||
}
|
||||
int framesInCommon = trace.length - 1 - m;
|
||||
|
||||
// Compute number of frames in common between this and caused
|
||||
StackTraceElement[] trace = getOurStackTrace();
|
||||
int m = trace.length-1, n = causedTrace.length-1;
|
||||
while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
|
||||
m--; n--;
|
||||
// Print our stack trace
|
||||
s.println(prefix + caption + this);
|
||||
for (int i = 0; i <= m; i++)
|
||||
s.println(prefix + "\tat " + trace[i]);
|
||||
if (framesInCommon != 0)
|
||||
s.println(prefix + "\t... " + framesInCommon + " more");
|
||||
|
||||
// Print suppressed exceptions, if any
|
||||
for (Throwable se : suppressedExceptions)
|
||||
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
|
||||
prefix +"\t", dejaVu);
|
||||
|
||||
// Print cause, if any
|
||||
Throwable ourCause = getCause();
|
||||
if (ourCause != null)
|
||||
ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
|
||||
}
|
||||
int framesInCommon = trace.length - 1 - m;
|
||||
|
||||
s.println("Caused by: " + this);
|
||||
for (int i=0; i <= m; i++)
|
||||
s.println("\tat " + trace[i]);
|
||||
if (framesInCommon != 0)
|
||||
s.println("\t... " + framesInCommon + " more");
|
||||
|
||||
// Recurse if we have a cause
|
||||
Throwable ourCause = getCause();
|
||||
if (ourCause != null)
|
||||
ourCause.printStackTraceAsCause(s, trace);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -528,44 +620,51 @@ public class Throwable implements Serializable {
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public void printStackTrace(PrintWriter s) {
|
||||
synchronized (s) {
|
||||
s.println(this);
|
||||
StackTraceElement[] trace = getOurStackTrace();
|
||||
for (int i=0; i < trace.length; i++)
|
||||
s.println("\tat " + trace[i]);
|
||||
|
||||
Throwable ourCause = getCause();
|
||||
if (ourCause != null)
|
||||
ourCause.printStackTraceAsCause(s, trace);
|
||||
}
|
||||
printStackTrace(new WrappedPrintWriter(s));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print our stack trace as a cause for the specified stack trace.
|
||||
* Wrapper class for PrintStream and PrintWriter to enable a single
|
||||
* implementation of printStackTrace.
|
||||
*/
|
||||
private void printStackTraceAsCause(PrintWriter s,
|
||||
StackTraceElement[] causedTrace)
|
||||
{
|
||||
// assert Thread.holdsLock(s);
|
||||
private abstract static class PrintStreamOrWriter {
|
||||
/** Returns the object to be locked when using this StreamOrWriter */
|
||||
abstract Object lock();
|
||||
|
||||
// Compute number of frames in common between this and caused
|
||||
StackTraceElement[] trace = getOurStackTrace();
|
||||
int m = trace.length-1, n = causedTrace.length-1;
|
||||
while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
|
||||
m--; n--;
|
||||
/** Prints the specified string as a line on this StreamOrWriter */
|
||||
abstract void println(Object o);
|
||||
}
|
||||
|
||||
private static class WrappedPrintStream extends PrintStreamOrWriter {
|
||||
private final PrintStream printStream;
|
||||
|
||||
WrappedPrintStream(PrintStream printStream) {
|
||||
this.printStream = printStream;
|
||||
}
|
||||
int framesInCommon = trace.length - 1 - m;
|
||||
|
||||
s.println("Caused by: " + this);
|
||||
for (int i=0; i <= m; i++)
|
||||
s.println("\tat " + trace[i]);
|
||||
if (framesInCommon != 0)
|
||||
s.println("\t... " + framesInCommon + " more");
|
||||
Object lock() {
|
||||
return printStream;
|
||||
}
|
||||
|
||||
// Recurse if we have a cause
|
||||
Throwable ourCause = getCause();
|
||||
if (ourCause != null)
|
||||
ourCause.printStackTraceAsCause(s, trace);
|
||||
void println(Object o) {
|
||||
printStream.println(o);
|
||||
}
|
||||
}
|
||||
|
||||
private static class WrappedPrintWriter extends PrintStreamOrWriter {
|
||||
private final PrintWriter printWriter;
|
||||
|
||||
WrappedPrintWriter(PrintWriter printWriter) {
|
||||
this.printWriter = printWriter;
|
||||
}
|
||||
|
||||
Object lock() {
|
||||
return printWriter;
|
||||
}
|
||||
|
||||
void println(Object o) {
|
||||
printWriter.println(o);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -667,10 +766,60 @@ public class Throwable implements Serializable {
|
||||
*/
|
||||
native StackTraceElement getStackTraceElement(int index);
|
||||
|
||||
private synchronized void writeObject(java.io.ObjectOutputStream s)
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
s.defaultReadObject(); // read in all fields
|
||||
List<Throwable> suppressed = Collections.emptyList();
|
||||
if (suppressedExceptions != null &&
|
||||
!suppressedExceptions.isEmpty()) { // Copy Throwables to new list
|
||||
suppressed = new ArrayList<Throwable>();
|
||||
for(Throwable t : suppressedExceptions) {
|
||||
if (t == null)
|
||||
throw new NullPointerException(NULL_CAUSE_MESSAGE);
|
||||
suppressed.add(t);
|
||||
}
|
||||
}
|
||||
suppressedExceptions = suppressed;
|
||||
}
|
||||
|
||||
private synchronized void writeObject(ObjectOutputStream s)
|
||||
throws IOException
|
||||
{
|
||||
getOurStackTrace(); // Ensure that stackTrace field is initialized.
|
||||
s.defaultWriteObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified exception to the list of exceptions that
|
||||
* were suppressed, typically by the automatic resource management
|
||||
* statement, in order to deliver this exception.
|
||||
*
|
||||
* @param exception the exception to be added to the list of
|
||||
* suppressed exceptions
|
||||
* @throws NullPointerException if {@code exception} is null
|
||||
* @since 1.7
|
||||
*/
|
||||
public synchronized void addSuppressedException(Throwable exception) {
|
||||
if (exception == null)
|
||||
throw new NullPointerException(NULL_CAUSE_MESSAGE);
|
||||
|
||||
if (suppressedExceptions.size() == 0)
|
||||
suppressedExceptions = new ArrayList<Throwable>();
|
||||
suppressedExceptions.add(exception);
|
||||
}
|
||||
|
||||
private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the exceptions that were
|
||||
* suppressed, typically by the automatic resource management
|
||||
* statement, in order to deliver this exception.
|
||||
*
|
||||
* @return an array containing all of the exceptions that were
|
||||
* suppressed to deliver this exception.
|
||||
* @since 1.7
|
||||
*/
|
||||
public Throwable[] getSuppressedExceptions() {
|
||||
return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ import java.io.IOException;
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public abstract class FileLock {
|
||||
public abstract class FileLock implements AutoCloseable {
|
||||
|
||||
private final Channel channel;
|
||||
private final long position;
|
||||
@ -298,6 +298,17 @@ public abstract class FileLock {
|
||||
*/
|
||||
public abstract void release() throws IOException;
|
||||
|
||||
/**
|
||||
* This method invokes the {@link #release} method. It was added
|
||||
* to the class so that it could be used in conjunction with the
|
||||
* automatic resource management block construct.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public final void close() throws IOException {
|
||||
release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing the range, type, and validity of this lock.
|
||||
*
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteOrder;
|
||||
@ -42,7 +43,7 @@ import java.nio.ByteOrder;
|
||||
* @see MemoryCacheImageInputStream
|
||||
*
|
||||
*/
|
||||
public interface ImageInputStream extends DataInput {
|
||||
public interface ImageInputStream extends DataInput, Closeable {
|
||||
|
||||
/**
|
||||
* Sets the desired byte order for future reads of data values
|
||||
|
165
jdk/test/java/lang/Throwable/SuppressedExceptions.java
Normal file
165
jdk/test/java/lang/Throwable/SuppressedExceptions.java
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6911258 6962571
|
||||
* @summary Basic tests of suppressed exceptions
|
||||
* @author Joseph D. Darcy
|
||||
*/
|
||||
|
||||
public class SuppressedExceptions {
|
||||
private static String message = "Bad suppressed exception information";
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
basicSupressionTest();
|
||||
serializationTest();
|
||||
selfReference();
|
||||
}
|
||||
|
||||
private static void basicSupressionTest() {
|
||||
Throwable throwable = new Throwable();
|
||||
RuntimeException suppressed = new RuntimeException("A suppressed exception.");
|
||||
AssertionError repressed = new AssertionError("A repressed error.");
|
||||
|
||||
Throwable[] t0 = throwable.getSuppressedExceptions();
|
||||
if (t0.length != 0) {
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
throwable.printStackTrace();
|
||||
|
||||
throwable.addSuppressedException(suppressed);
|
||||
Throwable[] t1 = throwable.getSuppressedExceptions();
|
||||
if (t1.length != 1 ||
|
||||
t1[0] != suppressed) {throw new RuntimeException(message);
|
||||
}
|
||||
throwable.printStackTrace();
|
||||
|
||||
throwable.addSuppressedException(repressed);
|
||||
Throwable[] t2 = throwable.getSuppressedExceptions();
|
||||
if (t2.length != 2 ||
|
||||
t2[0] != suppressed ||
|
||||
t2[1] != repressed) {
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
|
||||
private static void serializationTest() throws Exception {
|
||||
/*
|
||||
* Bytes of the serial form of
|
||||
*
|
||||
* (new Throwable())setStackTrace(new StackTraceElement[0])
|
||||
*
|
||||
* from JDK 6; suppressedException field will be missing and
|
||||
* thus default to null upon deserialization.
|
||||
*/
|
||||
byte[] bytes = {
|
||||
(byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x13,
|
||||
(byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e,
|
||||
(byte)0x67, (byte)0x2e, (byte)0x54, (byte)0x68, (byte)0x72, (byte)0x6f, (byte)0x77, (byte)0x61,
|
||||
(byte)0x62, (byte)0x6c, (byte)0x65, (byte)0xd5, (byte)0xc6, (byte)0x35, (byte)0x27, (byte)0x39,
|
||||
(byte)0x77, (byte)0xb8, (byte)0xcb, (byte)0x03, (byte)0x00, (byte)0x03, (byte)0x4c, (byte)0x00,
|
||||
(byte)0x05, (byte)0x63, (byte)0x61, (byte)0x75, (byte)0x73, (byte)0x65, (byte)0x74, (byte)0x00,
|
||||
(byte)0x15, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c,
|
||||
(byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x54, (byte)0x68, (byte)0x72, (byte)0x6f,
|
||||
(byte)0x77, (byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x3b, (byte)0x4c, (byte)0x00,
|
||||
(byte)0x0d, (byte)0x64, (byte)0x65, (byte)0x74, (byte)0x61, (byte)0x69, (byte)0x6c, (byte)0x4d,
|
||||
(byte)0x65, (byte)0x73, (byte)0x73, (byte)0x61, (byte)0x67, (byte)0x65, (byte)0x74, (byte)0x00,
|
||||
(byte)0x12, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c,
|
||||
(byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x69,
|
||||
(byte)0x6e, (byte)0x67, (byte)0x3b, (byte)0x5b, (byte)0x00, (byte)0x0a, (byte)0x73, (byte)0x74,
|
||||
(byte)0x61, (byte)0x63, (byte)0x6b, (byte)0x54, (byte)0x72, (byte)0x61, (byte)0x63, (byte)0x65,
|
||||
(byte)0x74, (byte)0x00, (byte)0x1e, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76,
|
||||
(byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53,
|
||||
(byte)0x74, (byte)0x61, (byte)0x63, (byte)0x6b, (byte)0x54, (byte)0x72, (byte)0x61, (byte)0x63,
|
||||
(byte)0x65, (byte)0x45, (byte)0x6c, (byte)0x65, (byte)0x6d, (byte)0x65, (byte)0x6e, (byte)0x74,
|
||||
(byte)0x3b, (byte)0x78, (byte)0x70, (byte)0x71, (byte)0x00, (byte)0x7e, (byte)0x00, (byte)0x04,
|
||||
(byte)0x70, (byte)0x75, (byte)0x72, (byte)0x00, (byte)0x1e, (byte)0x5b, (byte)0x4c, (byte)0x6a,
|
||||
(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67,
|
||||
(byte)0x2e, (byte)0x53, (byte)0x74, (byte)0x61, (byte)0x63, (byte)0x6b, (byte)0x54, (byte)0x72,
|
||||
(byte)0x61, (byte)0x63, (byte)0x65, (byte)0x45, (byte)0x6c, (byte)0x65, (byte)0x6d, (byte)0x65,
|
||||
(byte)0x6e, (byte)0x74, (byte)0x3b, (byte)0x02, (byte)0x46, (byte)0x2a, (byte)0x3c, (byte)0x3c,
|
||||
(byte)0xfd, (byte)0x22, (byte)0x39, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0xac, (byte)0xed, (byte)0x00,
|
||||
(byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x13, (byte)0x6a, (byte)0x61, (byte)0x76,
|
||||
(byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2e, (byte)0x54,
|
||||
(byte)0x68, (byte)0x72, (byte)0x6f, (byte)0x77, (byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65,
|
||||
(byte)0xd5, (byte)0xc6, (byte)0x35, (byte)0x27, (byte)0x39, (byte)0x77, (byte)0xb8, (byte)0xcb,
|
||||
(byte)0x03, (byte)0x00, (byte)0x03, (byte)0x4c, (byte)0x00, (byte)0x05, (byte)0x63, (byte)0x61,
|
||||
(byte)0x75, (byte)0x73, (byte)0x65, (byte)0x74, (byte)0x00, (byte)0x15, (byte)0x4c, (byte)0x6a,
|
||||
(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67,
|
||||
(byte)0x2f, (byte)0x54, (byte)0x68, (byte)0x72, (byte)0x6f, (byte)0x77, (byte)0x61, (byte)0x62,
|
||||
(byte)0x6c, (byte)0x65, (byte)0x3b, (byte)0x4c, (byte)0x00, (byte)0x0d, (byte)0x64, (byte)0x65,
|
||||
(byte)0x74, (byte)0x61, (byte)0x69, (byte)0x6c, (byte)0x4d, (byte)0x65, (byte)0x73, (byte)0x73,
|
||||
(byte)0x61, (byte)0x67, (byte)0x65, (byte)0x74, (byte)0x00, (byte)0x12, (byte)0x4c, (byte)0x6a,
|
||||
(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x6e, (byte)0x67, (byte)0x3b,
|
||||
(byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x69,
|
||||
(byte)0x5b, (byte)0x00, (byte)0x0a, (byte)0x73, (byte)0x74, (byte)0x61, (byte)0x63, (byte)0x6b,
|
||||
(byte)0x54, (byte)0x72, (byte)0x61, (byte)0x63, (byte)0x65, (byte)0x74, (byte)0x00, (byte)0x1e,
|
||||
(byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c,
|
||||
(byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53, (byte)0x74, (byte)0x61, (byte)0x63,
|
||||
(byte)0x6b, (byte)0x54, (byte)0x72, (byte)0x61, (byte)0x63, (byte)0x65, (byte)0x45, (byte)0x6c,
|
||||
(byte)0x65, (byte)0x6d, (byte)0x65, (byte)0x6e, (byte)0x74, (byte)0x3b, (byte)0x78, (byte)0x70,
|
||||
(byte)0x71, (byte)0x00, (byte)0x7e, (byte)0x00, (byte)0x04, (byte)0x70, (byte)0x75, (byte)0x72,
|
||||
(byte)0x00, (byte)0x1e, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61,
|
||||
(byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2e, (byte)0x53, (byte)0x74,
|
||||
(byte)0x61, (byte)0x63, (byte)0x6b, (byte)0x54, (byte)0x72, (byte)0x61, (byte)0x63, (byte)0x65,
|
||||
(byte)0x45, (byte)0x6c, (byte)0x65, (byte)0x6d, (byte)0x65, (byte)0x6e, (byte)0x74, (byte)0x3b,
|
||||
(byte)0x02, (byte)0x46, (byte)0x2a, (byte)0x3c, (byte)0x3c, (byte)0xfd, (byte)0x22, (byte)0x39,
|
||||
(byte)0x02, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70,
|
||||
};
|
||||
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||
|
||||
Object o = ois.readObject();
|
||||
Throwable throwable = (Throwable) o;
|
||||
|
||||
System.err.println("TESTING SERIALIZED EXCEPTION");
|
||||
|
||||
Throwable[] t0 = throwable.getSuppressedExceptions();
|
||||
if (t0.length != 0) { // Will fail if t0 is null.
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
|
||||
private static void selfReference() {
|
||||
Throwable throwable1 = new RuntimeException();
|
||||
Throwable throwable2 = new AssertionError();
|
||||
throwable1.initCause(throwable2);
|
||||
throwable2.initCause(throwable1);
|
||||
|
||||
throwable1.printStackTrace();
|
||||
|
||||
|
||||
throwable1.addSuppressedException(throwable1);
|
||||
throwable1.addSuppressedException(throwable2);
|
||||
|
||||
throwable1.printStackTrace();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user