--- old/jdk/src/share/classes/java/lang/StackTraceElement.java 2010-11-14 06:58:33.000000000 -0800 +++ new/jdk/src/share/classes/java/lang/StackTraceElement.java 2010-11-14 06:58:32.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -25,6 +25,8 @@ package java.lang; +import java.util.Objects; + /** * An element in a stack trace, as returned by {@link * Throwable#getStackTrace()}. Each element represents a single stack frame. @@ -53,26 +55,21 @@ * @param methodName the name of the method containing the execution point * represented by the stack trace element * @param fileName the name of the file containing the execution point - * represented by the stack trace element, or null if + * represented by the stack trace element, or {@code null} if * this information is unavailable * @param lineNumber the line number of the source line containing the * execution point represented by this stack trace element, or * a negative number if this information is unavailable. A value * of -2 indicates that the method containing the execution point * is a native method - * @throws NullPointerException if declaringClass or - * methodName is null + * @throws NullPointerException if {@code declaringClass} or + * {@code methodName} is null * @since 1.5 */ public StackTraceElement(String declaringClass, String methodName, String fileName, int lineNumber) { - if (declaringClass == null) - throw new NullPointerException("Declaring class is null"); - if (methodName == null) - throw new NullPointerException("Method name is null"); - - this.declaringClass = declaringClass; - this.methodName = methodName; + this.declaringClass = Objects.nonNull(declaringClass, "Declaring class is null"); + this.methodName = Objects.nonNull(methodName, "Method name is null"); this.fileName = fileName; this.lineNumber = lineNumber; } @@ -80,13 +77,13 @@ /** * Returns the name of the source file containing the execution point * represented by this stack trace element. Generally, this corresponds - * to the SourceFile attribute of the relevant class + * to the {@code SourceFile} attribute of the relevant {@code class} * file (as per The Java Virtual Machine Specification, Section * 4.7.7). In some systems, the name may refer to some source code unit * other than a file, such as an entry in source repository. * * @return the name of the file containing the execution point - * represented by this stack trace element, or null if + * represented by this stack trace element, or {@code null} if * this information is unavailable. */ public String getFileName() { @@ -96,8 +93,8 @@ /** * Returns the line number of the source line containing the execution * point represented by this stack trace element. Generally, this is - * derived from the LineNumberTable attribute of the relevant - * class file (as per The Java Virtual Machine + * derived from the {@code LineNumberTable} attribute of the relevant + * {@code class} file (as per The Java Virtual Machine * Specification, Section 4.7.8). * * @return the line number of the source line containing the execution @@ -112,7 +109,7 @@ * Returns the fully qualified name of the class containing the * execution point represented by this stack trace element. * - * @return the fully qualified name of the Class containing + * @return the fully qualified name of the {@code Class} containing * the execution point represented by this stack trace element. */ public String getClassName() { @@ -123,8 +120,8 @@ * Returns the name of the method containing the execution point * represented by this stack trace element. If the execution point is * contained in an instance or class initializer, this method will return - * the appropriate special method name, <init> or - * <clinit>, as per Section 3.9 of The Java Virtual + * the appropriate special method name, {@code } or + * {@code }, as per Section 3.9 of The Java Virtual * Machine Specification. * * @return the name of the method containing the execution point @@ -138,7 +135,7 @@ * Returns true if the method containing the execution point * represented by this stack trace element is a native method. * - * @return true if the method containing the execution point + * @return {@code true} if the method containing the execution point * represented by this stack trace element is a native method. */ public boolean isNativeMethod() { @@ -151,21 +148,21 @@ * examples may be regarded as typical: *
    *
  • - * "MyClass.mash(MyClass.java:9)" - Here, "MyClass" + * {@code "MyClass.mash(MyClass.java:9)"} - Here, {@code "MyClass"} * is the fully-qualified name of the class containing the * execution point represented by this stack trace element, - * "mash" is the name of the method containing the execution - * point, "MyClass.java" is the source file containing the - * execution point, and "9" is the line number of the source + * {@code "mash"} is the name of the method containing the execution + * point, {@code "MyClass.java"} is the source file containing the + * execution point, and {@code "9"} is the line number of the source * line containing the execution point. *
  • - * "MyClass.mash(MyClass.java)" - As above, but the line + * {@code "MyClass.mash(MyClass.java)"} - As above, but the line * number is unavailable. *
  • - * "MyClass.mash(Unknown Source)" - As above, but neither + * {@code "MyClass.mash(Unknown Source)"} - As above, but neither * the file name nor the line number are available. *
  • - * "MyClass.mash(Native Method)" - As above, but neither + * {@code "MyClass.mash(Native Method)"} - As above, but neither * the file name nor the line number are available, and the method * containing the execution point is known to be a native method. *
@@ -181,25 +178,21 @@ /** * Returns true if the specified object is another - * StackTraceElement instance representing the same execution - * point as this instance. Two stack trace elements a and - * b are equal if and only if: + * {@code StackTraceElement} instance representing the same execution + * point as this instance. Two stack trace elements {@code a} and + * {@code b} are equal if and only if: *
      *     equals(a.getFileName(), b.getFileName()) &&
      *     a.getLineNumber() == b.getLineNumber()) &&
      *     equals(a.getClassName(), b.getClassName()) &&
      *     equals(a.getMethodName(), b.getMethodName())
      * 
- * where equals is defined as: - *
-     *     static boolean equals(Object a, Object b) {
-     *         return a==b || (a != null && a.equals(b));
-     *     }
-     * 
+ * where {@code equals} has the semantics of {@link + * java.util.Objects#equals(Object, Object) Objects.equals}. * * @param obj the object to be compared with this stack trace element. * @return true if the specified object is another - * StackTraceElement instance representing the same + * {@code StackTraceElement} instance representing the same * execution point as this instance. */ public boolean equals(Object obj) { @@ -208,12 +201,10 @@ if (!(obj instanceof StackTraceElement)) return false; StackTraceElement e = (StackTraceElement)obj; - return e.declaringClass.equals(declaringClass) && e.lineNumber == lineNumber - && eq(methodName, e.methodName) && eq(fileName, e.fileName); - } - - private static boolean eq(Object a, Object b) { - return a==b || (a != null && a.equals(b)); + return e.declaringClass.equals(declaringClass) && + e.lineNumber == lineNumber && + Objects.equals(methodName, e.methodName) && + Objects.equals(fileName, e.fileName); } /** @@ -221,7 +212,7 @@ */ public int hashCode() { int result = 31*declaringClass.hashCode() + methodName.hashCode(); - result = 31*result + (fileName == null ? 0 : fileName.hashCode()); + result = 31*result + Objects.hashCode(fileName); result = 31*result + lineNumber; return result; } --- old/jdk/src/share/classes/java/lang/Throwable.java 2010-11-14 06:58:34.000000000 -0800 +++ new/jdk/src/share/classes/java/lang/Throwable.java 2010-11-14 06:58:33.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -170,6 +170,36 @@ private String detailMessage; /** + * A shared value for an empty stack. + */ + private static final StackTraceElement[] EMPTY_STACK = new StackTraceElement[0]; + + /* + * To allow Throwable objects to be made immutable and safely + * reused by the JVM, such as OutOfMemoryErrors, fields of + * Throwable that are writable in response to user actions, cause + * and suppressedExceptions obey the following protocol: + * + * 1) The fields are initialized to a non-null sentinel value + * which indicates the value has logically not been set. + * + * 2) Writing a null to the field indicates further writes + * are forbidden + * + * 3) The sentinel value may be replaced with another non-null + * value. + * + * For example, implementations of the HotSpot JVM have + * preallocated OutOfMemoryError objects to provide for better + * diagnosability of that situation. These objects are created + * without calling the constructor for that class and the fields + * in question are initialized to null. To support this + * capability, any new fields added to Throwable that require + * being initialized to a non-null value require a coordinated JVM + * change. + */ + + /** * The throwable that caused this throwable to get thrown, or null if this * throwable was not caused by another throwable, or if the causative * throwable is unknown. If this field is equal to this throwable itself, @@ -188,32 +218,30 @@ * @since 1.4 */ private StackTraceElement[] stackTrace; - /* - * This field is lazily initialized on first use or serialization and - * nulled out when fillInStackTrace is called. - */ + + // Setting this static field introduces an acceptable + // initialization dependency on a few java.util classes. + private static final List SUPPRESSED_SENTINEL = + Collections.unmodifiableList(new ArrayList(0)); /** - * The list of suppressed exceptions, as returned by - * {@link #getSuppressedExceptions()}. + * The list of suppressed exceptions, as returned by {@link + * #getSuppressed()}. The list is initialized to a zero-element + * unmodifiable sentinel list. When a serialized Throwable is + * read in, if the {@code suppressedExceptions} field points to a + * zero-element list, the field is reset to the sentinel value. * * @serial * @since 1.7 */ - private List suppressedExceptions = null; - /* - * This field is lazily initialized when the first suppressed - * exception is added. - * - * OutOfMemoryError is preallocated in the VM for better OOM - * diagnosability during VM initialization. Constructor can't - * be not invoked. If a new field to be added in the future must - * be initialized to non-null, it requires a synchronized VM change. - */ + private List suppressedExceptions = SUPPRESSED_SENTINEL; /** Message for trying to suppress a null exception. */ private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception."; + /** Message for trying to suppress oneself. */ + private static final String SELF_SUPPRESSION_MESSAGE = "Self-suppression not permitted"; + /** Caption for labeling causative exception stack traces */ private static final String CAUSE_CAPTION = "Caused by: "; @@ -572,7 +600,7 @@ s.println("\tat " + traceElement); // Print suppressed exceptions, if any - for (Throwable se : getSuppressedExceptions()) + for (Throwable se : getSuppressed()) se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu); // Print cause, if any @@ -613,7 +641,7 @@ s.println(prefix + "\t... " + framesInCommon + " more"); // Print suppressed exceptions, if any - for (Throwable se : getSuppressedExceptions()) + for (Throwable se : getSuppressed()) se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, prefix +"\t", dejaVu); @@ -755,7 +783,7 @@ for (int i = 0; i < defensiveCopy.length; i++) if (defensiveCopy[i] == null) throw new NullPointerException("stackTrace[" + i + "]"); - + synchronized (this) { this.stackTrace = defensiveCopy; } @@ -780,25 +808,58 @@ */ native StackTraceElement getStackTraceElement(int index); + /** + * Read a {@code Throwable} from a stream, enforcing + * well-formedness constraints on fields. Null entries and + * self-pointers are not allowed in the list of {@code + * suppressedExceptions}. Null entries are not allowed for stack + * trace elements. + * + * Note that there are no constraints on the value the {@code + * cause} field can hold; both {@code null} and {@code this} are + * valid values for the field. + */ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); // read in all fields - List suppressed = null; - if (suppressedExceptions != null && - !suppressedExceptions.isEmpty()) { // Copy Throwables to new list - suppressed = new ArrayList(); - for (Throwable t : suppressedExceptions) { - if (t == null) - throw new NullPointerException(NULL_CAUSE_MESSAGE); - suppressed.add(t); + if (suppressedExceptions != null) { + List suppressed = null; + if (suppressedExceptions.isEmpty()) { + // Use the sentinel for a zero-length list + suppressed = SUPPRESSED_SENTINEL; + } else { // Copy Throwables to new list + suppressed = new ArrayList(1); + for (Throwable t : suppressedExceptions) { + // Enforce constraints on suppressed exceptions in + // case of corrupt or malicious stream. + if (t == null) + throw new NullPointerException(NULL_CAUSE_MESSAGE); + if (t == this) + throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE); + suppressed.add(t); + } + } + suppressedExceptions = suppressed; + } // else a null suppressedExceptions field remains null + + if (stackTrace != null) { + for (StackTraceElement ste : stackTrace) { + if (ste == null) + throw new NullPointerException("null StackTraceElement in serial stream. "); } + } else { + // A null stackTrace field in the serial form can result from + // an exception serialized without that field in older JDK releases. + stackTrace = EMPTY_STACK; } - suppressedExceptions = suppressed; + } + /** + * Write a {@code Throwable} object to a stream. + */ private synchronized void writeObject(ObjectOutputStream s) - throws IOException - { + throws IOException { getOurStackTrace(); // Ensure that stackTrace field is initialized. s.defaultWriteObject(); } @@ -808,6 +869,14 @@ * were suppressed, typically by the {@code try}-with-resources * statement, in order to deliver this exception. * + * If the first exception to be suppressed is {@code null}, that + * indicates suppressed exception information will not be + * recorded for this exception. Subsequent calls to this method + * will not record any suppressed exceptions. Otherwise, + * attempting to suppress {@code null} after an exception has + * already been successfully suppressed results in a {@code + * NullPointerException}. + * *

Note that when one exception {@linkplain * #initCause(Throwable) causes} another exception, the first * exception is usually caught and then the second exception is @@ -819,20 +888,35 @@ * * @param exception the exception to be added to the list of * suppressed exceptions - * @throws NullPointerException if {@code exception} is null * @throws IllegalArgumentException if {@code exception} is this * throwable; a throwable cannot suppress itself. + * @throws NullPointerException if {@code exception} is null and + * an exception has already been suppressed by this exception * @since 1.7 */ - public synchronized void addSuppressedException(Throwable exception) { - if (exception == null) - throw new NullPointerException(NULL_CAUSE_MESSAGE); + public final synchronized void addSuppressed(Throwable exception) { if (exception == this) - throw new IllegalArgumentException("Self-suppression not permitted"); + throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE); - if (suppressedExceptions == null) - suppressedExceptions = new ArrayList(); - suppressedExceptions.add(exception); + if (exception == null) { + if (suppressedExceptions == SUPPRESSED_SENTINEL) { + suppressedExceptions = null; // No suppression information recorded + return; + } else + throw new NullPointerException(NULL_CAUSE_MESSAGE); + } else { + assert exception != null && exception != this; + + if (suppressedExceptions == null) // Suppressed exceptions not recorded + return; + + if (suppressedExceptions == SUPPRESSED_SENTINEL) + suppressedExceptions = new ArrayList(1); + + assert suppressedExceptions != SUPPRESSED_SENTINEL; + + suppressedExceptions.add(exception); + } } private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0]; @@ -842,12 +926,15 @@ * suppressed, typically by the {@code try}-with-resources * statement, in order to deliver this exception. * + * If no exceptions were suppressed, an empty array is returned. + * * @return an array containing all of the exceptions that were * suppressed to deliver this exception. * @since 1.7 */ - public synchronized Throwable[] getSuppressedExceptions() { - if (suppressedExceptions == null) + public final synchronized Throwable[] getSuppressed() { + if (suppressedExceptions == SUPPRESSED_SENTINEL || + suppressedExceptions == null) return EMPTY_THROWABLE_ARRAY; else return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY); --- old/jdk/test/java/lang/Throwable/StackTraceSerialization.java 2010-11-14 06:58:34.000000000 -0800 +++ new/jdk/test/java/lang/Throwable/StackTraceSerialization.java 2010-11-14 06:58:34.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -26,13 +26,33 @@ /* * @test - * @bug 4202914 4363318 + * @bug 4202914 4363318 6991528 * @summary Basic test of serialization of stack trace information * @author Josh Bloch */ public class StackTraceSerialization { public static void main(String args[]) throws Exception { + testWithSetStackTrace(); + testWithFillInStackTrace(); + } + + private static void testWithSetStackTrace() throws Exception { + Throwable t = new Throwable(); + + t.setStackTrace(new StackTraceElement[] + {new StackTraceElement("foo", "bar", "baz", -1)}); + + if (!equal(t, reconstitute(t))) + throw new Exception("Unequal Throwables with set stacktrace"); + } + + private static void assertEmptyStackTrace(Throwable t) { + if (t.getStackTrace().length != 0) + throw new AssertionError("Nonempty stacktrace."); + } + + private static void testWithFillInStackTrace() throws Exception { Throwable original = null; try { a(); @@ -40,27 +60,42 @@ original = e; } - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(bout); - out.writeObject(original); - out.flush(); - ByteArrayInputStream bin = - new ByteArrayInputStream(bout.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bin); - Throwable clone = (Throwable) in.readObject(); + if (!equal(original, reconstitute(original))) + throw new Exception("Unequal Throwables with filled-in stacktrace"); + } + + + /** + * Serialize the argument and return the deserialized result. + */ + private static Throwable reconstitute(Throwable t) throws Exception { + Throwable result = null; - if (!equal(original, clone)) - throw new Exception(); + try(ByteArrayOutputStream bout = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bout)) { + out.writeObject(t); + out.flush(); + try(ByteArrayInputStream bin = + new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bin)) { + result = (Throwable) in.readObject(); + } + } + + return result; } /** - * Returns true if e1 and e2 have equal stack traces and their causes - * are recursively equal (by the same definition). Returns false - * or throws NullPointerExeption otherwise. + * Returns true if e1 and e2 have equal stack traces and their + * causes are recursively equal (by the same definition) and their + * suppressed exception information is equals. Returns false or + * throws NullPointerExeption otherwise. */ private static boolean equal(Throwable t1, Throwable t2) { - return t1==t2 || (Arrays.equals(t1.getStackTrace(), t2.getStackTrace()) - && equal(t1.getCause(), t2.getCause())); + return t1==t2 || + (Arrays.equals(t1.getStackTrace(), t2.getStackTrace()) && + equal(t1.getCause(), t2.getCause()) && + Objects.equals(t1.getSuppressed(), t2.getSuppressed())); } static void a() throws HighLevelException { --- old/jdk/test/java/lang/Throwable/SuppressedExceptions.java 2010-11-14 06:58:35.000000000 -0800 +++ new/jdk/test/java/lang/Throwable/SuppressedExceptions.java 2010-11-14 06:58:35.000000000 -0800 @@ -26,7 +26,7 @@ /* * @test - * @bug 6911258 6962571 6963622 + * @bug 6911258 6962571 6963622 6991528 * @summary Basic tests of suppressed exceptions * @author Joseph D. Darcy */ @@ -39,12 +39,21 @@ basicSupressionTest(); serializationTest(); selfReference(); + noModification(); } private static void noSelfSuppression() { Throwable throwable = new Throwable(); try { - throwable.addSuppressedException(throwable); + throwable.addSuppressed(throwable); + throw new RuntimeException("IllegalArgumentException for self-suppresion not thrown."); + } catch (IllegalArgumentException iae) { + ; // Expected + } + + throwable.addSuppressed(null); // Immutable suppression list + try { + throwable.addSuppressed(throwable); throw new RuntimeException("IllegalArgumentException for self-suppresion not thrown."); } catch (IllegalArgumentException iae) { ; // Expected @@ -56,21 +65,21 @@ RuntimeException suppressed = new RuntimeException("A suppressed exception."); AssertionError repressed = new AssertionError("A repressed error."); - Throwable[] t0 = throwable.getSuppressedExceptions(); + Throwable[] t0 = throwable.getSuppressed(); if (t0.length != 0) { throw new RuntimeException(message); } throwable.printStackTrace(); - throwable.addSuppressedException(suppressed); - Throwable[] t1 = throwable.getSuppressedExceptions(); + throwable.addSuppressed(suppressed); + Throwable[] t1 = throwable.getSuppressed(); if (t1.length != 1 || t1[0] != suppressed) {throw new RuntimeException(message); } throwable.printStackTrace(); - throwable.addSuppressedException(repressed); - Throwable[] t2 = throwable.getSuppressedExceptions(); + throwable.addSuppressed(repressed); + Throwable[] t2 = throwable.getSuppressed(); if (t2.length != 2 || t2[0] != suppressed || t2[1] != repressed) { @@ -152,7 +161,7 @@ System.err.println("TESTING SERIALIZED EXCEPTION"); - Throwable[] t0 = throwable.getSuppressedExceptions(); + Throwable[] t0 = throwable.getSuppressed(); if (t0.length != 0) { // Will fail if t0 is null. throw new RuntimeException(message); } @@ -167,9 +176,25 @@ throwable1.printStackTrace(); - throwable1.addSuppressedException(throwable2); - throwable2.addSuppressedException(throwable1); + throwable1.addSuppressed(throwable2); + throwable2.addSuppressed(throwable1); throwable1.printStackTrace(); } + + private static void noModification() { + Throwable t = new Throwable(); + t.addSuppressed(null); + + Throwable[] t0 = t.getSuppressed(); + if (t0.length != 0) + throw new RuntimeException("Bad nonzero length of suppressed exceptions."); + + t.addSuppressed(new ArithmeticException()); + + // Make sure a suppressed exception did *not* get added. + t0 = t.getSuppressed(); + if (t0.length != 0) + throw new RuntimeException("Bad nonzero length of suppressed exceptions."); + } } --- old/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java 2010-11-14 06:58:36.000000000 -0800 +++ new/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java 2010-11-14 06:58:36.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -1509,17 +1509,17 @@ } private JCBlock makeArmFinallyClause(Symbol primaryException, JCExpression resource) { - // primaryException.addSuppressedException(catchException); + // primaryException.addSuppressed(catchException); VarSymbol catchException = new VarSymbol(0, make.paramName(2), syms.throwableType, currentMethodSym); JCStatement addSuppressionStatement = make.Exec(makeCall(make.Ident(primaryException), - names.fromString("addSuppressedException"), + names.addSuppressed, List.of(make.Ident(catchException)))); - // try { resource.close(); } catch (e) { primaryException.addSuppressedException(e); } + // try { resource.close(); } catch (e) { primaryException.addSuppressed(e); } JCBlock tryBlock = make.Block(0L, List.of(makeResourceCloseInvocation(resource))); JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null); --- old/langtools/src/share/classes/com/sun/tools/javac/util/Names.java 2010-11-14 06:58:37.000000000 -0800 +++ new/langtools/src/share/classes/com/sun/tools/javac/util/Names.java 2010-11-14 06:58:36.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -150,6 +150,7 @@ public final Name finalize; public final Name java_lang_AutoCloseable; public final Name close; + public final Name addSuppressed; public final Name.Table table; @@ -268,6 +269,7 @@ java_lang_AutoCloseable = fromString("java.lang.AutoCloseable"); close = fromString("close"); + addSuppressed = fromString("addSuppressed"); } protected Name.Table createTable(Options options) { --- old/langtools/test/tools/javac/TryWithResources/TwrSuppression.java 2010-11-14 06:58:37.000000000 -0800 +++ new/langtools/test/tools/javac/TryWithResources/TwrSuppression.java 2010-11-14 06:58:37.000000000 -0800 @@ -36,7 +36,7 @@ throw new RuntimeException(); } } catch(RuntimeException e) { - Throwable[] suppressedExceptions = e.getSuppressedExceptions(); + Throwable[] suppressedExceptions = e.getSuppressed(); int length = suppressedExceptions.length; if (length != 2) throw new RuntimeException("Unexpected length " + length); --- old/langtools/test/tools/javac/TryWithResources/TwrTests.java 2010-11-14 06:58:37.000000000 -0800 +++ new/langtools/test/tools/javac/TryWithResources/TwrTests.java 2010-11-14 06:58:37.000000000 -0800 @@ -90,7 +90,7 @@ } catch (Resource.CreateFailException e) { creationFailuresDetected++; checkCreateFailureId(e.resourceId(), createFailureId); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { throw new AssertionError("Secondary exception suppression failed"); } @@ -112,7 +112,7 @@ } catch (Resource.CreateFailException e) { creationFailuresDetected++; checkCreateFailureId(e.resourceId(), createFailureId); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { throw new AssertionError("Secondary exception suppression failed"); } @@ -134,7 +134,7 @@ } catch (Resource.CreateFailException e) { creationFailuresDetected++; checkCreateFailureId(e.resourceId(), createFailureId); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { throw new AssertionError("Secondary exception suppression failed:" + e); } @@ -158,7 +158,7 @@ } catch (Resource.CreateFailException e) { creationFailuresDetected++; checkCreateFailureId(e.resourceId(), createFailureId); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { throw new AssertionError("Secondary exception suppression failed:" + e); } @@ -181,7 +181,7 @@ } catch (Resource.CreateFailException e) { creationFailuresDetected++; checkCreateFailureId(e.resourceId(), createFailureId); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { throw new AssertionError("Secondary exception suppression failed:" + e); } @@ -207,7 +207,7 @@ } catch (Resource.CreateFailException e) { creationFailuresDetected++; checkCreateFailureId(e.resourceId(), createFailureId); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { throw new AssertionError("Secondary exception suppression failed:" + e); } @@ -231,7 +231,7 @@ } catch (Resource.CreateFailException e) { creationFailuresDetected++; checkCreateFailureId(e.resourceId(), createFailureId); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { throw new AssertionError("Secondary exception suppression failed:" + e); } @@ -259,7 +259,7 @@ } catch (Resource.CreateFailException e) { creationFailuresDetected++; checkCreateFailureId(e.resourceId(), createFailureId); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { throw new AssertionError("Secondary exception suppression failed:" + e); } @@ -310,7 +310,7 @@ * Check for proper suppressed exceptions in proper order. * * @param suppressedExceptions the suppressed exceptions array returned by - * getSuppressedExceptions() + * getSuppressed() * @bitmap a bitmap indicating which suppressed exceptions are expected. * Bit i is set iff id should throw a CloseFailException. */ @@ -376,7 +376,7 @@ } catch (MyKindOfException e) { if (failure == 0) throw new AssertionError("Unexpected MyKindOfException"); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { if (failure == 1) throw new AssertionError("Secondary exception suppression failed"); @@ -388,7 +388,7 @@ throw new AssertionError("CloseFailException: got id " + id + ", expected lg(" + highestCloseFailBit +")"); } - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); + checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit); } checkClosedList(closedList, 1); } @@ -409,7 +409,7 @@ } catch (MyKindOfException e) { if (failure == 0) throw new AssertionError("Unexpected MyKindOfException"); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { if (failure == 1) throw new AssertionError("Secondary exception suppression failed"); @@ -421,7 +421,7 @@ throw new AssertionError("CloseFailException: got id " + id + ", expected lg(" + highestCloseFailBit +")"); } - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); + checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit); } checkClosedList(closedList, 2); } @@ -443,7 +443,7 @@ } catch (MyKindOfException e) { if (failure == 0) throw new AssertionError("Unexpected MyKindOfException"); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { if (failure == 1) throw new AssertionError("Secondary exception suppression failed"); @@ -455,7 +455,7 @@ throw new AssertionError("CloseFailException: got id " + id + ", expected lg(" + highestCloseFailBit +")"); } - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); + checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit); } checkClosedList(closedList, 2); } @@ -477,7 +477,7 @@ } catch (MyKindOfException e) { if (failure == 0) throw new AssertionError("Unexpected MyKindOfException"); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { if (failure == 1) throw new AssertionError("Secondary exception suppression failed"); @@ -489,7 +489,7 @@ throw new AssertionError("CloseFailException: got id " + id + ", expected lg(" + highestCloseFailBit +")"); } - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); + checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit); } checkClosedList(closedList, 3); } @@ -513,7 +513,7 @@ } catch (MyKindOfException e) { if (failure == 0) throw new AssertionError("Unexpected MyKindOfException"); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { if (failure == 1) throw new AssertionError("Secondary exception suppression failed"); @@ -525,7 +525,7 @@ throw new AssertionError("CloseFailException: got id " + id + ", expected lg(" + highestCloseFailBit +")"); } - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); + checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit); } checkClosedList(closedList, 3); } @@ -548,7 +548,7 @@ } catch (MyKindOfException e) { if (failure == 0) throw new AssertionError("Unexpected MyKindOfException"); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { if (failure == 1) throw new AssertionError("Secondary exception suppression failed"); @@ -560,7 +560,7 @@ throw new AssertionError("CloseFailException: got id " + id + ", expected lg(" + highestCloseFailBit +")"); } - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); + checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit); } checkClosedList(closedList, 4); } @@ -586,7 +586,7 @@ } catch (MyKindOfException e) { if (failure == 0) throw new AssertionError("Unexpected MyKindOfException"); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { if (failure == 1) throw new AssertionError("Secondary exception suppression failed"); @@ -598,7 +598,7 @@ throw new AssertionError("CloseFailException: got id " + id + ", expected lg(" + highestCloseFailBit +")"); } - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); + checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit); } checkClosedList(closedList, 4); } @@ -621,7 +621,7 @@ } catch (MyKindOfException e) { if (failure == 0) throw new AssertionError("Unexpected MyKindOfException"); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { if (failure == 1) throw new AssertionError("Secondary exception suppression failed"); @@ -633,7 +633,7 @@ throw new AssertionError("CloseFailException: got id " + id + ", expected lg(" + highestCloseFailBit +")"); } - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); + checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit); } checkClosedList(closedList, 5); } @@ -660,7 +660,7 @@ } catch (MyKindOfException e) { if (failure == 0) throw new AssertionError("Unexpected MyKindOfException"); - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); + checkSuppressedExceptions(e.getSuppressed(), bitMap); } catch (Resource.CloseFailException e) { if (failure == 1) throw new AssertionError("Secondary exception suppression failed"); @@ -672,7 +672,7 @@ throw new AssertionError("CloseFailException: got id " + id + ", expected lg(" + highestCloseFailBit +")"); } - checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); + checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit); } checkClosedList(closedList, 5); }