From 8a710dcc7eaf0fd5df6e468685b593a48f042cb4 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Thu, 1 Aug 2013 12:38:07 +0100 Subject: [PATCH 01/39] 8022061: More ProblemList.txt updates (7/2013) Reviewed-by: alanb, psandoz --- jdk/test/ProblemList.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 0da9ac03f82..595dfb1a30d 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -138,6 +138,9 @@ java/lang/reflect/Method/GenericStringTest.java generic-all java/lang/instrument/RedefineBigClass.sh linux-x64 java/lang/instrument/RetransformBigClass.sh linux-x64 +# 8021230 +java/lang/ThreadLocal/ThreadLocalSupplierTest.java generic-all + ############################################################################ @@ -370,6 +373,9 @@ java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java generic-all # 8020435 java/util/concurrent/CompletableFuture/Basic.java generic-all +# 8020291 +java/util/Random/RandomStreamTest.java generic-all + # 7041639, Solaris DSA keypair generation bug java/util/TimeZone/TimeZoneDatePermissionCheck.sh solaris-all From e1b3c5b5ba5cfb8243d760e99887bbe1015a9d69 Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Tue, 30 Jul 2013 21:11:08 +0400 Subject: [PATCH 02/39] 7192942: (coll) Inefficient calculation of power of two in HashMap Reviewed-by: mduigou --- jdk/src/share/classes/java/util/HashMap.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/java/util/HashMap.java b/jdk/src/share/classes/java/util/HashMap.java index c2aace9db8f..8dfafac8642 100644 --- a/jdk/src/share/classes/java/util/HashMap.java +++ b/jdk/src/share/classes/java/util/HashMap.java @@ -876,13 +876,9 @@ public class HashMap private static int roundUpToPowerOf2(int number) { // assert number >= 0 : "number must be non-negative"; - int rounded = number >= MAXIMUM_CAPACITY + return number >= MAXIMUM_CAPACITY ? MAXIMUM_CAPACITY - : (rounded = Integer.highestOneBit(number)) != 0 - ? (Integer.bitCount(number) > 1) ? rounded << 1 : rounded - : 1; - - return rounded; + : (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1; } /** From ebe38d6cdc5b5a0bde8a6a0b5c9953c69debf06e Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Mon, 29 Jul 2013 12:35:42 +0400 Subject: [PATCH 03/39] 8020669: (fs) Files.readAllBytes() does not read any data when Files.size() is 0 Reviewed-by: alanb, chegar, martin, rriggs --- .../share/classes/java/nio/file/Files.java | 77 +++++++++++++++---- .../java/nio/file/Files/BytesAndLines.java | 23 +++++- 2 files changed, 83 insertions(+), 17 deletions(-) diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java index 586859f17dc..721184c1533 100644 --- a/jdk/src/share/classes/java/nio/file/Files.java +++ b/jdk/src/share/classes/java/nio/file/Files.java @@ -25,10 +25,10 @@ package java.nio.file; -import java.nio.ByteBuffer; import java.nio.file.attribute.*; import java.nio.file.spi.FileSystemProvider; import java.nio.file.spi.FileTypeDetector; +import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.SeekableByteChannel; import java.io.Closeable; @@ -2965,7 +2965,63 @@ public final class Files { } /** - * Read all the bytes from a file. The method ensures that the file is + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; + + /** + * Reads all the bytes from an input stream. Uses {@code initialSize} as a hint + * about how many bytes the stream will have. + * + * @param source + * the input stream to read from + * @param initialSize + * the initial size of the byte array to allocate + * + * @return a byte array containing the bytes read from the file + * + * @throws IOException + * if an I/O error occurs reading from the stream + * @throws OutOfMemoryError + * if an array of the required size cannot be allocated + */ + private static byte[] read(InputStream source, int initialSize) + throws IOException + { + int capacity = initialSize; + byte[] buf = new byte[capacity]; + int nread = 0; + int n; + for (;;) { + // read to EOF which may read more or less than initialSize (eg: file + // is truncated while we are reading) + while ((n = source.read(buf, nread, capacity - nread)) > 0) + nread += n; + + // if last call to source.read() returned -1, we are done + // otherwise, try to read one more byte; if that failed we're done too + if (n < 0 || (n = source.read()) < 0) + break; + + // one more byte was read; need to allocate a larger buffer + if (capacity <= MAX_BUFFER_SIZE - capacity) { + capacity = Math.max(capacity << 1, BUFFER_SIZE); + } else { + if (capacity == MAX_BUFFER_SIZE) + throw new OutOfMemoryError("Required array size too large"); + capacity = MAX_BUFFER_SIZE; + } + buf = Arrays.copyOf(buf, capacity); + buf[nread++] = (byte)n; + } + return (capacity == nread) ? buf : Arrays.copyOf(buf, nread); + } + + /** + * Reads all the bytes from a file. The method ensures that the file is * closed when all bytes have been read or an I/O error, or other runtime * exception, is thrown. * @@ -2989,22 +3045,13 @@ public final class Files { * method is invoked to check read access to the file. */ public static byte[] readAllBytes(Path path) throws IOException { - try (FileChannel fc = FileChannel.open(path)) { + try (FileChannel fc = FileChannel.open(path); + InputStream is = Channels.newInputStream(fc)) { long size = fc.size(); - if (size > (long)Integer.MAX_VALUE) + if (size > (long)MAX_BUFFER_SIZE) throw new OutOfMemoryError("Required array size too large"); - byte[] arr = new byte[(int)size]; - ByteBuffer bb = ByteBuffer.wrap(arr); - while (bb.hasRemaining()) { - if (fc.read(bb) < 0) { - // truncated - break; - } - } - - int nread = bb.position(); - return (nread == size) ? arr : Arrays.copyOf(arr, nread); + return read(is, (int)size); } } diff --git a/jdk/test/java/nio/file/Files/BytesAndLines.java b/jdk/test/java/nio/file/Files/BytesAndLines.java index 2833c99cb73..15fb6a4251b 100644 --- a/jdk/test/java/nio/file/Files/BytesAndLines.java +++ b/jdk/test/java/nio/file/Files/BytesAndLines.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 7006126 + * @bug 7006126 8020669 * @summary Unit test for methods for Files readAllBytes, readAllLines and * and write methods. */ @@ -82,6 +82,16 @@ public class BytesAndLines { write(file, lines, Charset.defaultCharset(), opts); throw new RuntimeException("NullPointerException expected"); } catch (NullPointerException ignore) { } + + // read from procfs + if (System.getProperty("os.name").equals("Linux")) { + // Refer to the Linux proc(5) man page for details about /proc/self/stat file + // procfs reports it to be zero sized, even though data can be read from it + String statFile = "/proc/self/stat"; + Path pathStat = Paths.get(statFile); + byte[] data = Files.readAllBytes(pathStat); + assertTrue(data.length > 0, "Files.readAllBytes('" + statFile + "') failed to read"); + } } @@ -174,6 +184,16 @@ public class BytesAndLines { throw new RuntimeException("NullPointerException expected"); } catch (NullPointerException ignore) { } + // read from procfs + if (System.getProperty("os.name").equals("Linux")) { + // Refer to the Linux proc(5) man page for details about /proc/self/status file + // procfs reports this file to be zero sized, even though data can be read from it + String statusFile = "/proc/self/status"; + Path pathStatus = Paths.get(statusFile); + lines = Files.readAllLines(pathStatus, US_ASCII); + assertTrue(lines.size() > 0, "Files.readAllLines('" + pathStatus + "') failed to read"); + } + } finally { delete(tmpfile); } @@ -242,7 +262,6 @@ public class BytesAndLines { } finally { delete(tmpfile); } - } static void assertTrue(boolean expr, String errmsg) { From b431c6929d129e7e74b1327ec3976cc6dc43443e Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Thu, 1 Aug 2013 07:34:30 -0700 Subject: [PATCH 04/39] 7127524: P11TlsPrfGenerator has anonymous inner class with serialVersionUID Reviewed-by: vinnie --- .../sun/security/pkcs11/P11TlsPrfGenerator.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java b/jdk/src/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java index 8f75b1ec37e..86bee16a72f 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java +++ b/jdk/src/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -96,10 +96,15 @@ final class P11TlsPrfGenerator extends KeyGeneratorSpi { } } - // SecretKeySpec does not allow zero length keys, so we define our own class. + // SecretKeySpec does not allow zero length keys, so we define our + // own class. + // + // As an anonymous class cannot make any guarantees about serialization + // compatibility, it is nonsensical for an anonymous class to define a + // serialVersionUID. Suppress warnings relative to missing serialVersionUID + // field in the anonymous subclass of serializable SecretKey. + @SuppressWarnings("serial") private static final SecretKey NULL_KEY = new SecretKey() { - private static final long serialVersionUID = -8090049519656411362L; - public byte[] getEncoded() { return new byte[0]; } From 98fb15899e845a65ee1a7437f9a7b932f211eca9 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Thu, 1 Aug 2013 16:53:40 +0100 Subject: [PATCH 05/39] 8022087: Fix doclint issues in j.u.Deque & Queue Reviewed-by: chegar, darcy --- jdk/src/share/classes/java/util/Deque.java | 149 +++++++++++---------- jdk/src/share/classes/java/util/Queue.java | 71 +++++----- 2 files changed, 112 insertions(+), 108 deletions(-) diff --git a/jdk/src/share/classes/java/util/Deque.java b/jdk/src/share/classes/java/util/Deque.java index 051ae9cca46..f6511417f33 100644 --- a/jdk/src/share/classes/java/util/Deque.java +++ b/jdk/src/share/classes/java/util/Deque.java @@ -38,7 +38,7 @@ package java.util; /** * A linear collection that supports element insertion and removal at * both ends. The name deque is short for "double ended queue" - * and is usually pronounced "deck". Most Deque + * and is usually pronounced "deck". Most {@code Deque} * implementations place no fixed limits on the number of elements * they may contain, but this interface supports capacity-restricted * deques as well as those with no fixed size limit. @@ -47,10 +47,10 @@ package java.util; * ends of the deque. Methods are provided to insert, remove, and * examine the element. Each of these methods exists in two forms: * one throws an exception if the operation fails, the other returns a - * special value (either null or false, depending on + * special value (either {@code null} or {@code false}, depending on * the operation). The latter form of the insert operation is * designed specifically for use with capacity-restricted - * Deque implementations; in most implementations, insert + * {@code Deque} implementations; in most implementations, insert * operations cannot fail. * *

The twelve methods described above are summarized in the @@ -58,6 +58,7 @@ package java.util; * *

* + * * * * @@ -72,38 +73,39 @@ package java.util; * * * - * - * - * - * + * + * + * + * * * * - * - * - * - * + * + * + * + * * * * - * - * - * - * + * + * + * + * * *
Summary of Deque methods
First Element (Head)
Insert{@link #addFirst addFirst(e)}{@link #offerFirst offerFirst(e)}{@link #addLast addLast(e)}{@link #offerLast offerLast(e)}{@link Deque#addFirst addFirst(e)}{@link Deque#offerFirst offerFirst(e)}{@link Deque#addLast addLast(e)}{@link Deque#offerLast offerLast(e)}
Remove{@link #removeFirst removeFirst()}{@link #pollFirst pollFirst()}{@link #removeLast removeLast()}{@link #pollLast pollLast()}{@link Deque#removeFirst removeFirst()}{@link Deque#pollFirst pollFirst()}{@link Deque#removeLast removeLast()}{@link Deque#pollLast pollLast()}
Examine{@link #getFirst getFirst()}{@link #peekFirst peekFirst()}{@link #getLast getLast()}{@link #peekLast peekLast()}{@link Deque#getFirst getFirst()}{@link Deque#peekFirst peekFirst()}{@link Deque#getLast getLast()}{@link Deque#peekLast peekLast()}
* *

This interface extends the {@link Queue} interface. When a deque is * used as a queue, FIFO (First-In-First-Out) behavior results. Elements are * added at the end of the deque and removed from the beginning. The methods - * inherited from the Queue interface are precisely equivalent to - * Deque methods as indicated in the following table: + * inherited from the {@code Queue} interface are precisely equivalent to + * {@code Deque} methods as indicated in the following table: * *

* + * * - * - * + * + * * * * @@ -135,13 +137,14 @@ package java.util; * interface should be used in preference to the legacy {@link Stack} class. * When a deque is used as a stack, elements are pushed and popped from the * beginning of the deque. Stack methods are precisely equivalent to - * Deque methods as indicated in the table below: + * {@code Deque} methods as indicated in the table below: * *

*

Comparison of Queue and Deque methods
Queue Method Equivalent Deque Method {@code Queue} Method Equivalent {@code Deque} Method
{@link java.util.Queue#add add(e)}
+ * * * - * + * * * * @@ -168,18 +171,18 @@ package java.util; *

Unlike the {@link List} interface, this interface does not * provide support for indexed access to elements. * - *

While Deque implementations are not strictly required + *

While {@code Deque} implementations are not strictly required * to prohibit the insertion of null elements, they are strongly - * encouraged to do so. Users of any Deque implementations + * encouraged to do so. Users of any {@code Deque} implementations * that do allow null elements are strongly encouraged not to * take advantage of the ability to insert nulls. This is so because - * null is used as a special return value by various methods + * {@code null} is used as a special return value by various methods * to indicated that the deque is empty. * - *

Deque implementations generally do not define - * element-based versions of the equals and hashCode + *

{@code Deque} implementations generally do not define + * element-based versions of the {@code equals} and {@code hashCode} * methods, but instead inherit the identity-based versions from class - * Object. + * {@code Object}. * *

This interface is a member of the Java Collections @@ -190,13 +193,13 @@ package java.util; * @since 1.6 * @param the type of elements held in this collection */ - public interface Deque extends Queue { /** * Inserts the specified element at the front of this deque if it is - * possible to do so immediately without violating capacity restrictions. - * When using a capacity-restricted deque, it is generally preferable to - * use method {@link #offerFirst}. + * possible to do so immediately without violating capacity restrictions, + * throwing an {@code IllegalStateException} if no space is currently + * available. When using a capacity-restricted deque, it is generally + * preferable to use method {@link #offerFirst}. * * @param e the element to add * @throws IllegalStateException if the element cannot be added at this @@ -212,9 +215,10 @@ public interface Deque extends Queue { /** * Inserts the specified element at the end of this deque if it is - * possible to do so immediately without violating capacity restrictions. - * When using a capacity-restricted deque, it is generally preferable to - * use method {@link #offerLast}. + * possible to do so immediately without violating capacity restrictions, + * throwing an {@code IllegalStateException} if no space is currently + * available. When using a capacity-restricted deque, it is generally + * preferable to use method {@link #offerLast}. * *

This method is equivalent to {@link #add}. * @@ -237,8 +241,8 @@ public interface Deque extends Queue { * which can fail to insert an element only by throwing an exception. * * @param e the element to add - * @return true if the element was added to this deque, else - * false + * @return {@code true} if the element was added to this deque, else + * {@code false} * @throws ClassCastException if the class of the specified element * prevents it from being added to this deque * @throws NullPointerException if the specified element is null and this @@ -255,8 +259,8 @@ public interface Deque extends Queue { * which can fail to insert an element only by throwing an exception. * * @param e the element to add - * @return true if the element was added to this deque, else - * false + * @return {@code true} if the element was added to this deque, else + * {@code false} * @throws ClassCastException if the class of the specified element * prevents it from being added to this deque * @throws NullPointerException if the specified element is null and this @@ -288,17 +292,17 @@ public interface Deque extends Queue { /** * Retrieves and removes the first element of this deque, - * or returns null if this deque is empty. + * or returns {@code null} if this deque is empty. * - * @return the head of this deque, or null if this deque is empty + * @return the head of this deque, or {@code null} if this deque is empty */ E pollFirst(); /** * Retrieves and removes the last element of this deque, - * or returns null if this deque is empty. + * or returns {@code null} if this deque is empty. * - * @return the tail of this deque, or null if this deque is empty + * @return the tail of this deque, or {@code null} if this deque is empty */ E pollLast(); @@ -325,31 +329,31 @@ public interface Deque extends Queue { /** * Retrieves, but does not remove, the first element of this deque, - * or returns null if this deque is empty. + * or returns {@code null} if this deque is empty. * - * @return the head of this deque, or null if this deque is empty + * @return the head of this deque, or {@code null} if this deque is empty */ E peekFirst(); /** * Retrieves, but does not remove, the last element of this deque, - * or returns null if this deque is empty. + * or returns {@code null} if this deque is empty. * - * @return the tail of this deque, or null if this deque is empty + * @return the tail of this deque, or {@code null} if this deque is empty */ E peekLast(); /** * Removes the first occurrence of the specified element from this deque. * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element e such that + * More formally, removes the first element {@code e} such that * (o==null ? e==null : o.equals(e)) * (if such an element exists). - * Returns true if this deque contained the specified element + * Returns {@code true} if this deque contained the specified element * (or equivalently, if this deque changed as a result of the call). * * @param o element to be removed from this deque, if present - * @return true if an element was removed as a result of this call + * @return {@code true} if an element was removed as a result of this call * @throws ClassCastException if the class of the specified element * is incompatible with this deque * (optional) @@ -362,14 +366,14 @@ public interface Deque extends Queue { /** * Removes the last occurrence of the specified element from this deque. * If the deque does not contain the element, it is unchanged. - * More formally, removes the last element e such that + * More formally, removes the last element {@code e} such that * (o==null ? e==null : o.equals(e)) * (if such an element exists). - * Returns true if this deque contained the specified element + * Returns {@code true} if this deque contained the specified element * (or equivalently, if this deque changed as a result of the call). * * @param o element to be removed from this deque, if present - * @return true if an element was removed as a result of this call + * @return {@code true} if an element was removed as a result of this call * @throws ClassCastException if the class of the specified element * is incompatible with this deque * (optional) @@ -385,15 +389,15 @@ public interface Deque extends Queue { * Inserts the specified element into the queue represented by this deque * (in other words, at the tail of this deque) if it is possible to do so * immediately without violating capacity restrictions, returning - * true upon success and throwing an - * IllegalStateException if no space is currently available. + * {@code true} upon success and throwing an + * {@code IllegalStateException} if no space is currently available. * When using a capacity-restricted deque, it is generally preferable to * use {@link #offer(Object) offer}. * *

This method is equivalent to {@link #addLast}. * * @param e the element to add - * @return true (as specified by {@link Collection#add}) + * @return {@code true} (as specified by {@link Collection#add}) * @throws IllegalStateException if the element cannot be added at this * time due to capacity restrictions * @throws ClassCastException if the class of the specified element @@ -409,7 +413,7 @@ public interface Deque extends Queue { * Inserts the specified element into the queue represented by this deque * (in other words, at the tail of this deque) if it is possible to do so * immediately without violating capacity restrictions, returning - * true upon success and false if no space is currently + * {@code true} upon success and {@code false} if no space is currently * available. When using a capacity-restricted deque, this method is * generally preferable to the {@link #add} method, which can fail to * insert an element only by throwing an exception. @@ -417,8 +421,8 @@ public interface Deque extends Queue { *

This method is equivalent to {@link #offerLast}. * * @param e the element to add - * @return true if the element was added to this deque, else - * false + * @return {@code true} if the element was added to this deque, else + * {@code false} * @throws ClassCastException if the class of the specified element * prevents it from being added to this deque * @throws NullPointerException if the specified element is null and this @@ -444,11 +448,11 @@ public interface Deque extends Queue { /** * Retrieves and removes the head of the queue represented by this deque * (in other words, the first element of this deque), or returns - * null if this deque is empty. + * {@code null} if this deque is empty. * *

This method is equivalent to {@link #pollFirst()}. * - * @return the first element of this deque, or null if + * @return the first element of this deque, or {@code null} if * this deque is empty */ E poll(); @@ -469,12 +473,12 @@ public interface Deque extends Queue { /** * Retrieves, but does not remove, the head of the queue represented by * this deque (in other words, the first element of this deque), or - * returns null if this deque is empty. + * returns {@code null} if this deque is empty. * *

This method is equivalent to {@link #peekFirst()}. * * @return the head of the queue represented by this deque, or - * null if this deque is empty + * {@code null} if this deque is empty */ E peek(); @@ -484,9 +488,8 @@ public interface Deque extends Queue { /** * Pushes an element onto the stack represented by this deque (in other * words, at the head of this deque) if it is possible to do so - * immediately without violating capacity restrictions, returning - * true upon success and throwing an - * IllegalStateException if no space is currently available. + * immediately without violating capacity restrictions, throwing an + * {@code IllegalStateException} if no space is currently available. * *

This method is equivalent to {@link #addFirst}. * @@ -520,16 +523,16 @@ public interface Deque extends Queue { /** * Removes the first occurrence of the specified element from this deque. * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element e such that + * More formally, removes the first element {@code e} such that * (o==null ? e==null : o.equals(e)) * (if such an element exists). - * Returns true if this deque contained the specified element + * Returns {@code true} if this deque contained the specified element * (or equivalently, if this deque changed as a result of the call). * - *

This method is equivalent to {@link #removeFirstOccurrence}. + *

This method is equivalent to {@link #removeFirstOccurrence(Object)}. * * @param o element to be removed from this deque, if present - * @return true if an element was removed as a result of this call + * @return {@code true} if an element was removed as a result of this call * @throws ClassCastException if the class of the specified element * is incompatible with this deque * (optional) @@ -540,13 +543,13 @@ public interface Deque extends Queue { boolean remove(Object o); /** - * Returns true if this deque contains the specified element. - * More formally, returns true if and only if this deque contains - * at least one element e such that + * Returns {@code true} if this deque contains the specified element. + * More formally, returns {@code true} if and only if this deque contains + * at least one element {@code e} such that * (o==null ? e==null : o.equals(e)). * * @param o element whose presence in this deque is to be tested - * @return true if this deque contains the specified element + * @return {@code true} if this deque contains the specified element * @throws ClassCastException if the type of the specified element * is incompatible with this deque * (optional) diff --git a/jdk/src/share/classes/java/util/Queue.java b/jdk/src/share/classes/java/util/Queue.java index 124cc449426..4d345df7e6f 100644 --- a/jdk/src/share/classes/java/util/Queue.java +++ b/jdk/src/share/classes/java/util/Queue.java @@ -41,14 +41,15 @@ package java.util; * queues provide additional insertion, extraction, and inspection * operations. Each of these methods exists in two forms: one throws * an exception if the operation fails, the other returns a special - * value (either null or false, depending on the + * value (either {@code null} or {@code false}, depending on the * operation). The latter form of the insert operation is designed - * specifically for use with capacity-restricted Queue + * specifically for use with capacity-restricted {@code Queue} * implementations; in most implementations, insert operations cannot * fail. * *

*

Comparison of Stack and Deque methods
Stack Method Equivalent Deque Method Equivalent {@code Deque} Method
{@link #push push(e)}
+ * * * * @@ -56,18 +57,18 @@ package java.util; * * * - * - * + * + * * * * - * - * + * + * * * * - * - * + * + * * *
Summary of Queue methods
Throws exception
Insert{@link #add add(e)}{@link #offer offer(e)}{@link Queue#add add(e)}{@link Queue#offer offer(e)}
Remove{@link #remove remove()}{@link #poll poll()}{@link Queue#remove remove()}{@link Queue#poll poll()}
Examine{@link #element element()}{@link #peek peek()}{@link Queue#element element()}{@link Queue#peek peek()}
* @@ -79,15 +80,15 @@ package java.util; * Whatever the ordering used, the head of the queue is that * element which would be removed by a call to {@link #remove() } or * {@link #poll()}. In a FIFO queue, all new elements are inserted at - * the tail of the queue. Other kinds of queues may use - * different placement rules. Every Queue implementation + * the tail of the queue. Other kinds of queues may use + * different placement rules. Every {@code Queue} implementation * must specify its ordering properties. * *

The {@link #offer offer} method inserts an element if possible, - * otherwise returning false. This differs from the {@link + * otherwise returning {@code false}. This differs from the {@link * java.util.Collection#add Collection.add} method, which can fail to * add an element only by throwing an unchecked exception. The - * offer method is designed for use when failure is a normal, + * {@code offer} method is designed for use when failure is a normal, * rather than exceptional occurrence, for example, in fixed-capacity * (or "bounded") queues. * @@ -95,32 +96,32 @@ package java.util; * return the head of the queue. * Exactly which element is removed from the queue is a * function of the queue's ordering policy, which differs from - * implementation to implementation. The remove() and - * poll() methods differ only in their behavior when the - * queue is empty: the remove() method throws an exception, - * while the poll() method returns null. + * implementation to implementation. The {@code remove()} and + * {@code poll()} methods differ only in their behavior when the + * queue is empty: the {@code remove()} method throws an exception, + * while the {@code poll()} method returns {@code null}. * *

The {@link #element()} and {@link #peek()} methods return, but do * not remove, the head of the queue. * - *

The Queue interface does not define the blocking queue + *

The {@code Queue} interface does not define the blocking queue * methods, which are common in concurrent programming. These methods, * which wait for elements to appear or for space to become available, are * defined in the {@link java.util.concurrent.BlockingQueue} interface, which * extends this interface. * - *

Queue implementations generally do not allow insertion - * of null elements, although some implementations, such as - * {@link LinkedList}, do not prohibit insertion of null. - * Even in the implementations that permit it, null should - * not be inserted into a Queue, as null is also - * used as a special return value by the poll method to + *

{@code Queue} implementations generally do not allow insertion + * of {@code null} elements, although some implementations, such as + * {@link LinkedList}, do not prohibit insertion of {@code null}. + * Even in the implementations that permit it, {@code null} should + * not be inserted into a {@code Queue}, as {@code null} is also + * used as a special return value by the {@code poll} method to * indicate that the queue contains no elements. * - *

Queue implementations generally do not define - * element-based versions of methods equals and - * hashCode but instead inherit the identity based versions - * from class Object, because element-based equality is not + *

{@code Queue} implementations generally do not define + * element-based versions of methods {@code equals} and + * {@code hashCode} but instead inherit the identity based versions + * from class {@code Object}, because element-based equality is not * always well-defined for queues with the same elements but different * ordering properties. * @@ -145,11 +146,11 @@ public interface Queue extends Collection { /** * Inserts the specified element into this queue if it is possible to do so * immediately without violating capacity restrictions, returning - * true upon success and throwing an IllegalStateException + * {@code true} upon success and throwing an {@code IllegalStateException} * if no space is currently available. * * @param e the element to add - * @return true (as specified by {@link Collection#add}) + * @return {@code true} (as specified by {@link Collection#add}) * @throws IllegalStateException if the element cannot be added at this * time due to capacity restrictions * @throws ClassCastException if the class of the specified element @@ -169,8 +170,8 @@ public interface Queue extends Collection { * by throwing an exception. * * @param e the element to add - * @return true if the element was added to this queue, else - * false + * @return {@code true} if the element was added to this queue, else + * {@code false} * @throws ClassCastException if the class of the specified element * prevents it from being added to this queue * @throws NullPointerException if the specified element is null and @@ -192,9 +193,9 @@ public interface Queue extends Collection { /** * Retrieves and removes the head of this queue, - * or returns null if this queue is empty. + * or returns {@code null} if this queue is empty. * - * @return the head of this queue, or null if this queue is empty + * @return the head of this queue, or {@code null} if this queue is empty */ E poll(); @@ -210,9 +211,9 @@ public interface Queue extends Collection { /** * Retrieves, but does not remove, the head of this queue, - * or returns null if this queue is empty. + * or returns {@code null} if this queue is empty. * - * @return the head of this queue, or null if this queue is empty + * @return the head of this queue, or {@code null} if this queue is empty */ E peek(); } From 3e78508945cf6f80e607e22de4c22dae92cf313b Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Thu, 1 Aug 2013 15:28:57 +0100 Subject: [PATCH 06/39] 8020016: Numerous splitereator impls do not throw NPE for null Consumers Reviewed-by: mduigou, alanb, henryjen --- .../java/util/stream/SpinedBuffer.java | 9 ++++ .../java/util/stream/StreamSpliterators.java | 33 ++++++++++++++ .../classes/java/util/stream/Streams.java | 25 +++++++++++ ...SpliteratorTraversingAndSplittingTest.java | 25 ++++++++++- .../util/stream/SpliteratorTestHelper.java | 45 +++++++++++++++++++ 5 files changed, 136 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/util/stream/SpinedBuffer.java b/jdk/src/share/classes/java/util/stream/SpinedBuffer.java index 77c375612ea..7312c984a51 100644 --- a/jdk/src/share/classes/java/util/stream/SpinedBuffer.java +++ b/jdk/src/share/classes/java/util/stream/SpinedBuffer.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.PrimitiveIterator; import java.util.Spliterator; import java.util.Spliterators; @@ -317,6 +318,8 @@ class SpinedBuffer @Override public boolean tryAdvance(Consumer consumer) { + Objects.requireNonNull(consumer); + if (splSpineIndex < lastSpineIndex || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) { consumer.accept(splChunk[splElementIndex++]); @@ -334,6 +337,8 @@ class SpinedBuffer @Override public void forEachRemaining(Consumer consumer) { + Objects.requireNonNull(consumer); + if (splSpineIndex < lastSpineIndex || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) { int i = splElementIndex; @@ -634,6 +639,8 @@ class SpinedBuffer @Override public boolean tryAdvance(T_CONS consumer) { + Objects.requireNonNull(consumer); + if (splSpineIndex < lastSpineIndex || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) { arrayForOne(splChunk, splElementIndex++, consumer); @@ -651,6 +658,8 @@ class SpinedBuffer @Override public void forEachRemaining(T_CONS consumer) { + Objects.requireNonNull(consumer); + if (splSpineIndex < lastSpineIndex || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) { int i = splElementIndex; diff --git a/jdk/src/share/classes/java/util/stream/StreamSpliterators.java b/jdk/src/share/classes/java/util/stream/StreamSpliterators.java index d0dc61ed1e0..1a27e98ff29 100644 --- a/jdk/src/share/classes/java/util/stream/StreamSpliterators.java +++ b/jdk/src/share/classes/java/util/stream/StreamSpliterators.java @@ -25,6 +25,7 @@ package java.util.stream; import java.util.Comparator; +import java.util.Objects; import java.util.Spliterator; import java.util.concurrent.atomic.AtomicLong; import java.util.function.BooleanSupplier; @@ -294,6 +295,7 @@ class StreamSpliterators { @Override public boolean tryAdvance(Consumer consumer) { + Objects.requireNonNull(consumer); boolean hasNext = doAdvance(); if (hasNext) consumer.accept(buffer.get(nextToConsume)); @@ -303,6 +305,7 @@ class StreamSpliterators { @Override public void forEachRemaining(Consumer consumer) { if (buffer == null && !finished) { + Objects.requireNonNull(consumer); init(); ph.wrapAndCopyInto((Sink) consumer::accept, spliterator); @@ -350,6 +353,7 @@ class StreamSpliterators { @Override public boolean tryAdvance(IntConsumer consumer) { + Objects.requireNonNull(consumer); boolean hasNext = doAdvance(); if (hasNext) consumer.accept(buffer.get(nextToConsume)); @@ -359,6 +363,7 @@ class StreamSpliterators { @Override public void forEachRemaining(IntConsumer consumer) { if (buffer == null && !finished) { + Objects.requireNonNull(consumer); init(); ph.wrapAndCopyInto((Sink.OfInt) consumer::accept, spliterator); @@ -406,6 +411,7 @@ class StreamSpliterators { @Override public boolean tryAdvance(LongConsumer consumer) { + Objects.requireNonNull(consumer); boolean hasNext = doAdvance(); if (hasNext) consumer.accept(buffer.get(nextToConsume)); @@ -415,6 +421,7 @@ class StreamSpliterators { @Override public void forEachRemaining(LongConsumer consumer) { if (buffer == null && !finished) { + Objects.requireNonNull(consumer); init(); ph.wrapAndCopyInto((Sink.OfLong) consumer::accept, spliterator); @@ -462,6 +469,7 @@ class StreamSpliterators { @Override public boolean tryAdvance(DoubleConsumer consumer) { + Objects.requireNonNull(consumer); boolean hasNext = doAdvance(); if (hasNext) consumer.accept(buffer.get(nextToConsume)); @@ -471,6 +479,7 @@ class StreamSpliterators { @Override public void forEachRemaining(DoubleConsumer consumer) { if (buffer == null && !finished) { + Objects.requireNonNull(consumer); init(); ph.wrapAndCopyInto((Sink.OfDouble) consumer::accept, spliterator); @@ -696,6 +705,8 @@ class StreamSpliterators { @Override public boolean tryAdvance(Consumer action) { + Objects.requireNonNull(action); + if (sliceOrigin >= fence) return false; @@ -713,6 +724,8 @@ class StreamSpliterators { @Override public void forEachRemaining(Consumer action) { + Objects.requireNonNull(action); + if (sliceOrigin >= fence) return; @@ -754,6 +767,8 @@ class StreamSpliterators { @Override public boolean tryAdvance(T_CONS action) { + Objects.requireNonNull(action); + if (sliceOrigin >= fence) return false; @@ -771,6 +786,8 @@ class StreamSpliterators { @Override public void forEachRemaining(T_CONS action) { + Objects.requireNonNull(action); + if (sliceOrigin >= fence) return; @@ -985,6 +1002,8 @@ class StreamSpliterators { @Override public boolean tryAdvance(Consumer action) { + Objects.requireNonNull(action); + while (permitStatus() != PermitStatus.NO_MORE) { if (!s.tryAdvance(this)) return false; @@ -999,6 +1018,8 @@ class StreamSpliterators { @Override public void forEachRemaining(Consumer action) { + Objects.requireNonNull(action); + ArrayBuffer.OfRef sb = null; PermitStatus permitStatus; while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) { @@ -1051,6 +1072,8 @@ class StreamSpliterators { @Override public boolean tryAdvance(T_CONS action) { + Objects.requireNonNull(action); + while (permitStatus() != PermitStatus.NO_MORE) { if (!s.tryAdvance((T_CONS) this)) return false; @@ -1066,6 +1089,8 @@ class StreamSpliterators { @Override public void forEachRemaining(T_CONS action) { + Objects.requireNonNull(action); + T_BUFF sb = null; PermitStatus permitStatus; while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) { @@ -1237,6 +1262,8 @@ class StreamSpliterators { @Override public boolean tryAdvance(Consumer action) { + Objects.requireNonNull(action); + action.accept(s.get()); return true; } @@ -1260,6 +1287,8 @@ class StreamSpliterators { @Override public boolean tryAdvance(IntConsumer action) { + Objects.requireNonNull(action); + action.accept(s.getAsInt()); return true; } @@ -1283,6 +1312,8 @@ class StreamSpliterators { @Override public boolean tryAdvance(LongConsumer action) { + Objects.requireNonNull(action); + action.accept(s.getAsLong()); return true; } @@ -1306,6 +1337,8 @@ class StreamSpliterators { @Override public boolean tryAdvance(DoubleConsumer action) { + Objects.requireNonNull(action); + action.accept(s.getAsDouble()); return true; } diff --git a/jdk/src/share/classes/java/util/stream/Streams.java b/jdk/src/share/classes/java/util/stream/Streams.java index fe83b9708df..15c3dcae497 100644 --- a/jdk/src/share/classes/java/util/stream/Streams.java +++ b/jdk/src/share/classes/java/util/stream/Streams.java @@ -25,6 +25,7 @@ package java.util.stream; import java.util.Comparator; +import java.util.Objects; import java.util.Spliterator; import java.util.function.Consumer; import java.util.function.DoubleConsumer; @@ -80,6 +81,8 @@ final class Streams { @Override public boolean tryAdvance(IntConsumer consumer) { + Objects.requireNonNull(consumer); + final int i = from; if (i < upTo) { from++; @@ -96,6 +99,8 @@ final class Streams { @Override public void forEachRemaining(IntConsumer consumer) { + Objects.requireNonNull(consumer); + int i = from; final int hUpTo = upTo; int hLast = last; @@ -199,6 +204,8 @@ final class Streams { @Override public boolean tryAdvance(LongConsumer consumer) { + Objects.requireNonNull(consumer); + final long i = from; if (i < upTo) { from++; @@ -215,6 +222,8 @@ final class Streams { @Override public void forEachRemaining(LongConsumer consumer) { + Objects.requireNonNull(consumer); + long i = from; final long hUpTo = upTo; int hLast = last; @@ -388,6 +397,8 @@ final class Streams { @Override public boolean tryAdvance(Consumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -400,6 +411,8 @@ final class Streams { @Override public void forEachRemaining(Consumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -475,6 +488,8 @@ final class Streams { @Override public boolean tryAdvance(IntConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -487,6 +502,8 @@ final class Streams { @Override public void forEachRemaining(IntConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -562,6 +579,8 @@ final class Streams { @Override public boolean tryAdvance(LongConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -574,6 +593,8 @@ final class Streams { @Override public void forEachRemaining(LongConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -649,6 +670,8 @@ final class Streams { @Override public boolean tryAdvance(DoubleConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -661,6 +684,8 @@ final class Streams { @Override public void forEachRemaining(DoubleConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; diff --git a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java index 6da6214e1ca..458c410c252 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java +++ b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java @@ -81,6 +81,10 @@ import java.util.function.UnaryOperator; import static org.testng.Assert.*; import static org.testng.Assert.assertEquals; +/** + * @test + * @bug 8020016 + */ @Test public class SpliteratorTraversingAndSplittingTest { @@ -386,11 +390,23 @@ public class SpliteratorTraversingAndSplittingTest { db.addCollection(CopyOnWriteArraySet::new); - if (size == 1) { + if (size == 0) { + db.addCollection(c -> Collections.emptySet()); + db.addList(c -> Collections.emptyList()); + } + else if (size == 1) { db.addCollection(c -> Collections.singleton(exp.get(0))); db.addCollection(c -> Collections.singletonList(exp.get(0))); } + { + Integer[] ai = new Integer[size]; + Arrays.fill(ai, 1); + db.add(String.format("Collections.nCopies(%d, 1)", exp.size()), + Arrays.asList(ai), + () -> Collections.nCopies(exp.size(), 1).spliterator()); + } + // Collections.synchronized/unmodifiable/checked wrappers db.addCollection(Collections::unmodifiableCollection); db.addCollection(c -> Collections.unmodifiableSet(new HashSet<>(c))); @@ -454,6 +470,13 @@ public class SpliteratorTraversingAndSplittingTest { db.addMap(ConcurrentHashMap::new); db.addMap(ConcurrentSkipListMap::new); + + if (size == 0) { + db.addMap(m -> Collections.emptyMap()); + } + else if (size == 1) { + db.addMap(m -> Collections.singletonMap(exp.get(0), exp.get(0))); + } } return spliteratorDataProvider = data.toArray(new Object[0][]); diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java b/jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java index 4d221735315..a3446ffd6cc 100644 --- a/jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java +++ b/jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java @@ -22,6 +22,8 @@ */ package java.util.stream; +import org.testng.annotations.Test; + import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -154,6 +156,7 @@ public class SpliteratorTestHelper { Collection exp = Collections.unmodifiableList(fromForEach); + testNullPointerException(supplier); testForEach(exp, supplier, boxingAdapter, asserter); testTryAdvance(exp, supplier, boxingAdapter, asserter); testMixedTryAdvanceForEach(exp, supplier, boxingAdapter, asserter); @@ -166,6 +169,31 @@ public class SpliteratorTestHelper { // + private static > void testNullPointerException(Supplier s) { + S sp = s.get(); + // Have to check instances and use casts to avoid tripwire messages and + // directly test the primitive methods + if (sp instanceof Spliterator.OfInt) { + Spliterator.OfInt psp = (Spliterator.OfInt) sp; + executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((IntConsumer) null)); + executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((IntConsumer) null)); + } + else if (sp instanceof Spliterator.OfLong) { + Spliterator.OfLong psp = (Spliterator.OfLong) sp; + executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((LongConsumer) null)); + executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((LongConsumer) null)); + } + else if (sp instanceof Spliterator.OfDouble) { + Spliterator.OfDouble psp = (Spliterator.OfDouble) sp; + executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((DoubleConsumer) null)); + executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((DoubleConsumer) null)); + } + else { + executeAndCatch(NullPointerException.class, () -> sp.forEachRemaining(null)); + executeAndCatch(NullPointerException.class, () -> sp.tryAdvance(null)); + } + } + private static > void testForEach( Collection exp, Supplier supplier, @@ -573,6 +601,23 @@ public class SpliteratorTestHelper { } } + private static void executeAndCatch(Class expected, Runnable r) { + Exception caught = null; + try { + r.run(); + } + catch (Exception e) { + caught = e; + } + + assertNotNull(caught, + String.format("No Exception was thrown, expected an Exception of %s to be thrown", + expected.getName())); + assertTrue(expected.isInstance(caught), + String.format("Exception thrown %s not an instance of %s", + caught.getClass().getName(), expected.getName())); + } + static void mixedTraverseAndSplit(Consumer b, Spliterator splTop) { Spliterator spl1, spl2, spl3; splTop.tryAdvance(b); From 9688bbb771ee3a2138ed150930c4e43d0c7077a6 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Fri, 2 Aug 2013 08:59:37 +0800 Subject: [PATCH 07/39] 8021789: jarsigner parses alias as command line option (depending on locale) Reviewed-by: vinnie --- .../sun/security/tools/jarsigner/Main.java | 27 ++++--- .../sun/security/tools/jarsigner/collator.sh | 76 +++++++++++++++++++ 2 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 jdk/test/sun/security/tools/jarsigner/collator.sh diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java index c5ed6b1facf..72ce4617bf6 100644 --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java @@ -291,7 +291,8 @@ public class Main { String flags = args[n]; String modifier = null; - if (flags.charAt(0) == '-') { + + if (flags.startsWith("-")) { int pos = flags.indexOf(':'); if (pos > 0) { modifier = flags.substring(pos+1); @@ -299,7 +300,14 @@ public class Main { } } - if (collator.compare(flags, "-keystore") == 0) { + if (!flags.startsWith("-")) { + if (jarfile == null) { + jarfile = flags; + } else { + alias = flags; + ckaliases.add(alias); + } + } else if (collator.compare(flags, "-keystore") == 0) { if (++n == args.length) usageNoArg(); keystore = args[n]; } else if (collator.compare(flags, "-storepass") ==0) { @@ -380,18 +388,9 @@ public class Main { collator.compare(flags, "-help") == 0) { fullusage(); } else { - if (!flags.startsWith("-")) { - if (jarfile == null) { - jarfile = flags; - } else { - alias = flags; - ckaliases.add(alias); - } - } else { - System.err.println( - rb.getString("Illegal.option.") + flags); - usage(); - } + System.err.println( + rb.getString("Illegal.option.") + flags); + usage(); } } diff --git a/jdk/test/sun/security/tools/jarsigner/collator.sh b/jdk/test/sun/security/tools/jarsigner/collator.sh new file mode 100644 index 00000000000..06e21aac5fe --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/collator.sh @@ -0,0 +1,76 @@ +# +# Copyright (c) 2013, 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. +# + +# @test +# @bug 8021789 +# @summary jarsigner parses alias as command line option (depending on locale) +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Windows_* ) + FS="\\" + ;; + * ) + FS="/" + ;; +esac + +F=collator +KS=collator.jks +JFILE=collator.jar + +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ + -keystore $KS" +JAR=$TESTJAVA${FS}bin${FS}jar +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit" + +rm $F $KS $JFILE 2> /dev/null + +echo 12345 > $F +$JAR cvf $JFILE $F + +ERR="" + +$KT -alias debug -dname CN=debug -genkey -validity 300 || ERR="$ERR 1" + +# use "debug" as alias name +$JARSIGNER $JFILE debug || ERR="$ERR 2" + +# use "" as alias name (although there will be a warning) +$JARSIGNER -verify $JFILE "" || ERR="$ERR 3" + +if [ "$ERR" = "" ]; then + exit 0 +else + echo "ERR is $ERR" + exit 1 +fi + + From b456dfe62998b1d5cc181339779b8d90cb8d8800 Mon Sep 17 00:00:00 2001 From: Alexey Utkin Date: Fri, 2 Aug 2013 13:16:43 +0400 Subject: [PATCH 08/39] 8020191: System.getProperty("os.name") returns "Windows NT (unknown)" on Windows 8.1 Reviewed-by: alanb, khazra, chegar --- jdk/src/windows/native/java/lang/java_props_md.c | 2 ++ jdk/src/windows/resource/java.manifest | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/jdk/src/windows/native/java/lang/java_props_md.c b/jdk/src/windows/native/java/lang/java_props_md.c index 3374bd44225..4dee31a8116 100644 --- a/jdk/src/windows/native/java/lang/java_props_md.c +++ b/jdk/src/windows/native/java/lang/java_props_md.c @@ -443,6 +443,7 @@ GetJavaProperties(JNIEnv* env) case 0: sprops.os_name = "Windows Vista"; break; case 1: sprops.os_name = "Windows 7"; break; case 2: sprops.os_name = "Windows 8"; break; + case 3: sprops.os_name = "Windows 8.1"; break; default: sprops.os_name = "Windows NT (unknown)"; } } else { @@ -450,6 +451,7 @@ GetJavaProperties(JNIEnv* env) case 0: sprops.os_name = "Windows Server 2008"; break; case 1: sprops.os_name = "Windows Server 2008 R2"; break; case 2: sprops.os_name = "Windows Server 2012"; break; + case 3: sprops.os_name = "Windows Server 2012 R2"; break; default: sprops.os_name = "Windows NT (unknown)"; } } diff --git a/jdk/src/windows/resource/java.manifest b/jdk/src/windows/resource/java.manifest index 24b19c06334..52f997e8b39 100644 --- a/jdk/src/windows/resource/java.manifest +++ b/jdk/src/windows/resource/java.manifest @@ -44,8 +44,14 @@ - + + + + + + + From 49fe3afa1855d330eb9975f1822183058557f8aa Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 2 Aug 2013 11:25:00 +0100 Subject: [PATCH 09/39] 8022121: Remove superfluous @test tag from SpliteratorTraversingAndSplittingTest Reviewed-by: psandoz --- .../Spliterator/SpliteratorTraversingAndSplittingTest.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java index 458c410c252..a84cbbeaebe 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java +++ b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java @@ -25,6 +25,7 @@ * @test * @summary Spliterator traversing and splitting tests * @run testng SpliteratorTraversingAndSplittingTest + * @bug 8020016 */ import org.testng.annotations.DataProvider; @@ -81,10 +82,6 @@ import java.util.function.UnaryOperator; import static org.testng.Assert.*; import static org.testng.Assert.assertEquals; -/** - * @test - * @bug 8020016 - */ @Test public class SpliteratorTraversingAndSplittingTest { From 0844d3e77bd54bfd5b189e5458f989f681b9a6e5 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Fri, 2 Aug 2013 08:30:46 -0400 Subject: [PATCH 10/39] 8001319: Add SecurityPermission "insertProvider" target name Reviewed-by: vinnie --- .../share/classes/java/security/Security.java | 55 +++++++++-------- .../java/security/SecurityPermission.java | 35 ++++++++--- .../java/security/Security/AddProvider.java | 59 +++++++++++++++++++ .../security/Security/AddProvider.policy.1 | 7 +++ .../security/Security/AddProvider.policy.2 | 8 +++ .../security/Security/AddProvider.policy.3 | 7 +++ 6 files changed, 140 insertions(+), 31 deletions(-) create mode 100644 jdk/test/java/security/Security/AddProvider.java create mode 100644 jdk/test/java/security/Security/AddProvider.policy.1 create mode 100644 jdk/test/java/security/Security/AddProvider.policy.2 create mode 100644 jdk/test/java/security/Security/AddProvider.policy.3 diff --git a/jdk/src/share/classes/java/security/Security.java b/jdk/src/share/classes/java/security/Security.java index 98699da8149..ce99101e716 100644 --- a/jdk/src/share/classes/java/security/Security.java +++ b/jdk/src/share/classes/java/security/Security.java @@ -326,17 +326,13 @@ public final class Security { * *

A provider cannot be added if it is already installed. * - *

First, if there is a security manager, its - * {@code checkSecurityAccess} - * method is called with the string - * {@code "insertProvider."+provider.getName()} - * to see if it's ok to add a new provider. - * If the default implementation of {@code checkSecurityAccess} - * is used (i.e., that method is not overriden), then this will result in - * a call to the security manager's {@code checkPermission} method - * with a - * {@code SecurityPermission("insertProvider."+provider.getName())} - * permission. + *

If there is a security manager, the + * {@link java.lang.SecurityManager#checkSecurityAccess} method is called + * with the {@code "insertProvider"} permission target name to see if + * it's ok to add a new provider. If this permission check is denied, + * {@code checkSecurityAccess} is called again with the + * {@code "insertProvider."+provider.getName()} permission target name. If + * both checks are denied, a {@code SecurityException} is thrown. * * @param provider the provider to be added. * @@ -360,7 +356,7 @@ public final class Security { public static synchronized int insertProviderAt(Provider provider, int position) { String providerName = provider.getName(); - check("insertProvider." + providerName); + checkInsertProvider(providerName); ProviderList list = Providers.getFullProviderList(); ProviderList newList = ProviderList.insertAt(list, provider, position - 1); if (list == newList) { @@ -373,17 +369,13 @@ public final class Security { /** * Adds a provider to the next position available. * - *

First, if there is a security manager, its - * {@code checkSecurityAccess} - * method is called with the string - * {@code "insertProvider."+provider.getName()} - * to see if it's ok to add a new provider. - * If the default implementation of {@code checkSecurityAccess} - * is used (i.e., that method is not overriden), then this will result in - * a call to the security manager's {@code checkPermission} method - * with a - * {@code SecurityPermission("insertProvider."+provider.getName())} - * permission. + *

If there is a security manager, the + * {@link java.lang.SecurityManager#checkSecurityAccess} method is called + * with the {@code "insertProvider"} permission target name to see if + * it's ok to add a new provider. If this permission check is denied, + * {@code checkSecurityAccess} is called again with the + * {@code "insertProvider."+provider.getName()} permission target name. If + * both checks are denied, a {@code SecurityException} is thrown. * * @param provider the provider to be added. * @@ -863,6 +855,23 @@ public final class Security { } } + private static void checkInsertProvider(String name) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + try { + security.checkSecurityAccess("insertProvider"); + } catch (SecurityException se1) { + try { + security.checkSecurityAccess("insertProvider." + name); + } catch (SecurityException se2) { + // throw first exception, but add second to suppressed + se1.addSuppressed(se2); + throw se1; + } + } + } + } + /* * Returns all providers who satisfy the specified * criterion. diff --git a/jdk/src/share/classes/java/security/SecurityPermission.java b/jdk/src/share/classes/java/security/SecurityPermission.java index e0f0f92b40c..bbdccaeffe3 100644 --- a/jdk/src/share/classes/java/security/SecurityPermission.java +++ b/jdk/src/share/classes/java/security/SecurityPermission.java @@ -130,14 +130,17 @@ import java.util.StringTokenizer; * * * - * insertProvider.{provider name} - * Addition of a new provider, with the specified name + * insertProvider + * Addition of a new provider * This would allow somebody to introduce a possibly * malicious provider (e.g., one that discloses the private keys passed * to it) as the highest-priority provider. This would be possible * because the Security object (which manages the installed providers) * currently does not check the integrity or authenticity of a provider - * before attaching it. + * before attaching it. The "insertProvider" permission subsumes the + * "insertProvider.{provider name}" permission (see the section below for + * more information). + * * * * @@ -186,9 +189,10 @@ import java.util.StringTokenizer; * * *

- * The following permissions are associated with classes that have been - * deprecated: {@link Identity}, {@link IdentityScope}, {@link Signer}. Use of - * them is discouraged. See the applicable classes for more information. + * The following permissions have been superseded by newer permissions or are + * associated with classes that have been deprecated: {@link Identity}, + * {@link IdentityScope}, {@link Signer}. Use of them is discouraged. See the + * applicable classes for more information. *

* * @@ -199,6 +203,23 @@ import java.util.StringTokenizer; * * * + * + * + * + * + * + * * * *
insertProvider.{provider name}Addition of a new provider, with the specified nameUse of this permission is discouraged from further use because it is + * possible to circumvent the name restrictions by overriding the + * {@link java.security.Provider#getName} method. Also, there is an equivalent + * level of risk associated with granting code permission to insert a provider + * with a specific name, or any name it chooses. Users should use the + * "insertProvider" permission instead. + *

This would allow somebody to introduce a possibly + * malicious provider (e.g., one that discloses the private keys passed + * to it) as the highest-priority provider. This would be possible + * because the Security object (which manages the installed providers) + * currently does not check the integrity or authenticity of a provider + * before attaching it.

setSystemScopeSetting of the system identity scopeThis would allow an attacker to configure the system identity scope with @@ -306,7 +327,6 @@ public final class SecurityPermission extends BasicPermission { * @throws NullPointerException if {@code name} is {@code null}. * @throws IllegalArgumentException if {@code name} is empty. */ - public SecurityPermission(String name) { super(name); @@ -323,7 +343,6 @@ public final class SecurityPermission extends BasicPermission { * @throws NullPointerException if {@code name} is {@code null}. * @throws IllegalArgumentException if {@code name} is empty. */ - public SecurityPermission(String name, String actions) { super(name, actions); diff --git a/jdk/test/java/security/Security/AddProvider.java b/jdk/test/java/security/Security/AddProvider.java new file mode 100644 index 00000000000..27559ffdbc8 --- /dev/null +++ b/jdk/test/java/security/Security/AddProvider.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 8001319 + * @summary check that SecurityPermission insertProvider permission is enforced + * correctly + * @run main/othervm/policy=AddProvider.policy.1 AddProvider 1 + * @run main/othervm/policy=AddProvider.policy.2 AddProvider 2 + * @run main/othervm/policy=AddProvider.policy.3 AddProvider 3 + */ +import java.security.Provider; +import java.security.Security; + +public class AddProvider { + + public static void main(String[] args) throws Exception { + boolean legacy = args[0].equals("2"); + Security.addProvider(new TestProvider("Test1")); + Security.insertProviderAt(new TestProvider("Test2"), 1); + try { + Security.addProvider(new TestProvider("Test3")); + if (legacy) { + throw new Exception("Expected SecurityException"); + } + } catch (SecurityException se) { + if (!legacy) { + throw se; + } + } + } + + private static class TestProvider extends Provider { + TestProvider(String name) { + super(name, 0.0, "Not for use in production systems!"); + } + } +} diff --git a/jdk/test/java/security/Security/AddProvider.policy.1 b/jdk/test/java/security/Security/AddProvider.policy.1 new file mode 100644 index 00000000000..17a49b47b77 --- /dev/null +++ b/jdk/test/java/security/Security/AddProvider.policy.1 @@ -0,0 +1,7 @@ +grant codeBase "file:${{java.ext.dirs}}/*" { + permission java.security.AllPermission; +}; + +grant { + permission java.security.SecurityPermission "insertProvider"; +}; diff --git a/jdk/test/java/security/Security/AddProvider.policy.2 b/jdk/test/java/security/Security/AddProvider.policy.2 new file mode 100644 index 00000000000..d5a7ca94442 --- /dev/null +++ b/jdk/test/java/security/Security/AddProvider.policy.2 @@ -0,0 +1,8 @@ +grant codeBase "file:${{java.ext.dirs}}/*" { + permission java.security.AllPermission; +}; + +grant { + permission java.security.SecurityPermission "insertProvider.Test1"; + permission java.security.SecurityPermission "insertProvider.Test2"; +}; diff --git a/jdk/test/java/security/Security/AddProvider.policy.3 b/jdk/test/java/security/Security/AddProvider.policy.3 new file mode 100644 index 00000000000..930b443d7f6 --- /dev/null +++ b/jdk/test/java/security/Security/AddProvider.policy.3 @@ -0,0 +1,7 @@ +grant codeBase "file:${{java.ext.dirs}}/*" { + permission java.security.AllPermission; +}; + +grant { + permission java.security.SecurityPermission "insertProvider.*"; +}; From b1a10b8ed7bedb27ae25341602319a11a1225ee7 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Fri, 2 Aug 2013 14:29:31 +0100 Subject: [PATCH 11/39] 8020291: j.u.c.CompletionStage 8020435: CompletableFuture/Basic.java fails on single core machine Reviewed-by: chegar, psandoz --- .../util/concurrent/CompletableFuture.java | 2221 +++++++---------- .../java/util/concurrent/CompletionStage.java | 760 ++++++ jdk/test/ProblemList.txt | 6 - .../concurrent/CompletableFuture/Basic.java | 2 + 4 files changed, 1725 insertions(+), 1264 deletions(-) create mode 100644 jdk/src/share/classes/java/util/concurrent/CompletionStage.java diff --git a/jdk/src/share/classes/java/util/concurrent/CompletableFuture.java b/jdk/src/share/classes/java/util/concurrent/CompletableFuture.java index 7926f2e63b9..5e2fb134fc1 100644 --- a/jdk/src/share/classes/java/util/concurrent/CompletableFuture.java +++ b/jdk/src/share/classes/java/util/concurrent/CompletableFuture.java @@ -48,13 +48,16 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; /** * A {@link Future} that may be explicitly completed (setting its - * value and status), and may include dependent functions and actions - * that trigger upon its completion. + * value and status), and may be used as a {@link CompletionStage}, + * supporting dependent functions and actions that trigger upon its + * completion. * *

When two or more threads attempt to * {@link #complete complete}, @@ -62,64 +65,50 @@ import java.util.concurrent.locks.LockSupport; * {@link #cancel cancel} * a CompletableFuture, only one of them succeeds. * - *

Methods are available for adding dependents based on - * user-provided Functions, Consumers, or Runnables. The appropriate - * form to use depends on whether actions require arguments and/or - * produce results. Completion of a dependent action will trigger the - * completion of another CompletableFuture. Actions may also be - * triggered after either or both the current and another - * CompletableFuture complete. Multiple CompletableFutures may also - * be grouped as one using {@link #anyOf(CompletableFuture...)} and - * {@link #allOf(CompletableFuture...)}. + *

In addition to these and related methods for directly + * manipulating status and results, CompletableFuture implements + * interface {@link CompletionStage} with the following policies:

    * - *

    CompletableFutures themselves do not execute asynchronously. - * However, actions supplied for dependent completions of another - * CompletableFuture may do so, depending on whether they are provided - * via one of the async methods (that is, methods with names - * of the form xxxAsync). The async - * methods provide a way to commence asynchronous processing of an - * action using either a given {@link Executor} or by default the - * {@link ForkJoinPool#commonPool()}. To simplify monitoring, + *

  • Actions supplied for dependent completions of + * non-async methods may be performed by the thread that + * completes the current CompletableFuture, or by any other caller of + * a completion method.
  • + * + *
  • All async methods without an explicit Executor + * argument are performed using the {@link ForkJoinPool#commonPool()} + * (unless it does not support a parallelism level of at least two, in + * which case, a new Thread is used). To simplify monitoring, * debugging, and tracking, all generated asynchronous tasks are - * instances of the marker interface {@link AsynchronousCompletionTask}. + * instances of the marker interface {@link + * AsynchronousCompletionTask}.
  • * - *

    Actions supplied for dependent completions of non-async - * methods may be performed by the thread that completes the current - * CompletableFuture, or by any other caller of these methods. There - * are no guarantees about the order of processing completions unless - * constrained by these methods. + *

  • All CompletionStage methods are implemented independently of + * other public methods, so the behavior of one method is not impacted + * by overrides of others in subclasses.
* - *

Since (unlike {@link FutureTask}) this class has no direct + *

CompletableFuture also implements {@link Future} with the following + * policies:

    + * + *
  • Since (unlike {@link FutureTask}) this class has no direct * control over the computation that causes it to be completed, - * cancellation is treated as just another form of exceptional completion. - * Method {@link #cancel cancel} has the same effect as - * {@code completeExceptionally(new CancellationException())}. + * cancellation is treated as just another form of exceptional + * completion. Method {@link #cancel cancel} has the same effect as + * {@code completeExceptionally(new CancellationException())}. Method + * {@link #isCompletedExceptionally} can be used to determine if a + * CompletableFuture completed in any exceptional fashion.
  • * - *

    Upon exceptional completion (including cancellation), or when a - * completion entails an additional computation which terminates - * abruptly with an (unchecked) exception or error, then all of their - * dependent completions (and their dependents in turn) generally act - * as {@code completeExceptionally} with a {@link CompletionException} - * holding that exception as its cause. However, the {@link - * #exceptionally exceptionally} and {@link #handle handle} - * completions are able to handle exceptional completions of - * the CompletableFutures they depend on. - * - *

    In case of exceptional completion with a CompletionException, + *

  • In case of exceptional completion with a CompletionException, * methods {@link #get()} and {@link #get(long, TimeUnit)} throw an * {@link ExecutionException} with the same cause as held in the - * corresponding CompletionException. However, in these cases, - * methods {@link #join()} and {@link #getNow} throw the - * CompletionException, which simplifies usage. - * - *

    Arguments used to pass a completion result (that is, for parameters - * of type {@code T}) may be null, but passing a null value for any other - * parameter will result in a {@link NullPointerException} being thrown. + * corresponding CompletionException. To simplify usage in most + * contexts, this class also defines methods {@link #join()} and + * {@link #getNow} that instead throw the CompletionException directly + * in these cases.

* * @author Doug Lea * @since 1.8 */ -public class CompletableFuture implements Future { +public class CompletableFuture implements Future, CompletionStage { /* * Overview: @@ -438,6 +427,19 @@ public class CompletableFuture implements Future { public final void run() { exec(); } } + /** + * Starts the given async task using the given executor, unless + * the executor is ForkJoinPool.commonPool and it has been + * disabled, in which case starts a new thread. + */ + static void execAsync(Executor e, Async r) { + if (e == ForkJoinPool.commonPool() && + ForkJoinPool.getCommonPoolParallelism() <= 1) + new Thread(r).start(); + else + e.execute(r); + } + static final class AsyncRun extends Async { final Runnable fn; final CompletableFuture dst; @@ -538,13 +540,13 @@ public class CompletableFuture implements Future { static final class AsyncAccept extends Async { final T arg; final Consumer fn; - final CompletableFuture dst; + final CompletableFuture dst; AsyncAccept(T arg, Consumer fn, - CompletableFuture dst) { + CompletableFuture dst) { this.arg = arg; this.fn = fn; this.dst = dst; } public final boolean exec() { - CompletableFuture d; Throwable ex; + CompletableFuture d; Throwable ex; if ((d = this.dst) != null && d.result == null) { try { fn.accept(arg); @@ -563,14 +565,14 @@ public class CompletableFuture implements Future { final T arg1; final U arg2; final BiConsumer fn; - final CompletableFuture dst; + final CompletableFuture dst; AsyncAcceptBoth(T arg1, U arg2, BiConsumer fn, - CompletableFuture dst) { + CompletableFuture dst) { this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst; } public final boolean exec() { - CompletableFuture d; Throwable ex; + CompletableFuture d; Throwable ex; if ((d = this.dst) != null && d.result == null) { try { fn.accept(arg1, arg2); @@ -587,10 +589,10 @@ public class CompletableFuture implements Future { static final class AsyncCompose extends Async { final T arg; - final Function> fn; + final Function> fn; final CompletableFuture dst; AsyncCompose(T arg, - Function> fn, + Function> fn, CompletableFuture dst) { this.arg = arg; this.fn = fn; this.dst = dst; } @@ -598,7 +600,8 @@ public class CompletableFuture implements Future { CompletableFuture d, fr; U u; Throwable ex; if ((d = this.dst) != null && d.result == null) { try { - fr = fn.apply(arg); + CompletionStage cs = fn.apply(arg); + fr = (cs == null) ? null : cs.toCompletableFuture(); ex = (fr == null) ? new NullPointerException() : null; } catch (Throwable rex) { ex = rex; @@ -626,6 +629,33 @@ public class CompletableFuture implements Future { private static final long serialVersionUID = 5232453952276885070L; } + static final class AsyncWhenComplete extends Async { + final T arg1; + final Throwable arg2; + final BiConsumer fn; + final CompletableFuture dst; + AsyncWhenComplete(T arg1, Throwable arg2, + BiConsumer fn, + CompletableFuture dst) { + this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst; + } + public final boolean exec() { + CompletableFuture d; + if ((d = this.dst) != null && d.result == null) { + Throwable ex = arg2; + try { + fn.accept(arg1, ex); + } catch (Throwable rex) { + if (ex == null) + ex = rex; + } + d.internalComplete(arg1, ex); + } + return true; + } + private static final long serialVersionUID = 5232453952276885070L; + } + /* ------------- Completions -------------- */ /** @@ -680,7 +710,7 @@ public class CompletableFuture implements Future { if (ex == null) { try { if (e != null) - e.execute(new AsyncApply(t, fn, dst)); + execAsync(e, new AsyncApply(t, fn, dst)); else u = fn.apply(t); } catch (Throwable rex) { @@ -697,11 +727,11 @@ public class CompletableFuture implements Future { static final class ThenAccept extends Completion { final CompletableFuture src; final Consumer fn; - final CompletableFuture dst; + final CompletableFuture dst; final Executor executor; ThenAccept(CompletableFuture src, Consumer fn, - CompletableFuture dst, + CompletableFuture dst, Executor executor) { this.src = src; this.fn = fn; this.dst = dst; this.executor = executor; @@ -709,7 +739,7 @@ public class CompletableFuture implements Future { public final void run() { final CompletableFuture a; final Consumer fn; - final CompletableFuture dst; + final CompletableFuture dst; Object r; T t; Throwable ex; if ((dst = this.dst) != null && (fn = this.fn) != null && @@ -729,7 +759,7 @@ public class CompletableFuture implements Future { if (ex == null) { try { if (e != null) - e.execute(new AsyncAccept(t, fn, dst)); + execAsync(e, new AsyncAccept(t, fn, dst)); else fn.accept(t); } catch (Throwable rex) { @@ -773,7 +803,7 @@ public class CompletableFuture implements Future { if (ex == null) { try { if (e != null) - e.execute(new AsyncRun(fn, dst)); + execAsync(e, new AsyncRun(fn, dst)); else fn.run(); } catch (Throwable rex) { @@ -839,7 +869,7 @@ public class CompletableFuture implements Future { if (ex == null) { try { if (e != null) - e.execute(new AsyncCombine(t, u, fn, dst)); + execAsync(e, new AsyncCombine(t, u, fn, dst)); else v = fn.apply(t, u); } catch (Throwable rex) { @@ -904,7 +934,7 @@ public class CompletableFuture implements Future { if (ex == null) { try { if (e != null) - e.execute(new AsyncAcceptBoth(t, u, fn, dst)); + execAsync(e, new AsyncAcceptBoth(t, u, fn, dst)); else fn.accept(t, u); } catch (Throwable rex) { @@ -956,7 +986,7 @@ public class CompletableFuture implements Future { if (ex == null) { try { if (e != null) - e.execute(new AsyncRun(fn, dst)); + execAsync(e, new AsyncRun(fn, dst)); else fn.run(); } catch (Throwable rex) { @@ -1042,7 +1072,7 @@ public class CompletableFuture implements Future { if (ex == null) { try { if (e != null) - e.execute(new AsyncApply(t, fn, dst)); + execAsync(e, new AsyncApply(t, fn, dst)); else u = fn.apply(t); } catch (Throwable rex) { @@ -1095,7 +1125,7 @@ public class CompletableFuture implements Future { if (ex == null) { try { if (e != null) - e.execute(new AsyncAccept(t, fn, dst)); + execAsync(e, new AsyncAccept(t, fn, dst)); else fn.accept(t); } catch (Throwable rex) { @@ -1143,7 +1173,7 @@ public class CompletableFuture implements Future { if (ex == null) { try { if (e != null) - e.execute(new AsyncRun(fn, dst)); + execAsync(e, new AsyncRun(fn, dst)); else fn.run(); } catch (Throwable rex) { @@ -1226,6 +1256,54 @@ public class CompletableFuture implements Future { private static final long serialVersionUID = 5232453952276885070L; } + static final class WhenCompleteCompletion extends Completion { + final CompletableFuture src; + final BiConsumer fn; + final CompletableFuture dst; + final Executor executor; + WhenCompleteCompletion(CompletableFuture src, + BiConsumer fn, + CompletableFuture dst, + Executor executor) { + this.src = src; this.fn = fn; this.dst = dst; + this.executor = executor; + } + public final void run() { + final CompletableFuture a; + final BiConsumer fn; + final CompletableFuture dst; + Object r; T t; Throwable ex; + if ((dst = this.dst) != null && + (fn = this.fn) != null && + (a = this.src) != null && + (r = a.result) != null && + compareAndSet(0, 1)) { + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + Executor e = executor; + Throwable dx = null; + try { + if (e != null) + execAsync(e, new AsyncWhenComplete(t, ex, fn, dst)); + else + fn.accept(t, ex); + } catch (Throwable rex) { + dx = rex; + } + if (e == null || dx != null) + dst.internalComplete(t, ex != null ? ex : dx); + } + } + private static final long serialVersionUID = 5232453952276885070L; + } + static final class ThenCopy extends Completion { final CompletableFuture src; final CompletableFuture dst; @@ -1286,10 +1364,13 @@ public class CompletableFuture implements Future { final CompletableFuture src; final BiFunction fn; final CompletableFuture dst; + final Executor executor; HandleCompletion(CompletableFuture src, BiFunction fn, - CompletableFuture dst) { + CompletableFuture dst, + Executor executor) { this.src = src; this.fn = fn; this.dst = dst; + this.executor = executor; } public final void run() { final CompletableFuture a; @@ -1310,13 +1391,19 @@ public class CompletableFuture implements Future { @SuppressWarnings("unchecked") T tr = (T) r; t = tr; } - U u = null; Throwable dx = null; + Executor e = executor; + U u = null; + Throwable dx = null; try { - u = fn.apply(t, ex); + if (e != null) + execAsync(e, new AsyncCombine(t, ex, fn, dst)); + else + u = fn.apply(t, ex); } catch (Throwable rex) { dx = rex; } - dst.internalComplete(u, dx); + if (e == null || dx != null) + dst.internalComplete(u, dx); } } private static final long serialVersionUID = 5232453952276885070L; @@ -1324,11 +1411,11 @@ public class CompletableFuture implements Future { static final class ThenCompose extends Completion { final CompletableFuture src; - final Function> fn; + final Function> fn; final CompletableFuture dst; final Executor executor; ThenCompose(CompletableFuture src, - Function> fn, + Function> fn, CompletableFuture dst, Executor executor) { this.src = src; this.fn = fn; this.dst = dst; @@ -1336,7 +1423,7 @@ public class CompletableFuture implements Future { } public final void run() { final CompletableFuture a; - final Function> fn; + final Function> fn; final CompletableFuture dst; Object r; T t; Throwable ex; Executor e; if ((dst = this.dst) != null && @@ -1358,10 +1445,12 @@ public class CompletableFuture implements Future { boolean complete = false; if (ex == null) { if ((e = executor) != null) - e.execute(new AsyncCompose(t, fn, dst)); + execAsync(e, new AsyncCompose(t, fn, dst)); else { try { - if ((c = fn.apply(t)) == null) + CompletionStage cs = fn.apply(t); + c = (cs == null) ? null : cs.toCompletableFuture(); + if (c == null) ex = new NullPointerException(); } catch (Throwable rex) { ex = rex; @@ -1401,6 +1490,619 @@ public class CompletableFuture implements Future { private static final long serialVersionUID = 5232453952276885070L; } + // Implementations of stage methods with (plain, async, Executor) forms + + private CompletableFuture doThenApply + (Function fn, + Executor e) { + if (fn == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + ThenApply d = null; + Object r; + if ((r = result) == null) { + CompletionNode p = new CompletionNode + (d = new ThenApply(this, fn, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + U u = null; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncApply(t, fn, dst)); + else + u = fn.apply(t); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(u, ex); + } + helpPostComplete(); + return dst; + } + + private CompletableFuture doThenAccept(Consumer fn, + Executor e) { + if (fn == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + ThenAccept d = null; + Object r; + if ((r = result) == null) { + CompletionNode p = new CompletionNode + (d = new ThenAccept(this, fn, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncAccept(t, fn, dst)); + else + fn.accept(t); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + return dst; + } + + private CompletableFuture doThenRun(Runnable action, + Executor e) { + if (action == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + ThenRun d = null; + Object r; + if ((r = result) == null) { + CompletionNode p = new CompletionNode + (d = new ThenRun(this, action, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + Throwable ex; + if (r instanceof AltResult) + ex = ((AltResult)r).ex; + else + ex = null; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncRun(action, dst)); + else + action.run(); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + return dst; + } + + private CompletableFuture doThenCombine + (CompletableFuture other, + BiFunction fn, + Executor e) { + if (other == null || fn == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + ThenCombine d = null; + Object r, s = null; + if ((r = result) == null || (s = other.result) == null) { + d = new ThenCombine(this, other, fn, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r == null && (r = result) == null) || + (s == null && (s = other.result) == null)) { + if (q != null) { + if (s != null || + UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (r != null || + UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) { + if (s != null) + break; + q = new CompletionNode(d); + } + } + } + if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { + T t; U u; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + if (ex != null) + u = null; + else if (s instanceof AltResult) { + ex = ((AltResult)s).ex; + u = null; + } + else { + @SuppressWarnings("unchecked") U us = (U) s; + u = us; + } + V v = null; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncCombine(t, u, fn, dst)); + else + v = fn.apply(t, u); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(v, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private CompletableFuture doThenAcceptBoth + (CompletableFuture other, + BiConsumer fn, + Executor e) { + if (other == null || fn == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + ThenAcceptBoth d = null; + Object r, s = null; + if ((r = result) == null || (s = other.result) == null) { + d = new ThenAcceptBoth(this, other, fn, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r == null && (r = result) == null) || + (s == null && (s = other.result) == null)) { + if (q != null) { + if (s != null || + UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (r != null || + UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) { + if (s != null) + break; + q = new CompletionNode(d); + } + } + } + if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { + T t; U u; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + if (ex != null) + u = null; + else if (s instanceof AltResult) { + ex = ((AltResult)s).ex; + u = null; + } + else { + @SuppressWarnings("unchecked") U us = (U) s; + u = us; + } + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncAcceptBoth(t, u, fn, dst)); + else + fn.accept(t, u); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private CompletableFuture doRunAfterBoth(CompletableFuture other, + Runnable action, + Executor e) { + if (other == null || action == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + RunAfterBoth d = null; + Object r, s = null; + if ((r = result) == null || (s = other.result) == null) { + d = new RunAfterBoth(this, other, action, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r == null && (r = result) == null) || + (s == null && (s = other.result) == null)) { + if (q != null) { + if (s != null || + UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (r != null || + UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) { + if (s != null) + break; + q = new CompletionNode(d); + } + } + } + if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { + Throwable ex; + if (r instanceof AltResult) + ex = ((AltResult)r).ex; + else + ex = null; + if (ex == null && (s instanceof AltResult)) + ex = ((AltResult)s).ex; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncRun(action, dst)); + else + action.run(); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private CompletableFuture doApplyToEither + (CompletableFuture other, + Function fn, + Executor e) { + if (other == null || fn == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + ApplyToEither d = null; + Object r; + if ((r = result) == null && (r = other.result) == null) { + d = new ApplyToEither(this, other, fn, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r = result) == null && (r = other.result) == null) { + if (q != null) { + if (UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + q = new CompletionNode(d); + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + U u = null; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncApply(t, fn, dst)); + else + u = fn.apply(t); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(u, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private CompletableFuture doAcceptEither + (CompletableFuture other, + Consumer fn, + Executor e) { + if (other == null || fn == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + AcceptEither d = null; + Object r; + if ((r = result) == null && (r = other.result) == null) { + d = new AcceptEither(this, other, fn, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r = result) == null && (r = other.result) == null) { + if (q != null) { + if (UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + q = new CompletionNode(d); + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncAccept(t, fn, dst)); + else + fn.accept(t); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private CompletableFuture doRunAfterEither + (CompletableFuture other, + Runnable action, + Executor e) { + if (other == null || action == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + RunAfterEither d = null; + Object r; + if ((r = result) == null && (r = other.result) == null) { + d = new RunAfterEither(this, other, action, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r = result) == null && (r = other.result) == null) { + if (q != null) { + if (UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + q = new CompletionNode(d); + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + Throwable ex; + if (r instanceof AltResult) + ex = ((AltResult)r).ex; + else + ex = null; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncRun(action, dst)); + else + action.run(); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private CompletableFuture doThenCompose + (Function> fn, + Executor e) { + if (fn == null) throw new NullPointerException(); + CompletableFuture dst = null; + ThenCompose d = null; + Object r; + if ((r = result) == null) { + dst = new CompletableFuture(); + CompletionNode p = new CompletionNode + (d = new ThenCompose(this, fn, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + if (ex == null) { + if (e != null) { + if (dst == null) + dst = new CompletableFuture(); + execAsync(e, new AsyncCompose(t, fn, dst)); + } + else { + try { + CompletionStage cs = fn.apply(t); + if (cs == null || + (dst = cs.toCompletableFuture()) == null) + ex = new NullPointerException(); + } catch (Throwable rex) { + ex = rex; + } + } + } + if (dst == null) + dst = new CompletableFuture(); + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + dst.helpPostComplete(); + return dst; + } + + private CompletableFuture doWhenComplete + (BiConsumer fn, + Executor e) { + if (fn == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + WhenCompleteCompletion d = null; + Object r; + if ((r = result) == null) { + CompletionNode p = + new CompletionNode(d = new WhenCompleteCompletion + (this, fn, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject(this, COMPLETIONS, + p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + Throwable dx = null; + try { + if (e != null) + execAsync(e, new AsyncWhenComplete(t, ex, fn, dst)); + else + fn.accept(t, ex); + } catch (Throwable rex) { + dx = rex; + } + if (e == null || dx != null) + dst.internalComplete(t, ex != null ? ex : dx); + } + helpPostComplete(); + return dst; + } + + private CompletableFuture doHandle + (BiFunction fn, + Executor e) { + if (fn == null) throw new NullPointerException(); + CompletableFuture dst = new CompletableFuture(); + HandleCompletion d = null; + Object r; + if ((r = result) == null) { + CompletionNode p = + new CompletionNode(d = new HandleCompletion + (this, fn, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject(this, COMPLETIONS, + p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + U u = null; + Throwable dx = null; + try { + if (e != null) + execAsync(e, new AsyncCombine(t, ex, fn, dst)); + else { + u = fn.apply(t, ex); + dx = null; + } + } catch (Throwable rex) { + dx = rex; + u = null; + } + if (e == null || dx != null) + dst.internalComplete(u, dx); + } + helpPostComplete(); + return dst; + } + + // public methods /** @@ -1416,13 +2118,13 @@ public class CompletableFuture implements Future { * * @param supplier a function returning the value to be used * to complete the returned CompletableFuture + * @param the function's return type * @return the new CompletableFuture */ public static CompletableFuture supplyAsync(Supplier supplier) { if (supplier == null) throw new NullPointerException(); CompletableFuture f = new CompletableFuture(); - ForkJoinPool.commonPool(). - execute((ForkJoinTask)new AsyncSupply(supplier, f)); + execAsync(ForkJoinPool.commonPool(), new AsyncSupply(supplier, f)); return f; } @@ -1434,6 +2136,7 @@ public class CompletableFuture implements Future { * @param supplier a function returning the value to be used * to complete the returned CompletableFuture * @param executor the executor to use for asynchronous execution + * @param the function's return type * @return the new CompletableFuture */ public static CompletableFuture supplyAsync(Supplier supplier, @@ -1441,7 +2144,7 @@ public class CompletableFuture implements Future { if (executor == null || supplier == null) throw new NullPointerException(); CompletableFuture f = new CompletableFuture(); - executor.execute(new AsyncSupply(supplier, f)); + execAsync(executor, new AsyncSupply(supplier, f)); return f; } @@ -1457,8 +2160,7 @@ public class CompletableFuture implements Future { public static CompletableFuture runAsync(Runnable runnable) { if (runnable == null) throw new NullPointerException(); CompletableFuture f = new CompletableFuture(); - ForkJoinPool.commonPool(). - execute((ForkJoinTask)new AsyncRun(runnable, f)); + execAsync(ForkJoinPool.commonPool(), new AsyncRun(runnable, f)); return f; } @@ -1477,7 +2179,7 @@ public class CompletableFuture implements Future { if (executor == null || runnable == null) throw new NullPointerException(); CompletableFuture f = new CompletableFuture(); - executor.execute(new AsyncRun(runnable, f)); + execAsync(executor, new AsyncRun(runnable, f)); return f; } @@ -1486,6 +2188,7 @@ public class CompletableFuture implements Future { * the given value. * * @param value the value + * @param the type of the value * @return the completed CompletableFuture */ public static CompletableFuture completedFuture(U value) { @@ -1657,60 +2360,18 @@ public class CompletableFuture implements Future { return triggered; } - /** - * Returns a new CompletableFuture that is completed - * when this CompletableFuture completes, with the result of the - * given function of this CompletableFuture's result. - * - *

If this CompletableFuture completes exceptionally, or the - * supplied function throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture thenApply(Function fn) { + // CompletionStage methods + + public CompletableFuture thenApply + (Function fn) { return doThenApply(fn, null); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, with the result of the - * given function of this CompletableFuture's result from a - * task running in the {@link ForkJoinPool#commonPool()}. - * - *

If this CompletableFuture completes exceptionally, or the - * supplied function throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ public CompletableFuture thenApplyAsync (Function fn) { return doThenApply(fn, ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, with the result of the - * given function of this CompletableFuture's result from a - * task running in the given executor. - * - *

If this CompletableFuture completes exceptionally, or the - * supplied function throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ public CompletableFuture thenApplyAsync (Function fn, Executor executor) { @@ -1718,1149 +2379,228 @@ public class CompletableFuture implements Future { return doThenApply(fn, executor); } - private CompletableFuture doThenApply - (Function fn, - Executor e) { - if (fn == null) throw new NullPointerException(); - CompletableFuture dst = new CompletableFuture(); - ThenApply d = null; - Object r; - if ((r = result) == null) { - CompletionNode p = new CompletionNode - (d = new ThenApply(this, fn, dst, e)); - while ((r = result) == null) { - if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - break; - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - U u = null; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncApply(t, fn, dst)); - else - u = fn.apply(t); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(u, ex); - } - helpPostComplete(); - return dst; + public CompletableFuture thenAccept + (Consumer action) { + return doThenAccept(action, null); } - /** - * Returns a new CompletableFuture that is completed - * when this CompletableFuture completes, after performing the given - * action with this CompletableFuture's result. - * - *

If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture thenAccept(Consumer block) { - return doThenAccept(block, null); + public CompletableFuture thenAcceptAsync + (Consumer action) { + return doThenAccept(action, ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, after performing the given - * action with this CompletableFuture's result from a task running - * in the {@link ForkJoinPool#commonPool()}. - * - *

If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture thenAcceptAsync(Consumer block) { - return doThenAccept(block, ForkJoinPool.commonPool()); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, after performing the given - * action with this CompletableFuture's result from a task running - * in the given executor. - * - *

If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param block the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public CompletableFuture thenAcceptAsync(Consumer block, - Executor executor) { + public CompletableFuture thenAcceptAsync + (Consumer action, + Executor executor) { if (executor == null) throw new NullPointerException(); - return doThenAccept(block, executor); + return doThenAccept(action, executor); } - private CompletableFuture doThenAccept(Consumer fn, - Executor e) { - if (fn == null) throw new NullPointerException(); - CompletableFuture dst = new CompletableFuture(); - ThenAccept d = null; - Object r; - if ((r = result) == null) { - CompletionNode p = new CompletionNode - (d = new ThenAccept(this, fn, dst, e)); - while ((r = result) == null) { - if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - break; - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncAccept(t, fn, dst)); - else - fn.accept(t); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - return dst; - } - - /** - * Returns a new CompletableFuture that is completed - * when this CompletableFuture completes, after performing the given - * action. - * - *

If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture thenRun(Runnable action) { + public CompletableFuture thenRun + (Runnable action) { return doThenRun(action, null); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, after performing the given - * action from a task running in the {@link ForkJoinPool#commonPool()}. - * - *

If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture thenRunAsync(Runnable action) { + public CompletableFuture thenRunAsync + (Runnable action) { return doThenRun(action, ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, after performing the given - * action from a task running in the given executor. - * - *

If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param action the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public CompletableFuture thenRunAsync(Runnable action, - Executor executor) { + public CompletableFuture thenRunAsync + (Runnable action, + Executor executor) { if (executor == null) throw new NullPointerException(); return doThenRun(action, executor); } - private CompletableFuture doThenRun(Runnable action, - Executor e) { - if (action == null) throw new NullPointerException(); - CompletableFuture dst = new CompletableFuture(); - ThenRun d = null; - Object r; - if ((r = result) == null) { - CompletionNode p = new CompletionNode - (d = new ThenRun(this, action, dst, e)); - while ((r = result) == null) { - if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - break; - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - Throwable ex; - if (r instanceof AltResult) - ex = ((AltResult)r).ex; - else - ex = null; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncRun(action, dst)); - else - action.run(); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - return dst; - } - - /** - * Returns a new CompletableFuture that is completed - * when both this and the other given CompletableFuture complete, - * with the result of the given function of the results of the two - * CompletableFutures. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, or the supplied function throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ public CompletableFuture thenCombine - (CompletableFuture other, + (CompletionStage other, BiFunction fn) { - return doThenCombine(other, fn, null); + return doThenCombine(other.toCompletableFuture(), fn, null); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * with the result of the given function of the results of the two - * CompletableFutures from a task running in the - * {@link ForkJoinPool#commonPool()}. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, or the supplied function throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ public CompletableFuture thenCombineAsync - (CompletableFuture other, + (CompletionStage other, BiFunction fn) { - return doThenCombine(other, fn, ForkJoinPool.commonPool()); + return doThenCombine(other.toCompletableFuture(), fn, + ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * with the result of the given function of the results of the two - * CompletableFutures from a task running in the given executor. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, or the supplied function throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ public CompletableFuture thenCombineAsync - (CompletableFuture other, + (CompletionStage other, BiFunction fn, Executor executor) { if (executor == null) throw new NullPointerException(); - return doThenCombine(other, fn, executor); + return doThenCombine(other.toCompletableFuture(), fn, executor); } - private CompletableFuture doThenCombine - (CompletableFuture other, - BiFunction fn, - Executor e) { - if (other == null || fn == null) throw new NullPointerException(); - CompletableFuture dst = new CompletableFuture(); - ThenCombine d = null; - Object r, s = null; - if ((r = result) == null || (s = other.result) == null) { - d = new ThenCombine(this, other, fn, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r == null && (r = result) == null) || - (s == null && (s = other.result) == null)) { - if (q != null) { - if (s != null || - UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (r != null || - UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) { - if (s != null) - break; - q = new CompletionNode(d); - } - } - } - if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { - T t; U u; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - if (ex != null) - u = null; - else if (s instanceof AltResult) { - ex = ((AltResult)s).ex; - u = null; - } - else { - @SuppressWarnings("unchecked") U us = (U) s; - u = us; - } - V v = null; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncCombine(t, u, fn, dst)); - else - v = fn.apply(t, u); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(v, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; - } - - /** - * Returns a new CompletableFuture that is completed - * when both this and the other given CompletableFuture complete, - * after performing the given action with the results of the two - * CompletableFutures. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ public CompletableFuture thenAcceptBoth - (CompletableFuture other, - BiConsumer block) { - return doThenAcceptBoth(other, block, null); + (CompletionStage other, + BiConsumer action) { + return doThenAcceptBoth(other.toCompletableFuture(), action, null); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * after performing the given action with the results of the two - * CompletableFutures from a task running in the {@link - * ForkJoinPool#commonPool()}. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ public CompletableFuture thenAcceptBothAsync - (CompletableFuture other, - BiConsumer block) { - return doThenAcceptBoth(other, block, ForkJoinPool.commonPool()); + (CompletionStage other, + BiConsumer action) { + return doThenAcceptBoth(other.toCompletableFuture(), action, + ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * after performing the given action with the results of the two - * CompletableFutures from a task running in the given executor. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ public CompletableFuture thenAcceptBothAsync - (CompletableFuture other, - BiConsumer block, + (CompletionStage other, + BiConsumer action, Executor executor) { if (executor == null) throw new NullPointerException(); - return doThenAcceptBoth(other, block, executor); + return doThenAcceptBoth(other.toCompletableFuture(), action, executor); } - private CompletableFuture doThenAcceptBoth - (CompletableFuture other, - BiConsumer fn, - Executor e) { - if (other == null || fn == null) throw new NullPointerException(); - CompletableFuture dst = new CompletableFuture(); - ThenAcceptBoth d = null; - Object r, s = null; - if ((r = result) == null || (s = other.result) == null) { - d = new ThenAcceptBoth(this, other, fn, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r == null && (r = result) == null) || - (s == null && (s = other.result) == null)) { - if (q != null) { - if (s != null || - UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (r != null || - UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) { - if (s != null) - break; - q = new CompletionNode(d); - } - } - } - if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { - T t; U u; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - if (ex != null) - u = null; - else if (s instanceof AltResult) { - ex = ((AltResult)s).ex; - u = null; - } - else { - @SuppressWarnings("unchecked") U us = (U) s; - u = us; - } - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncAcceptBoth(t, u, fn, dst)); - else - fn.accept(t, u); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; - } - - /** - * Returns a new CompletableFuture that is completed - * when both this and the other given CompletableFuture complete, - * after performing the given action. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture runAfterBoth(CompletableFuture other, - Runnable action) { - return doRunAfterBoth(other, action, null); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * after performing the given action from a task running in the - * {@link ForkJoinPool#commonPool()}. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture runAfterBothAsync(CompletableFuture other, - Runnable action) { - return doRunAfterBoth(other, action, ForkJoinPool.commonPool()); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * after performing the given action from a task running in the - * given executor. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public CompletableFuture runAfterBothAsync(CompletableFuture other, - Runnable action, - Executor executor) { - if (executor == null) throw new NullPointerException(); - return doRunAfterBoth(other, action, executor); - } - - private CompletableFuture doRunAfterBoth(CompletableFuture other, - Runnable action, - Executor e) { - if (other == null || action == null) throw new NullPointerException(); - CompletableFuture dst = new CompletableFuture(); - RunAfterBoth d = null; - Object r, s = null; - if ((r = result) == null || (s = other.result) == null) { - d = new RunAfterBoth(this, other, action, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r == null && (r = result) == null) || - (s == null && (s = other.result) == null)) { - if (q != null) { - if (s != null || - UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (r != null || - UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) { - if (s != null) - break; - q = new CompletionNode(d); - } - } - } - if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { - Throwable ex; - if (r instanceof AltResult) - ex = ((AltResult)r).ex; - else - ex = null; - if (ex == null && (s instanceof AltResult)) - ex = ((AltResult)s).ex; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncRun(action, dst)); - else - action.run(); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; - } - - /** - * Returns a new CompletableFuture that is completed - * when either this or the other given CompletableFuture completes, - * with the result of the given function of either this or the other - * CompletableFuture's result. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied function - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture applyToEither - (CompletableFuture other, - Function fn) { - return doApplyToEither(other, fn, null); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * with the result of the given function of either this or the other - * CompletableFuture's result from a task running in the - * {@link ForkJoinPool#commonPool()}. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied function - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture applyToEitherAsync - (CompletableFuture other, - Function fn) { - return doApplyToEither(other, fn, ForkJoinPool.commonPool()); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * with the result of the given function of either this or the other - * CompletableFuture's result from a task running in the - * given executor. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied function - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public CompletableFuture applyToEitherAsync - (CompletableFuture other, - Function fn, - Executor executor) { - if (executor == null) throw new NullPointerException(); - return doApplyToEither(other, fn, executor); - } - - private CompletableFuture doApplyToEither - (CompletableFuture other, - Function fn, - Executor e) { - if (other == null || fn == null) throw new NullPointerException(); - CompletableFuture dst = new CompletableFuture(); - ApplyToEither d = null; - Object r; - if ((r = result) == null && (r = other.result) == null) { - d = new ApplyToEither(this, other, fn, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r = result) == null && (r = other.result) == null) { - if (q != null) { - if (UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - q = new CompletionNode(d); - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - U u = null; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncApply(t, fn, dst)); - else - u = fn.apply(t); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(u, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; - } - - /** - * Returns a new CompletableFuture that is completed - * when either this or the other given CompletableFuture completes, - * after performing the given action with the result of either this - * or the other CompletableFuture's result. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture acceptEither - (CompletableFuture other, - Consumer block) { - return doAcceptEither(other, block, null); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * after performing the given action with the result of either this - * or the other CompletableFuture's result from a task running in - * the {@link ForkJoinPool#commonPool()}. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture acceptEitherAsync - (CompletableFuture other, - Consumer block) { - return doAcceptEither(other, block, ForkJoinPool.commonPool()); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * after performing the given action with the result of either this - * or the other CompletableFuture's result from a task running in - * the given executor. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public CompletableFuture acceptEitherAsync - (CompletableFuture other, - Consumer block, - Executor executor) { - if (executor == null) throw new NullPointerException(); - return doAcceptEither(other, block, executor); - } - - private CompletableFuture doAcceptEither - (CompletableFuture other, - Consumer fn, - Executor e) { - if (other == null || fn == null) throw new NullPointerException(); - CompletableFuture dst = new CompletableFuture(); - AcceptEither d = null; - Object r; - if ((r = result) == null && (r = other.result) == null) { - d = new AcceptEither(this, other, fn, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r = result) == null && (r = other.result) == null) { - if (q != null) { - if (UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - q = new CompletionNode(d); - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncAccept(t, fn, dst)); - else - fn.accept(t); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; - } - - /** - * Returns a new CompletableFuture that is completed - * when either this or the other given CompletableFuture completes, - * after performing the given action. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture runAfterEither(CompletableFuture other, - Runnable action) { - return doRunAfterEither(other, action, null); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * after performing the given action from a task running in the - * {@link ForkJoinPool#commonPool()}. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture runAfterEitherAsync - (CompletableFuture other, + public CompletableFuture runAfterBoth + (CompletionStage other, Runnable action) { - return doRunAfterEither(other, action, ForkJoinPool.commonPool()); + return doRunAfterBoth(other.toCompletableFuture(), action, null); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * after performing the given action from a task running in the - * given executor. - * - *

If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public CompletableFuture runAfterEitherAsync - (CompletableFuture other, + public CompletableFuture runAfterBothAsync + (CompletionStage other, + Runnable action) { + return doRunAfterBoth(other.toCompletableFuture(), action, + ForkJoinPool.commonPool()); + } + + public CompletableFuture runAfterBothAsync + (CompletionStage other, Runnable action, Executor executor) { if (executor == null) throw new NullPointerException(); - return doRunAfterEither(other, action, executor); + return doRunAfterBoth(other.toCompletableFuture(), action, executor); } - private CompletableFuture doRunAfterEither - (CompletableFuture other, + + public CompletableFuture applyToEither + (CompletionStage other, + Function fn) { + return doApplyToEither(other.toCompletableFuture(), fn, null); + } + + public CompletableFuture applyToEitherAsync + (CompletionStage other, + Function fn) { + return doApplyToEither(other.toCompletableFuture(), fn, + ForkJoinPool.commonPool()); + } + + public CompletableFuture applyToEitherAsync + (CompletionStage other, + Function fn, + Executor executor) { + if (executor == null) throw new NullPointerException(); + return doApplyToEither(other.toCompletableFuture(), fn, executor); + } + + public CompletableFuture acceptEither + (CompletionStage other, + Consumer action) { + return doAcceptEither(other.toCompletableFuture(), action, null); + } + + public CompletableFuture acceptEitherAsync + (CompletionStage other, + Consumer action) { + return doAcceptEither(other.toCompletableFuture(), action, + ForkJoinPool.commonPool()); + } + + public CompletableFuture acceptEitherAsync + (CompletionStage other, + Consumer action, + Executor executor) { + if (executor == null) throw new NullPointerException(); + return doAcceptEither(other.toCompletableFuture(), action, executor); + } + + public CompletableFuture runAfterEither(CompletionStage other, + Runnable action) { + return doRunAfterEither(other.toCompletableFuture(), action, null); + } + + public CompletableFuture runAfterEitherAsync + (CompletionStage other, + Runnable action) { + return doRunAfterEither(other.toCompletableFuture(), action, + ForkJoinPool.commonPool()); + } + + public CompletableFuture runAfterEitherAsync + (CompletionStage other, Runnable action, - Executor e) { - if (other == null || action == null) throw new NullPointerException(); - CompletableFuture dst = new CompletableFuture(); - RunAfterEither d = null; - Object r; - if ((r = result) == null && (r = other.result) == null) { - d = new RunAfterEither(this, other, action, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r = result) == null && (r = other.result) == null) { - if (q != null) { - if (UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - q = new CompletionNode(d); - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - Throwable ex; - if (r instanceof AltResult) - ex = ((AltResult)r).ex; - else - ex = null; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncRun(action, dst)); - else - action.run(); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; + Executor executor) { + if (executor == null) throw new NullPointerException(); + return doRunAfterEither(other.toCompletableFuture(), action, executor); } - /** - * Returns a CompletableFuture that upon completion, has the same - * value as produced by the given function of the result of this - * CompletableFuture. - * - *

If this CompletableFuture completes exceptionally, then the - * returned CompletableFuture also does so, with a - * CompletionException holding this exception as its cause. - * Similarly, if the computed CompletableFuture completes - * exceptionally, then so does the returned CompletableFuture. - * - * @param fn the function returning a new CompletableFuture - * @return the CompletableFuture - */ public CompletableFuture thenCompose - (Function> fn) { + (Function> fn) { return doThenCompose(fn, null); } - /** - * Returns a CompletableFuture that upon completion, has the same - * value as that produced asynchronously using the {@link - * ForkJoinPool#commonPool()} by the given function of the result - * of this CompletableFuture. - * - *

If this CompletableFuture completes exceptionally, then the - * returned CompletableFuture also does so, with a - * CompletionException holding this exception as its cause. - * Similarly, if the computed CompletableFuture completes - * exceptionally, then so does the returned CompletableFuture. - * - * @param fn the function returning a new CompletableFuture - * @return the CompletableFuture - */ public CompletableFuture thenComposeAsync - (Function> fn) { + (Function> fn) { return doThenCompose(fn, ForkJoinPool.commonPool()); } - /** - * Returns a CompletableFuture that upon completion, has the same - * value as that produced asynchronously using the given executor - * by the given function of this CompletableFuture. - * - *

If this CompletableFuture completes exceptionally, then the - * returned CompletableFuture also does so, with a - * CompletionException holding this exception as its cause. - * Similarly, if the computed CompletableFuture completes - * exceptionally, then so does the returned CompletableFuture. - * - * @param fn the function returning a new CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the CompletableFuture - */ public CompletableFuture thenComposeAsync - (Function> fn, + (Function> fn, Executor executor) { if (executor == null) throw new NullPointerException(); return doThenCompose(fn, executor); } - private CompletableFuture doThenCompose - (Function> fn, - Executor e) { - if (fn == null) throw new NullPointerException(); - CompletableFuture dst = null; - ThenCompose d = null; - Object r; - if ((r = result) == null) { - dst = new CompletableFuture(); - CompletionNode p = new CompletionNode - (d = new ThenCompose(this, fn, dst, e)); - while ((r = result) == null) { - if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - break; - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - if (ex == null) { - if (e != null) { - if (dst == null) - dst = new CompletableFuture(); - e.execute(new AsyncCompose(t, fn, dst)); - } - else { - try { - if ((dst = fn.apply(t)) == null) - ex = new NullPointerException(); - } catch (Throwable rex) { - ex = rex; - } - } - } - if (dst == null) - dst = new CompletableFuture(); - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - dst.helpPostComplete(); - return dst; + public CompletableFuture whenComplete + (BiConsumer action) { + return doWhenComplete(action, null); } + public CompletableFuture whenCompleteAsync + (BiConsumer action) { + return doWhenComplete(action, ForkJoinPool.commonPool()); + } + + public CompletableFuture whenCompleteAsync + (BiConsumer action, + Executor executor) { + if (executor == null) throw new NullPointerException(); + return doWhenComplete(action, executor); + } + + public CompletableFuture handle + (BiFunction fn) { + return doHandle(fn, null); + } + + public CompletableFuture handleAsync + (BiFunction fn) { + return doHandle(fn, ForkJoinPool.commonPool()); + } + + public CompletableFuture handleAsync + (BiFunction fn, + Executor executor) { + if (executor == null) throw new NullPointerException(); + return doHandle(fn, executor); + } + + /** + * Returns this CompletableFuture + * + * @return this CompletableFuture + */ + public CompletableFuture toCompletableFuture() { + return this; + } + + // not in interface CompletionStage + /** * Returns a new CompletableFuture that is completed when this * CompletableFuture completes, with the result of the given @@ -2868,6 +2608,8 @@ public class CompletableFuture implements Future { * completion when it completes exceptionally; otherwise, if this * CompletableFuture completes normally, then the returned * CompletableFuture also completes normally with the same value. + * Note: More flexible versions of this functionality are + * available using methods {@code whenComplete} and {@code handle}. * * @param fn the function to use to compute the value of the * returned CompletableFuture if this CompletableFuture completed @@ -2882,7 +2624,8 @@ public class CompletableFuture implements Future { Object r; if ((r = result) == null) { CompletionNode p = - new CompletionNode(d = new ExceptionCompletion(this, fn, dst)); + new CompletionNode(d = new ExceptionCompletion + (this, fn, dst)); while ((r = result) == null) { if (UNSAFE.compareAndSwapObject(this, COMPLETIONS, p.next = completions, p)) @@ -2910,59 +2653,6 @@ public class CompletableFuture implements Future { return dst; } - /** - * Returns a new CompletableFuture that is completed when this - * CompletableFuture completes, with the result of the given - * function of the result and exception of this CompletableFuture's - * completion. The given function is invoked with the result (or - * {@code null} if none) and the exception (or {@code null} if none) - * of this CompletableFuture when complete. - * - * @param fn the function to use to compute the value of the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture handle - (BiFunction fn) { - if (fn == null) throw new NullPointerException(); - CompletableFuture dst = new CompletableFuture(); - HandleCompletion d = null; - Object r; - if ((r = result) == null) { - CompletionNode p = - new CompletionNode(d = new HandleCompletion(this, fn, dst)); - while ((r = result) == null) { - if (UNSAFE.compareAndSwapObject(this, COMPLETIONS, - p.next = completions, p)) - break; - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - U u; Throwable dx; - try { - u = fn.apply(t, ex); - dx = null; - } catch (Throwable rex) { - dx = rex; - u = null; - } - dst.internalComplete(u, dx); - } - helpPostComplete(); - return dst; - } - - /* ------------- Arbitrary-arity constructions -------------- */ /* @@ -3214,6 +2904,21 @@ public class CompletableFuture implements Future { (((AltResult)r).ex instanceof CancellationException); } + /** + * Returns {@code true} if this CompletableFuture completed + * exceptionally, in any way. Possible causes include + * cancellation, explicit invocation of {@code + * completeExceptionally}, and abrupt termination of a + * CompletionStage action. + * + * @return {@code true} if this CompletableFuture completed + * exceptionally + */ + public boolean isCompletedExceptionally() { + Object r; + return ((r = result) instanceof AltResult) && r != NIL; + } + /** * Forcibly sets or resets the value subsequently returned by * method {@link #get()} and related methods, whether or not diff --git a/jdk/src/share/classes/java/util/concurrent/CompletionStage.java b/jdk/src/share/classes/java/util/concurrent/CompletionStage.java new file mode 100644 index 00000000000..6de60980cff --- /dev/null +++ b/jdk/src/share/classes/java/util/concurrent/CompletionStage.java @@ -0,0 +1,760 @@ +/* + * 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. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +package java.util.concurrent; +import java.util.function.Supplier; +import java.util.function.Consumer; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.BiFunction; +import java.util.concurrent.Executor; + +/** + * A stage of a possibly asynchronous computation, that performs an + * action or computes a value when another CompletionStage completes. + * A stage completes upon termination of its computation, but this may + * in turn trigger other dependent stages. The functionality defined + * in this interface takes only a few basic forms, which expand out to + * a larger set of methods to capture a range of usage styles:

    + * + *
  • The computation performed by a stage may be expressed as a + * Function, Consumer, or Runnable (using methods with names including + * apply, accept, or run, respectively) + * depending on whether it requires arguments and/or produces results. + * For example, {@code stage.thenApply(x -> square(x)).thenAccept(x -> + * System.out.print(x)).thenRun(() -> System.out.println())}. An + * additional form (compose) applies functions of stages + * themselves, rather than their results.
  • + * + *
  • One stage's execution may be triggered by completion of a + * single stage, or both of two stages, or either of two stages. + * Dependencies on a single stage are arranged using methods with + * prefix then. Those triggered by completion of + * both of two stages may combine their results or + * effects, using correspondingly named methods. Those triggered by + * either of two stages make no guarantees about which of the + * results or effects are used for the dependent stage's + * computation.
  • + * + *
  • Dependencies among stages control the triggering of + * computations, but do not otherwise guarantee any particular + * ordering. Additionally, execution of a new stage's computations may + * be arranged in any of three ways: default execution, default + * asynchronous execution (using methods with suffix async + * that employ the stage's default asynchronous execution facility), + * or custom (via a supplied {@link Executor}). The execution + * properties of default and async modes are specified by + * CompletionStage implementations, not this interface. Methods with + * explicit Executor arguments may have arbitrary execution + * properties, and might not even support concurrent execution, but + * are arranged for processing in a way that accommodates asynchrony. + * + *
  • Two method forms support processing whether the triggering + * stage completed normally or exceptionally: Method {@link + * #whenComplete whenComplete} allows injection of an action + * regardless of outcome, otherwise preserving the outcome in its + * completion. Method {@link #handle handle} additionally allows the + * stage to compute a replacement result that may enable further + * processing by other dependent stages. In all other cases, if a + * stage's computation terminates abruptly with an (unchecked) + * exception or error, then all dependent stages requiring its + * completion complete exceptionally as well, with a {@link + * CompletionException} holding the exception as its cause. If a + * stage is dependent on both of two stages, and both + * complete exceptionally, then the CompletionException may correspond + * to either one of these exceptions. If a stage is dependent on + * either of two others, and only one of them completes + * exceptionally, no guarantees are made about whether the dependent + * stage completes normally or exceptionally. In the case of method + * {@code whenComplete}, when the supplied action itself encounters an + * exception, then the stage exceptionally completes with this + * exception if not already completed exceptionally.
  • + * + *
+ * + *

All methods adhere to the above triggering, execution, and + * exceptional completion specifications (which are not repeated in + * individual method specifications). Additionally, while arguments + * used to pass a completion result (that is, for parameters of type + * {@code T}) for methods accepting them may be null, passing a null + * value for any other parameter will result in a {@link + * NullPointerException} being thrown. + * + *

This interface does not define methods for initially creating, + * forcibly completing normally or exceptionally, probing completion + * status or results, or awaiting completion of a stage. + * Implementations of CompletionStage may provide means of achieving + * such effects, as appropriate. Method {@link #toCompletableFuture} + * enables interoperability among different implementations of this + * interface by providing a common conversion type. + * + * @author Doug Lea + * @since 1.8 + */ +public interface CompletionStage { + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed with this stage's result as the argument + * to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage thenApply(Function fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using this stage's default asynchronous + * execution facility, with this stage's result as the argument to + * the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage thenApplyAsync + (Function fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using the supplied Executor, with this + * stage's result as the argument to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage thenApplyAsync + (Function fn, + Executor executor); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed with this stage's result as the argument + * to the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage thenAccept(Consumer action); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using this stage's default asynchronous + * execution facility, with this stage's result as the argument to + * the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage thenAcceptAsync(Consumer action); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using the supplied Executor, with this + * stage's result as the argument to the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage thenAcceptAsync(Consumer action, + Executor executor); + /** + * Returns a new CompletionStage that, when this stage completes + * normally, executes the given action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage thenRun(Runnable action); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, executes the given action using this stage's default + * asynchronous execution facility. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage thenRunAsync(Runnable action); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, executes the given action using the supplied Executor. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage thenRunAsync(Runnable action, + Executor executor); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage both complete normally, is executed with the two + * results as arguments to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param the type of the other CompletionStage's result + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage thenCombine + (CompletionStage other, + BiFunction fn); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, is executed using this stage's + * default asynchronous execution facility, with the two results + * as arguments to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param the type of the other CompletionStage's result + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage thenCombineAsync + (CompletionStage other, + BiFunction fn); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, is executed using the supplied + * executor, with the two results as arguments to the supplied + * function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @param the type of the other CompletionStage's result + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage thenCombineAsync + (CompletionStage other, + BiFunction fn, + Executor executor); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage both complete normally, is executed with the two + * results as arguments to the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param the type of the other CompletionStage's result + * @return the new CompletionStage + */ + public CompletionStage thenAcceptBoth + (CompletionStage other, + BiConsumer action); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, is executed using this stage's + * default asynchronous execution facility, with the two results + * as arguments to the supplied action. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param the type of the other CompletionStage's result + * @return the new CompletionStage + */ + public CompletionStage thenAcceptBothAsync + (CompletionStage other, + BiConsumer action); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, is executed using the supplied + * executor, with the two results as arguments to the supplied + * function. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @param the type of the other CompletionStage's result + * @return the new CompletionStage + */ + public CompletionStage thenAcceptBothAsync + (CompletionStage other, + BiConsumer action, + Executor executor); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage both complete normally, executes the given action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage runAfterBoth(CompletionStage other, + Runnable action); + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, executes the given action using + * this stage's default asynchronous execution facility. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage runAfterBothAsync(CompletionStage other, + Runnable action); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, executes the given action using + * the supplied executor + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage runAfterBothAsync(CompletionStage other, + Runnable action, + Executor executor); + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed with the + * corresponding result as argument to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage applyToEither + (CompletionStage other, + Function fn); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed using this + * stage's default asynchronous execution facility, with the + * corresponding result as argument to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage applyToEitherAsync + (CompletionStage other, + Function fn); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed using the + * supplied executor, with the corresponding result as argument to + * the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage applyToEitherAsync + (CompletionStage other, + Function fn, + Executor executor); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed with the + * corresponding result as argument to the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage acceptEither + (CompletionStage other, + Consumer action); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed using this + * stage's default asynchronous execution facility, with the + * corresponding result as argument to the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage acceptEitherAsync + (CompletionStage other, + Consumer action); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed using the + * supplied executor, with the corresponding result as argument to + * the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage acceptEitherAsync + (CompletionStage other, + Consumer action, + Executor executor); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, executes the given action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage runAfterEither(CompletionStage other, + Runnable action); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, executes the given action + * using this stage's default asynchronous execution facility. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage runAfterEitherAsync + (CompletionStage other, + Runnable action); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, executes the given action + * using supplied executor. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage runAfterEitherAsync + (CompletionStage other, + Runnable action, + Executor executor); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed with this stage as the argument + * to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function returning a new CompletionStage + * @param the type of the returned CompletionStage's result + * @return the CompletionStage + */ + public CompletionStage thenCompose + (Function> fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using this stage's default asynchronous + * execution facility, with this stage as the argument to the + * supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function returning a new CompletionStage + * @param the type of the returned CompletionStage's result + * @return the CompletionStage + */ + public CompletionStage thenComposeAsync + (Function> fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using the supplied Executor, with this + * stage's result as the argument to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function returning a new CompletionStage + * @param executor the executor to use for asynchronous execution + * @param the type of the returned CompletionStage's result + * @return the CompletionStage + */ + public CompletionStage thenComposeAsync + (Function> fn, + Executor executor); + + /** + * Returns a new CompletionStage that, when this stage completes + * exceptionally, is executed with this stage's exception as the + * argument to the supplied function. Otherwise, if this stage + * completes normally, then the returned stage also completes + * normally with the same value. + * + * @param fn the function to use to compute the value of the + * returned CompletionStage if this CompletionStage completed + * exceptionally + * @return the new CompletionStage + */ + public CompletionStage exceptionally + (Function fn); + + /** + * Returns a new CompletionStage with the same result or exception + * as this stage, and when this stage completes, executes the + * given action with the result (or {@code null} if none) and the + * exception (or {@code null} if none) of this stage. + * + * @param action the action to perform + * @return the new CompletionStage + */ + public CompletionStage whenComplete + (BiConsumer action); + + /** + * Returns a new CompletionStage with the same result or exception + * as this stage, and when this stage completes, executes the + * given action executes the given action using this stage's + * default asynchronous execution facility, with the result (or + * {@code null} if none) and the exception (or {@code null} if + * none) of this stage as arguments. + * + * @param action the action to perform + * @return the new CompletionStage + */ + public CompletionStage whenCompleteAsync + (BiConsumer action); + + /** + * Returns a new CompletionStage with the same result or exception + * as this stage, and when this stage completes, executes using + * the supplied Executor, the given action with the result (or + * {@code null} if none) and the exception (or {@code null} if + * none) of this stage as arguments. + * + * @param action the action to perform + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage whenCompleteAsync + (BiConsumer action, + Executor executor); + + /** + * Returns a new CompletionStage that, when this stage completes + * either normally or exceptionally, is executed with this stage's + * result and exception as arguments to the supplied function. + * The given function is invoked with the result (or {@code null} + * if none) and the exception (or {@code null} if none) of this + * stage when complete as arguments. + * + * @param fn the function to use to compute the value of the + * returned CompletionStage + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage handle + (BiFunction fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * either normally or exceptionally, is executed using this stage's + * default asynchronous execution facility, with this stage's + * result and exception as arguments to the supplied function. + * The given function is invoked with the result (or {@code null} + * if none) and the exception (or {@code null} if none) of this + * stage when complete as arguments. + * + * @param fn the function to use to compute the value of the + * returned CompletionStage + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage handleAsync + (BiFunction fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * either normally or exceptionally, is executed using the + * supplied executor, with this stage's result and exception as + * arguments to the supplied function. The given function is + * invoked with the result (or {@code null} if none) and the + * exception (or {@code null} if none) of this stage when complete + * as arguments. + * + * @param fn the function to use to compute the value of the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @param the function's return type + * @return the new CompletionStage + */ + public CompletionStage handleAsync + (BiFunction fn, + Executor executor); + + /** + * Returns a {@link CompletableFuture} maintaining the same + * completion properties as this stage. If this stage is already a + * CompletableFuture, this method may return this stage itself. + * Otherwise, invocation of this method may be equivalent in + * effect to {@code thenApply(x -> x)}, but returning an instance + * of type {@code CompletableFuture}. A CompletionStage + * implementation that does not choose to interoperate with others + * may throw {@code UnsupportedOperationException}. + * + * @return the CompletableFuture + * @throws UnsupportedOperationException if this implementation + * does not interoperate with CompletableFuture + */ + public CompletableFuture toCompletableFuture(); + +} diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 595dfb1a30d..7dcb991f486 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -370,12 +370,6 @@ java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java generic-all # Filed 6772009 java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java generic-all -# 8020435 -java/util/concurrent/CompletableFuture/Basic.java generic-all - -# 8020291 -java/util/Random/RandomStreamTest.java generic-all - # 7041639, Solaris DSA keypair generation bug java/util/TimeZone/TimeZoneDatePermissionCheck.sh solaris-all diff --git a/jdk/test/java/util/concurrent/CompletableFuture/Basic.java b/jdk/test/java/util/concurrent/CompletableFuture/Basic.java index ec6909de2de..f6233892c90 100644 --- a/jdk/test/java/util/concurrent/CompletableFuture/Basic.java +++ b/jdk/test/java/util/concurrent/CompletableFuture/Basic.java @@ -34,6 +34,8 @@ /* * @test * @bug 8005696 + * @run main Basic + * @run main/othervm -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 Basic * @summary Basic tests for CompletableFuture * @author Chris Hegarty */ From 2c31d993a43254f31c7a1652ad5a4bda13cd040a Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Wed, 31 Jul 2013 10:53:33 -0700 Subject: [PATCH 12/39] 6476168: (fmt) Inconsistency formatting subnormal doubles with hexadecimal conversion Update specification to match implementation. Reviewed-by: darcy --- .../share/classes/java/util/Formatter.java | 30 ++++++---- .../java/util/Formatter/Basic-X.java.template | 59 ++++++++++++++----- jdk/test/java/util/Formatter/Basic.java | 2 +- jdk/test/java/util/Formatter/BasicDouble.java | 59 ++++++++++++++----- 4 files changed, 107 insertions(+), 43 deletions(-) diff --git a/jdk/src/share/classes/java/util/Formatter.java b/jdk/src/share/classes/java/util/Formatter.java index 5c096c63acf..275e1854e0a 100644 --- a/jdk/src/share/classes/java/util/Formatter.java +++ b/jdk/src/share/classes/java/util/Formatter.java @@ -626,12 +626,11 @@ import sun.misc.FormattedFloatingDecimal; *

For general argument types, the precision is the maximum number of * characters to be written to the output. * - *

For the floating-point conversions {@code 'e'}, {@code 'E'}, and - * {@code 'f'} the precision is the number of digits after the decimal - * separator. If the conversion is {@code 'g'} or {@code 'G'}, then the + *

For the floating-point conversions {@code 'a'}, {@code 'A'}, {@code 'e'}, + * {@code 'E'}, and {@code 'f'} the precision is the number of digits after the + * radix point. If the conversion is {@code 'g'} or {@code 'G'}, then the * precision is the total number of digits in the resulting magnitude after - * rounding. If the conversion is {@code 'a'} or {@code 'A'}, then the - * precision must not be specified. + * rounding. * *

For character, integral, and date/time argument types and the percent * and line separator conversions, the precision is not applicable; if a @@ -1297,14 +1296,21 @@ import sun.misc.FormattedFloatingDecimal; * of the significand as a fraction. The exponent is represented by * {@code 'p'} ('\u0070') followed by a decimal string of the * unbiased exponent as if produced by invoking {@link - * Integer#toString(int) Integer.toString} on the exponent value. + * Integer#toString(int) Integer.toString} on the exponent value. If the + * precision is specified, the value is rounded to the given number of + * hexadecimal digits. * *

  • If m is a {@code double} value with a subnormal - * representation then the significand is represented by the characters - * {@code '0x0.'} followed by the hexadecimal representation of the rest - * of the significand as a fraction. The exponent is represented by - * {@code 'p-1022'}. Note that there must be at least one nonzero digit - * in a subnormal significand. + * representation then, unless the precision is specified to be in the range + * 1 through 12, inclusive, the significand is represented by the characters + * {@code '0x0.'} followed by the hexadecimal representation of the rest of + * the significand as a fraction, and the exponent represented by + * {@code 'p-1022'}. If the precision is in the interval + * [1, 12], the subnormal value is normalized such that it + * begins with the characters {@code '0x1.'}, rounded to the number of + * hexadecimal digits of precision, and the exponent adjusted + * accordingly. Note that there must be at least one nonzero digit in a + * subnormal significand. * * * @@ -1367,7 +1373,7 @@ import sun.misc.FormattedFloatingDecimal; * {@code 1}. * *

    If the conversion is {@code 'a'} or {@code 'A'}, then the precision - * is the number of hexadecimal digits after the decimal separator. If the + * is the number of hexadecimal digits after the radix point. If the * precision is not provided, then all of the digits as returned by {@link * Double#toHexString(double)} will be output. * diff --git a/jdk/test/java/util/Formatter/Basic-X.java.template b/jdk/test/java/util/Formatter/Basic-X.java.template index a2d586a8958..813cf2d6782 100644 --- a/jdk/test/java/util/Formatter/Basic-X.java.template +++ b/jdk/test/java/util/Formatter/Basic-X.java.template @@ -1319,10 +1319,8 @@ public class Basic$Type$ extends Basic { Math.nextDown(DoubleConsts.MIN_NORMAL)); test("%.1a", "0x1.0p-1022", Math.nextDown(DoubleConsts.MIN_NORMAL)); - test("%.11a", "0x1.ffffffffffep-1023", - Double.parseDouble("0x0.fffffffffffp-1022")); - test("%.1a", "0x1.0p-1022", - Double.parseDouble("0x0.fffffffffffp-1022")); + test("%.11a", "0x1.ffffffffffep-1023", 0x0.fffffffffffp-1022); + test("%.1a", "0x1.0p-1022", 0x0.fffffffffffp-1022); test("%.30a", "0x0.000000000000100000000000000000p-1022", Double.MIN_VALUE); test("%.13a", "0x0.0000000000001p-1022", Double.MIN_VALUE); test("%.11a", "0x1.00000000000p-1074", Double.MIN_VALUE); @@ -1336,19 +1334,50 @@ public class Basic$Type$ extends Basic { test("%.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); test("%.11a", "0x1.00000000000p1024", Double.MAX_VALUE); test("%.1a", "0x1.0p1024", Double.MAX_VALUE); - test("%.11a", "0x1.18000000000p0", Double.parseDouble("0x1.18p0")); - test("%.1a", "0x1.2p0", Double.parseDouble("0x1.18p0")); + test("%.11a", "0x1.18000000000p0", 0x1.18p0); + test("%.1a", "0x1.2p0", 0x1.18p0); - test("%.11a", "0x1.18000000000p0", - Double.parseDouble("0x1.180000000001p0")); - test("%.1a", "0x1.2p0", - Double.parseDouble("0x1.180000000001p0")); - test("%.11a", "0x1.28000000000p0", Double.parseDouble("0x1.28p0")); - test("%.1a", "0x1.2p0", Double.parseDouble("0x1.28p0")); + test("%.11a", "0x1.18000000000p0", 0x1.180000000001p0); + test("%.1a", "0x1.2p0", 0x1.180000000001p0); + test("%.11a", "0x1.28000000000p0", 0x1.28p0); + test("%.1a", "0x1.2p0", 0x1.28p0); + + test("%.11a", "0x1.28000000000p0", 0x1.280000000001p0); + test("%.1a", "0x1.3p0", 0x1.280000000001p0); + + test("%a", "0x0.123p-1022", 0x0.123p-1022); + test("%1.3a", "0x1.230p-1026", 0x0.123p-1022); + test("%1.12a", "0x1.230000000000p-1026", 0x0.123p-1022); + test("%1.15a", "0x0.123000000000000p-1022", 0x0.123p-1022); + test("%1.5a", "0x1.00000p-1074", 0x0.0000000000001p-1022); + test("%1.7a", "0x1.0000000p-1022", 0x0.fffffffffffffp-1022); + + test("%1.6a", "0x1.230000p-1026", 0x0.123000057p-1022); + test("%1.7a", "0x1.2300005p-1026", 0x0.123000057p-1022); + test("%1.8a", "0x1.23000057p-1026", 0x0.123000057p-1022); + test("%1.9a", "0x1.230000570p-1026", 0x0.123000057p-1022); + + test("%1.6a", "0x1.230000p-1026", 0x0.123000058p-1022); + test("%1.7a", "0x1.2300006p-1026", 0x0.123000058p-1022); + test("%1.8a", "0x1.23000058p-1026", 0x0.123000058p-1022); + test("%1.9a", "0x1.230000580p-1026", 0x0.123000058p-1022); + + test("%1.6a", "0x1.230000p-1026", 0x0.123000059p-1022); + test("%1.7a", "0x1.2300006p-1026", 0x0.123000059p-1022); + test("%1.8a", "0x1.23000059p-1026", 0x0.123000059p-1022); + test("%1.9a", "0x1.230000590p-1026", 0x0.123000059p-1022); + + test("%1.4a", "0x1.0000p-1022", Math.nextDown(Double.MIN_NORMAL)); + + test("%a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); + test("%1.1a", "0x1.0p1024", Double.MAX_VALUE); + test("%1.2a", "0x1.00p1024", Double.MAX_VALUE); + test("%1.6a", "0x1.000000p1024", Double.MAX_VALUE); + test("%1.9a", "0x1.000000000p1024", Double.MAX_VALUE); + test("%1.11a", "0x1.00000000000p1024", Double.MAX_VALUE); + test("%1.12a", "0x1.000000000000p1024", Double.MAX_VALUE); + test("%1.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); - test("%.11a", "0x1.28000000000p0", - Double.parseDouble("0x1.280000000001p0")); - test("%.1a", "0x1.3p0", Double.parseDouble("0x1.280000000001p0")); #end[double] //--------------------------------------------------------------------- diff --git a/jdk/test/java/util/Formatter/Basic.java b/jdk/test/java/util/Formatter/Basic.java index 79123a19bca..88b21102818 100644 --- a/jdk/test/java/util/Formatter/Basic.java +++ b/jdk/test/java/util/Formatter/Basic.java @@ -25,7 +25,7 @@ * @summary Unit test for formatter * @bug 4906370 4962433 4973103 4989961 5005818 5031150 4970931 4989491 5002937 * 5005104 5007745 5061412 5055180 5066788 5088703 6317248 6318369 6320122 - * 6344623 6369500 6534606 6282094 6286592 6476425 5063507 6469160 + * 6344623 6369500 6534606 6282094 6286592 6476425 5063507 6469160 6476168 * * @run shell/timeout=240 Basic.sh */ diff --git a/jdk/test/java/util/Formatter/BasicDouble.java b/jdk/test/java/util/Formatter/BasicDouble.java index 4c86c29c198..fa7bd1efa7d 100644 --- a/jdk/test/java/util/Formatter/BasicDouble.java +++ b/jdk/test/java/util/Formatter/BasicDouble.java @@ -1319,10 +1319,8 @@ public class BasicDouble extends Basic { Math.nextDown(DoubleConsts.MIN_NORMAL)); test("%.1a", "0x1.0p-1022", Math.nextDown(DoubleConsts.MIN_NORMAL)); - test("%.11a", "0x1.ffffffffffep-1023", - Double.parseDouble("0x0.fffffffffffp-1022")); - test("%.1a", "0x1.0p-1022", - Double.parseDouble("0x0.fffffffffffp-1022")); + test("%.11a", "0x1.ffffffffffep-1023", 0x0.fffffffffffp-1022); + test("%.1a", "0x1.0p-1022", 0x0.fffffffffffp-1022); test("%.30a", "0x0.000000000000100000000000000000p-1022", Double.MIN_VALUE); test("%.13a", "0x0.0000000000001p-1022", Double.MIN_VALUE); test("%.11a", "0x1.00000000000p-1074", Double.MIN_VALUE); @@ -1336,19 +1334,50 @@ public class BasicDouble extends Basic { test("%.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); test("%.11a", "0x1.00000000000p1024", Double.MAX_VALUE); test("%.1a", "0x1.0p1024", Double.MAX_VALUE); - test("%.11a", "0x1.18000000000p0", Double.parseDouble("0x1.18p0")); - test("%.1a", "0x1.2p0", Double.parseDouble("0x1.18p0")); + test("%.11a", "0x1.18000000000p0", 0x1.18p0); + test("%.1a", "0x1.2p0", 0x1.18p0); - test("%.11a", "0x1.18000000000p0", - Double.parseDouble("0x1.180000000001p0")); - test("%.1a", "0x1.2p0", - Double.parseDouble("0x1.180000000001p0")); - test("%.11a", "0x1.28000000000p0", Double.parseDouble("0x1.28p0")); - test("%.1a", "0x1.2p0", Double.parseDouble("0x1.28p0")); + test("%.11a", "0x1.18000000000p0", 0x1.180000000001p0); + test("%.1a", "0x1.2p0", 0x1.180000000001p0); + test("%.11a", "0x1.28000000000p0", 0x1.28p0); + test("%.1a", "0x1.2p0", 0x1.28p0); + + test("%.11a", "0x1.28000000000p0", 0x1.280000000001p0); + test("%.1a", "0x1.3p0", 0x1.280000000001p0); + + test("%a", "0x0.123p-1022", 0x0.123p-1022); + test("%1.3a", "0x1.230p-1026", 0x0.123p-1022); + test("%1.12a", "0x1.230000000000p-1026", 0x0.123p-1022); + test("%1.15a", "0x0.123000000000000p-1022", 0x0.123p-1022); + test("%1.5a", "0x1.00000p-1074", 0x0.0000000000001p-1022); + test("%1.7a", "0x1.0000000p-1022", 0x0.fffffffffffffp-1022); + + test("%1.6a", "0x1.230000p-1026", 0x0.123000057p-1022); + test("%1.7a", "0x1.2300005p-1026", 0x0.123000057p-1022); + test("%1.8a", "0x1.23000057p-1026", 0x0.123000057p-1022); + test("%1.9a", "0x1.230000570p-1026", 0x0.123000057p-1022); + + test("%1.6a", "0x1.230000p-1026", 0x0.123000058p-1022); + test("%1.7a", "0x1.2300006p-1026", 0x0.123000058p-1022); + test("%1.8a", "0x1.23000058p-1026", 0x0.123000058p-1022); + test("%1.9a", "0x1.230000580p-1026", 0x0.123000058p-1022); + + test("%1.6a", "0x1.230000p-1026", 0x0.123000059p-1022); + test("%1.7a", "0x1.2300006p-1026", 0x0.123000059p-1022); + test("%1.8a", "0x1.23000059p-1026", 0x0.123000059p-1022); + test("%1.9a", "0x1.230000590p-1026", 0x0.123000059p-1022); + + test("%1.4a", "0x1.0000p-1022", Math.nextDown(Double.MIN_NORMAL)); + + test("%a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); + test("%1.1a", "0x1.0p1024", Double.MAX_VALUE); + test("%1.2a", "0x1.00p1024", Double.MAX_VALUE); + test("%1.6a", "0x1.000000p1024", Double.MAX_VALUE); + test("%1.9a", "0x1.000000000p1024", Double.MAX_VALUE); + test("%1.11a", "0x1.00000000000p1024", Double.MAX_VALUE); + test("%1.12a", "0x1.000000000000p1024", Double.MAX_VALUE); + test("%1.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); - test("%.11a", "0x1.28000000000p0", - Double.parseDouble("0x1.280000000001p0")); - test("%.1a", "0x1.3p0", Double.parseDouble("0x1.280000000001p0")); //--------------------------------------------------------------------- From b661fb4e1aee40d80bd0a35959b23af63ab83821 Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Fri, 2 Aug 2013 15:30:11 -0700 Subject: [PATCH 13/39] 8011194: Apps launched via double-clicked .jars have file.encoding value of US-ASCII on Mac OS X On Mac, default to UTF-8 if no environmental hints are available Reviewed-by: naoto, ddehaven --- .../solaris/native/java/lang/java_props_md.c | 19 ++ .../ExpectedEncoding.java | 22 ++- .../MacJNUEncoding.sh | 0 .../System/MacEncoding/TestFileEncoding.java | 168 ++++++++++++++++++ 4 files changed, 203 insertions(+), 6 deletions(-) rename jdk/test/java/lang/System/{MacJNUEncoding => MacEncoding}/ExpectedEncoding.java (72%) rename jdk/test/java/lang/System/{MacJNUEncoding => MacEncoding}/MacJNUEncoding.sh (100%) create mode 100644 jdk/test/java/lang/System/MacEncoding/TestFileEncoding.java diff --git a/jdk/src/solaris/native/java/lang/java_props_md.c b/jdk/src/solaris/native/java/lang/java_props_md.c index c8c18982585..58e5e4543d7 100644 --- a/jdk/src/solaris/native/java/lang/java_props_md.c +++ b/jdk/src/solaris/native/java/lang/java_props_md.c @@ -360,6 +360,25 @@ static int ParseLocale(JNIEnv* env, int cat, char ** std_language, char ** std_s */ *std_encoding = "Big5-HKSCS-2001"; } +#endif +#ifdef MACOSX + /* + * For the case on MacOS X where encoding is set to US-ASCII, but we + * don't have any encoding hints from LANG/LC_ALL/LC_CTYPE, use UTF-8 + * instead. + * + * The contents of ASCII files will still be read and displayed + * correctly, but so will files containing UTF-8 characters beyond the + * standard ASCII range. + * + * Specifically, this allows apps launched by double-clicking a .jar + * file to correctly read UTF-8 files using the default encoding (see + * 8011194). + */ + if (strcmp(p,"US-ASCII") == 0 && getenv("LANG") == NULL && + getenv("LC_ALL") == NULL && getenv("LC_CTYPE") == NULL) { + *std_encoding = "UTF-8"; + } #endif } diff --git a/jdk/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java b/jdk/test/java/lang/System/MacEncoding/ExpectedEncoding.java similarity index 72% rename from jdk/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java rename to jdk/test/java/lang/System/MacEncoding/ExpectedEncoding.java index 723d45c677f..f9eb5161356 100644 --- a/jdk/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java +++ b/jdk/test/java/lang/System/MacEncoding/ExpectedEncoding.java @@ -31,6 +31,7 @@ public class ExpectedEncoding { if (args.length != 2) { System.out.println("Usage:"); System.out.println("$ java ExpectedEncoding "); + System.out.println("$ use \"skip\" to skip checking property's value"); System.exit(1); } String expectFileEnc = args[0]; @@ -39,16 +40,25 @@ public class ExpectedEncoding { String fileEnc = System.getProperty("file.encoding"); String jnuEnc = System.getProperty("sun.jnu.encoding"); - if (fileEnc == null || !fileEnc.equals(expectFileEnc)) { + if ("skip".equals(expectFileEnc)) { + System.err.println("Expected file.encoding is \"skip\", ignoring"); + } else { System.err.println("Expected file.encoding: " + expectFileEnc); System.err.println("Actual file.encoding: " + fileEnc); - failed = true; + if (fileEnc == null || !fileEnc.equals(expectFileEnc)) { + failed = true; + } } - if (jnuEnc == null || !jnuEnc.equals(expectSunJnuEnc)) { - System.err.println("Expected sun.jnu.encoding: " + expectSunJnuEnc); - System.err.println("Actual sun.jnu.encoding: " + jnuEnc); - failed = true; + if ("skip".equals(expectSunJnuEnc)) { + System.err.println("Expected sun.jnu.encoding is \"skip\", ignoring"); + } else { + if (jnuEnc == null || !jnuEnc.equals(expectSunJnuEnc)) { + System.err.println("Expected sun.jnu.encoding: " + expectSunJnuEnc); + System.err.println("Actual sun.jnu.encoding: " + jnuEnc); + failed = true; + } } + if (failed) { throw new RuntimeException("Test Failed"); } diff --git a/jdk/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh b/jdk/test/java/lang/System/MacEncoding/MacJNUEncoding.sh similarity index 100% rename from jdk/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh rename to jdk/test/java/lang/System/MacEncoding/MacJNUEncoding.sh diff --git a/jdk/test/java/lang/System/MacEncoding/TestFileEncoding.java b/jdk/test/java/lang/System/MacEncoding/TestFileEncoding.java new file mode 100644 index 00000000000..f911d5b8653 --- /dev/null +++ b/jdk/test/java/lang/System/MacEncoding/TestFileEncoding.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013, 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.util.*; + +/* + * @test + * @bug 8011194 + * @summary Test value of file.encoding for corresponding value of LANG, etc + * @library ../../../../tools/launcher/ ../ + * @build TestHelper TestFileEncoding ExpectedEncoding + * @run main TestFileEncoding UTF-8 + * @run main/othervm -Dfile.encoding=MyEncoding -DuserEncoding=MyEncoding TestFileEncoding MyEncoding + * @run main TestFileEncoding UTF-8 en_US.UTF-8 + * @run main/othervm -Dfile.encoding=MyEncoding -DuserEncoding=MyEncoding TestFileEncoding MyEncoding en_US.UTF-8 + * @run main TestFileEncoding US-ASCII C + * @run main/othervm -Dfile.encoding=MyEncoding -DuserEncoding=MyEncoding TestFileEncoding MyEncoding C + * @author Brent Christian + */ + +/** + * Setup the environment and run a sub-test to check the expected value of + * file.encoding, based on the value(s) of encoding-related environment vars + * (LANG, LC_ALL, LC_CTYPE). + * + * The first argument (required) is the expected value of the + * file.encoding System property. + * The second argument (optional) is the value to set to the LANG/etc env vars. + */ +public class TestFileEncoding { + private static final String TEST_NAME = "ExpectedEncoding"; + + private String expectedEncoding; // Expected value for file.encoding + private String langVar = null; // Value to set for LANG, etc + + private static Set envToRm = new HashSet<>(3); + static { + // Take these vars out of the test's run environment, possibly adding + // our own value back in. + envToRm.add("LANG"); + envToRm.add("LC_ALL"); + envToRm.add("LC_CTYPE"); + } + + public TestFileEncoding(String expectedEncoding) { + this.expectedEncoding = expectedEncoding; + } + + public TestFileEncoding(String expectedEncoding, String langVar) { + this.expectedEncoding = expectedEncoding; + this.langVar = langVar; + } + + /* + * Launch ExpectedEncoding with the given parameters, check for the + * expected file.encoding. + */ + private void run() { + String testClasses = System.getProperty("test.classes"); + + // Pick up VM opts + String vmOptsStr = System.getProperty("test.vm.opts"); + System.out.println("test.vm.opts: " + vmOptsStr); + String[] vmOpts = new String[0]; + if (vmOptsStr != null && !"".equals(vmOptsStr)) { + vmOpts = vmOptsStr.split(" "); + System.out.println("found vm options:"); + for (String opt : vmOpts) { + System.out.println(" <" + opt + ">"); + } + } + + // Build java cmd + LinkedList cmdList = new LinkedList<>(); + cmdList.add(TestHelper.javaCmd); + for (String vmOpt : vmOpts) { + if (vmOpt != null && !vmOpt.equals("")) { + cmdList.add(vmOpt); + } + } + + // See if the user specified a file.encoding that we should pass through + String userEncoding = System.getProperty("userEncoding"); + if (userEncoding != null) { + cmdList.add("-Dfile.encoding="+userEncoding); + } + + cmdList.add("-cp"); + cmdList.add(testClasses); + cmdList.add(TEST_NAME); + cmdList.add(expectedEncoding); + cmdList.add("skip"); // ignore sun.jnu.encoding for this test + + String cmdArray[] = new String[cmdList.size()]; + cmdList.toArray(cmdArray); + + // Run the test(s) + if (langVar == null) { + System.out.println("TestFileEncoding: Running with no envvars set"); + TestHelper.TestResult tr = TestHelper.doExec(null, envToRm, + cmdArray); + checkResult(tr); + } else { + runWithEnvVar("LANG", cmdArray); + runWithEnvVar("LC_ALL", cmdArray); + runWithEnvVar("LC_CTYPE", cmdArray); + } + } + + /* + * Run the test, setting the environment named by envVarName to the value + * in langVar. + */ + private void runWithEnvVar(String envVarName, String[] cmdArray) { + Map envToAdd = new HashMap<>(1); + TestHelper.TestResult tr = null; + + System.out.println("TestFileEncoding: Running with " + envVarName + "=" + langVar); + envToAdd.put(envVarName, langVar); + tr = TestHelper.doExec(envToAdd, envToRm, cmdArray); + checkResult(tr); + } + + private void checkResult(TestHelper.TestResult tr) { + System.out.println(tr); + if (!tr.isOK()) { + throw new RuntimeException("TEST FAILED: !tr.isOK()"); + } + } + + public static void main(String[] args) { + TestFileEncoding cfe = null; + if (!TestHelper.isMacOSX) { + System.out.println("Test is currently only for Mac OS X - pass."); + return; + } + if (args.length == 1) { + cfe = new TestFileEncoding(args[0]); + } else if (args.length == 2) { + cfe = new TestFileEncoding(args[0], args[1]); + } else { + System.out.println("Usage: TestFileEncoding "); + System.out.println(" TestFileEncoding "); + return; + } + cfe.run(); + } +} From aafacb6fa664f26689076592a896b79c63eb5ac0 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Fri, 2 Aug 2013 11:10:41 -0700 Subject: [PATCH 14/39] 8022094: BigDecimal/CompareToTests and BigInteger/CompareToTests are incorrect Fail test if errors; fix test values; port BigDecimal version to BigInteger Reviewed-by: smarks, alanb --- .../java/math/BigDecimal/CompareToTests.java | 35 +++++--- .../java/math/BigInteger/CompareToTests.java | 81 ++++++++++++------- 2 files changed, 79 insertions(+), 37 deletions(-) diff --git a/jdk/test/java/math/BigDecimal/CompareToTests.java b/jdk/test/java/math/BigDecimal/CompareToTests.java index 311f378d652..f9e3d258299 100644 --- a/jdk/test/java/math/BigDecimal/CompareToTests.java +++ b/jdk/test/java/math/BigDecimal/CompareToTests.java @@ -53,12 +53,29 @@ public class CompareToTests { {valueOf(5,-1), valueOf(2), ONE}, // Boundary and near boundary values - {valueOf(Long.MAX_VALUE), valueOf(Long.MAX_VALUE), ZERO}, - {valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE), valueOf(Long.MIN_VALUE), ZERO}, - {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), ONE}, + {valueOf(Long.MAX_VALUE), valueOf(Long.MAX_VALUE), ZERO}, + {valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE}, + + {valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE}, + + {valueOf(Long.MIN_VALUE), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MAX_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MAX_VALUE), ZERO}, + + {valueOf(Long.MAX_VALUE), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MAX_VALUE-1), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE), valueOf(Long.MIN_VALUE), ZERO}, + {valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE+1), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MIN_VALUE), ONE}, }; for (BigDecimal[] testCase : testCases) { @@ -69,8 +86,6 @@ public class CompareToTests { int expected = testCase[2].intValue(); failures += compareToTest(a, b, expected); - failures += compareToTest(a_negate, b, -1); - failures += compareToTest(a, b_negate, 1); failures += compareToTest(a_negate, b_negate, -expected); } @@ -81,11 +96,11 @@ public class CompareToTests { private static int compareToTest(BigDecimal a, BigDecimal b, int expected) { int result = a.compareTo(b); int failed = (result==expected) ? 0 : 1; - if (result == 1) { + if (failed == 1) { System.err.println("(" + a + ").compareTo(" + b + ") => " + result + "\n\tExpected " + expected); } - return result; + return failed; } public static void main(String argv[]) { diff --git a/jdk/test/java/math/BigInteger/CompareToTests.java b/jdk/test/java/math/BigInteger/CompareToTests.java index 311f378d652..fc4386a797a 100644 --- a/jdk/test/java/math/BigInteger/CompareToTests.java +++ b/jdk/test/java/math/BigInteger/CompareToTests.java @@ -24,20 +24,23 @@ /* * @test * @bug 6473768 - * @summary Tests of BigDecimal.compareTo + * @summary Tests of BigInteger.compareTo * @author Joseph D. Darcy */ import java.math.*; -import static java.math.BigDecimal.*; +import static java.math.BigInteger.*; public class CompareToTests { private static int compareToTests() { int failures = 0; - final BigDecimal MINUS_ONE = BigDecimal.ONE.negate(); + final BigInteger MINUS_ONE = BigInteger.ONE.negate(); + final BigInteger TWO_POW_126 = ONE.shiftLeft(126); + final BigInteger TWO_POW_127 = ONE.shiftLeft(127); + final BigInteger TWO_POW_128 = ONE.shiftLeft(128); // First operand, second operand, expected compareTo result - BigDecimal [][] testCases = { + BigInteger [][] testCases = { // Basics {valueOf(0), valueOf(0), ZERO}, {valueOf(0), valueOf(1), MINUS_ONE}, @@ -45,32 +48,56 @@ public class CompareToTests { {valueOf(2), valueOf(1), ONE}, {valueOf(10), valueOf(10), ZERO}, - // Significands would compare differently than scaled value - {valueOf(2,1), valueOf(2), MINUS_ONE}, - {valueOf(2,-1), valueOf(2), ONE}, - {valueOf(1,1), valueOf(2), MINUS_ONE}, - {valueOf(1,-1), valueOf(2), ONE}, - {valueOf(5,-1), valueOf(2), ONE}, + // Various relative lengths of internal mag array. + {TWO_POW_127, TWO_POW_127, ZERO}, + {TWO_POW_127.negate(), TWO_POW_127, MINUS_ONE}, - // Boundary and near boundary values - {valueOf(Long.MAX_VALUE), valueOf(Long.MAX_VALUE), ZERO}, - {valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE), valueOf(Long.MIN_VALUE), ZERO}, - {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), ONE}, + {TWO_POW_128.or(TWO_POW_126), TWO_POW_128, ONE}, + {TWO_POW_128.or(TWO_POW_126), TWO_POW_128.negate(), ONE}, + + {TWO_POW_128, TWO_POW_128.or(TWO_POW_126), MINUS_ONE}, + {TWO_POW_128.negate(), TWO_POW_128.or(TWO_POW_126), MINUS_ONE}, + + {TWO_POW_127, TWO_POW_128, MINUS_ONE}, + {TWO_POW_127.negate(), TWO_POW_128, MINUS_ONE}, + + {TWO_POW_128, TWO_POW_127, ONE}, + {TWO_POW_128.negate(), TWO_POW_127, MINUS_ONE}, + + // Long boundary and near boundary values + {valueOf(Long.MAX_VALUE), valueOf(Long.MAX_VALUE), ZERO}, + {valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE}, + + {valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE}, + + {valueOf(Long.MIN_VALUE), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MAX_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MAX_VALUE), ZERO}, + + {valueOf(Long.MAX_VALUE), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MAX_VALUE-1), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE), valueOf(Long.MIN_VALUE), ZERO}, + {valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE+1), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MIN_VALUE), ONE}, }; - for (BigDecimal[] testCase : testCases) { - BigDecimal a = testCase[0]; - BigDecimal a_negate = a.negate(); - BigDecimal b = testCase[1]; - BigDecimal b_negate = b.negate(); + for (BigInteger[] testCase : testCases) { + BigInteger a = testCase[0]; + BigInteger a_negate = a.negate(); + BigInteger b = testCase[1]; + BigInteger b_negate = b.negate(); int expected = testCase[2].intValue(); failures += compareToTest(a, b, expected); - failures += compareToTest(a_negate, b, -1); - failures += compareToTest(a, b_negate, 1); failures += compareToTest(a_negate, b_negate, -expected); } @@ -78,14 +105,14 @@ public class CompareToTests { return failures; } - private static int compareToTest(BigDecimal a, BigDecimal b, int expected) { + private static int compareToTest(BigInteger a, BigInteger b, int expected) { int result = a.compareTo(b); int failed = (result==expected) ? 0 : 1; - if (result == 1) { + if (failed == 1) { System.err.println("(" + a + ").compareTo(" + b + ") => " + result + "\n\tExpected " + expected); } - return result; + return failed; } public static void main(String argv[]) { From 2be7768ab06be1db080133019c6aeecbdcb712f7 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Mon, 5 Aug 2013 07:50:16 -0700 Subject: [PATCH 15/39] 8022190: Fix varargs lint warnings in the JDK Reviewed-by: alanb, lancea, alexsch --- jdk/src/share/classes/java/util/stream/Stream.java | 1 + jdk/src/share/classes/javax/swing/SwingWorker.java | 3 ++- .../share/classes/sun/reflect/annotation/AnnotationParser.java | 1 + jdk/src/share/classes/sun/swing/AccumulativeRunnable.java | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/util/stream/Stream.java b/jdk/src/share/classes/java/util/stream/Stream.java index a5f36841f4a..76789d38f13 100644 --- a/jdk/src/share/classes/java/util/stream/Stream.java +++ b/jdk/src/share/classes/java/util/stream/Stream.java @@ -827,6 +827,7 @@ public interface Stream extends BaseStream> { * @return the new stream */ @SafeVarargs + @SuppressWarnings("varargs") // Creating a stream from an array is safe public static Stream of(T... values) { return Arrays.stream(values); } diff --git a/jdk/src/share/classes/javax/swing/SwingWorker.java b/jdk/src/share/classes/javax/swing/SwingWorker.java index 294808188cd..f7b343d8e44 100644 --- a/jdk/src/share/classes/javax/swing/SwingWorker.java +++ b/jdk/src/share/classes/javax/swing/SwingWorker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -405,6 +405,7 @@ public abstract class SwingWorker implements RunnableFuture { * */ @SafeVarargs + @SuppressWarnings("varargs") // Passing chunks to add is safe protected final void publish(V... chunks) { synchronized (this) { if (doProcess == null) { diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java index 341f2033f64..2dc978a4dea 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java @@ -88,6 +88,7 @@ public class AnnotationParser { * @param selectAnnotationClasses an array of annotation types to select when parsing */ @SafeVarargs + @SuppressWarnings("varargs") // selectAnnotationClasses is used safely static Map, Annotation> parseSelectAnnotations( byte[] rawAnnotations, ConstantPool constPool, diff --git a/jdk/src/share/classes/sun/swing/AccumulativeRunnable.java b/jdk/src/share/classes/sun/swing/AccumulativeRunnable.java index a1712731524..ac57e6d2115 100644 --- a/jdk/src/share/classes/sun/swing/AccumulativeRunnable.java +++ b/jdk/src/share/classes/sun/swing/AccumulativeRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -121,6 +121,7 @@ public abstract class AccumulativeRunnable implements Runnable { * @param args the arguments to accumulate */ @SafeVarargs + @SuppressWarnings("varargs") // Copying args is safe public final synchronized void add(T... args) { boolean isSubmitted = true; if (arguments == null) { From bdc36d78a1669edd37eb380a72e00bc7dca7095e Mon Sep 17 00:00:00 2001 From: Andreas Rieber Date: Mon, 5 Aug 2013 21:31:40 +0530 Subject: [PATCH 16/39] 8016531: jconsole-plugin script demo does not work with nashorn Reviewed-by: lagergren, hannesw --- .../scripting/jconsole/ScriptShellPanel.java | 4 +- .../jconsole-plugin/src/resources/jconsole.js | 146 +++++++++++++----- .../jconsole-plugin/src/scripts/invoke.js | 4 +- .../jconsole-plugin/src/scripts/jstack.js | 10 +- .../jconsole-plugin/src/scripts/jtop.js | 12 +- .../jconsole-plugin/src/scripts/sysprops.js | 10 +- .../sample/scripting/scriptpad/README.txt | 2 +- .../scripting/scriptpad/src/resources/conc.js | 4 +- .../scripting/scriptpad/src/resources/mm.js | 57 ++++--- 9 files changed, 156 insertions(+), 93 deletions(-) diff --git a/jdk/src/share/demo/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptShellPanel.java b/jdk/src/share/demo/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptShellPanel.java index 40cf8088169..c7e4dee51bc 100644 --- a/jdk/src/share/demo/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptShellPanel.java +++ b/jdk/src/share/demo/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptShellPanel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -54,7 +54,7 @@ import javax.swing.text.*; * jconsole's script console. */ -class ScriptShellPanel extends JPanel { +public class ScriptShellPanel extends JPanel { private static final long serialVersionUID = 4116273141148726319L; diff --git a/jdk/src/share/demo/scripting/jconsole-plugin/src/resources/jconsole.js b/jdk/src/share/demo/scripting/jconsole-plugin/src/resources/jconsole.js index 715da1d9a56..f39dea30069 100644 --- a/jdk/src/share/demo/scripting/jconsole-plugin/src/resources/jconsole.js +++ b/jdk/src/share/demo/scripting/jconsole-plugin/src/resources/jconsole.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -77,12 +77,37 @@ function jcontext() { return plugin.getContext(); } -jcontext.docString = "returns JConsoleContext for the current jconsole plugin" +jcontext.docString = "returns JConsoleContext for the current jconsole plugin"; function mbeanConnection() { return jcontext().getMBeanServerConnection(); } -mbeanConnection.docString = "returns current MBeanServer connection" +mbeanConnection.docString = "returns current MBeanServer connection"; + +// check if there is a build in sync function, define one if missing +if (typeof sync === "undefined") { + var sync = function(func, obj) { + if (arguments.length < 1 || arguments.length > 2 ) { + throw "sync(function [,object]) parameter count mismatch"; + } + + var syncobj = (arguments.length == 2 ? obj : this); + + if (!syncobj._syncLock) { + syncobj._syncLock = new Lock(); + } + + return function() { + syncobj._syncLock.lock(); + try { + func.apply(null, arguments); + } finally { + syncobj._syncLock.unlock(); + } + }; + }; + sync.docString = "synchronize a function, optionally on an object"; +} /** * Prints one liner help message for each function exposed here @@ -188,22 +213,12 @@ queryMBeans.docString = "return MBeans using given ObjectName and optional query // wraps a script array as java.lang.Object[] function objectArray(array) { - var len = array.length; - var res = java.lang.reflect.Array.newInstance(java.lang.Object, len); - for (var i = 0; i < array.length; i++) { - res[i] = array[i]; - } - return res; + return Java.to(array, "java.lang.Object[]"); } // wraps a script (string) array as java.lang.String[] function stringArray(array) { - var len = array.length; - var res = java.lang.reflect.Array.newInstance(java.lang.String, len); - for (var i = 0; i < array.length; i++) { - res[i] = String(array[i]); - } - return res; + return Java.to(array, "java.lang.String[]"); } // script array to Java List @@ -286,16 +301,18 @@ invokeMBean.docString = "invokes MBean operation on given ObjectName"; * will be of type FutureTask. When you need value, call 'get' on it. */ function mbean(objName, async) { + var index; + objName = objectName(objName); var info = mbeanInfo(objName); var attrs = info.attributes; var attrMap = new Object; - for (var index in attrs) { + for (index in attrs) { attrMap[attrs[index].name] = attrs[index]; } var opers = info.operations; var operMap = new Object; - for (var index in opers) { + for (index in opers) { operMap[opers[index].name] = opers[index]; } @@ -318,21 +335,30 @@ function mbean(objName, async) { } else { return getMBeanAttribute(objName, name); } - } else if (isOperation(name)) { + } else { + return undefined; + } + }, + __call__: function(name) { + if (isOperation(name)) { var oper = operMap[name]; - return function() { - var params = objectArray(arguments); - var sigs = oper.signature; - var sigNames = new Array(sigs.length); - for (var index in sigs) { - sigNames[index] = sigs[index].getType(); - } - if (async) { - return invokeMBean.future(objName, name, - params, sigNames); - } else { - return invokeMBean(objName, name, params, sigNames); - } + + var params = []; + for (var j = 1; j < arguments.length; j++) { + params[j-1]= arguments[j]; + } + + var sigs = oper.signature; + + var sigNames = new Array(sigs.length); + for (var index in sigs) { + sigNames[index] = sigs[index].getType(); + } + + if (async) { + return invokeMBean.future(objName, name, params, sigNames); + } else { + return invokeMBean(objName, name, params, sigNames); } } else { return undefined; @@ -520,7 +546,7 @@ Function.prototype.sync = function (lock) { } finally { lock.unlock(); } -} +}; /** * Causes current thread to sleep for specified @@ -534,8 +560,7 @@ function sleep(interval) { sleep.docString = "wrapper for java.lang.Thread.sleep method"; /** - * Schedules a task to be executed once in - * every N milliseconds specified. + * Schedules a task to be executed once in N milliseconds specified. * * @param callback function or expression to evaluate * @param interval in milliseconds to sleep @@ -549,15 +574,15 @@ function setTimeout(callback, interval) { // start a new thread that sleeps given time // and calls callback in an infinite loop return (function() { - while (true) { + try { sleep(interval); - callback(); - } + } catch (x) { } + callback(); }).daemon(); } -setTimeout.docString = "calls given callback once after specified interval" +setTimeout.docString = "calls given callback once after specified interval"; -/** +/** * Cancels a timeout set earlier. * @param tid timeout ID returned from setTimeout */ @@ -565,6 +590,45 @@ function clearTimeout(tid) { // we just interrupt the timer thread tid.interrupt(); } +clearTimeout.docString = "interrupt a setTimeout timer"; + +/** + * Schedules a task to be executed once in + * every N milliseconds specified. + * + * @param callback function or expression to evaluate + * @param interval in milliseconds to sleep + * @return timeout ID (which is nothing but Thread instance) + */ +function setInterval(callback, interval) { + if (! (callback instanceof Function)) { + callback = new Function(callback); + } + + // start a new thread that sleeps given time + // and calls callback in an infinite loop + return (function() { + while (true) { + try { + sleep(interval); + } catch (x) { + break; + } + callback(); + } + }).daemon(); +} +setInterval.docString = "calls given callback every specified interval"; + +/** + * Cancels a timeout set earlier. + * @param tid timeout ID returned from setTimeout + */ +function clearInterval(tid) { + // we just interrupt the timer thread + tid.interrupt(); +} +clearInterval.docString = "interrupt a setInterval timer"; /** * Simple access to thread local storage. @@ -680,7 +744,7 @@ function msgBox(msg, title, msgType) { if (msg === undefined) msg = "undefined"; if (msg === null) msg = "null"; if (title == undefined) title = msg; - if (msgType == undefined) type = JOptionPane.INFORMATION_MESSAGE; + if (msgType == undefined) msgType = JOptionPane.INFORMATION_MESSAGE; JOptionPane.showMessageDialog(window, msg, title, msgType); } if (isEventThread()) { @@ -800,7 +864,7 @@ echo.docString = "echoes arguments to interactive console screen"; * Clear the screen */ function clear() { - (function() { window.clear(false) }).invokeLater(); + (function() { window.clear(false); }).invokeLater(); } clear.docString = "clears interactive console screen"; diff --git a/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/invoke.js b/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/invoke.js index 8c66e0df388..919769bc493 100644 --- a/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/invoke.js +++ b/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/invoke.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,6 +53,6 @@ * */ function resetPeakThreadCount() { - return invokeMBean("java.lang:type=Threading", "resetPeakThreadCount", [], ""); + return invokeMBean("java.lang:type=Threading", "resetPeakThreadCount", [], {}); } diff --git a/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/jstack.js b/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/jstack.js index b05dc198b47..aff7d7c04e1 100644 --- a/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/jstack.js +++ b/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/jstack.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,16 +43,16 @@ * threads.'jstack' function which can be called once or periodically * from a timer thread (calling it periodically would slow down the target * application). To call this once, just call 'jstack()' in script - * console prompt. To call jtop in a timer thread, you can use + * console prompt. To call jstack in a timer thread, you can use * - * var t = setTimeout(function () { jstack(print); }, 5000); + * var t = setInterval(function () { jstack(print); }, 5000); * * The above call prints threads in sorted order for every 5 seconds. * The print output goes to OS console window from which jconsole was * started. The timer can be cancelled later by clearTimeout() function * as shown below: * - * clearTimeout(t); + * clearInterval(t); */ @@ -87,7 +87,7 @@ function jstack(printFunc, maxFrames) { var tmbean = newPlatformMXBeanProxy( "java.lang:type=Threading", - java.lang.management.ThreadMXBean); + java.lang.management.ThreadMXBean.class); var tids = tmbean.allThreadIds; var tinfos = tmbean["getThreadInfo(long[],int)"](tids, maxFrames); diff --git a/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/jtop.js b/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/jtop.js index daebfc63a4f..2733b12a69e 100644 --- a/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/jtop.js +++ b/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/jtop.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,14 +45,14 @@ * To call this once, just call 'jtop()' in script console prompt. * To call jtop in a timer thread, you can use * - * var t = setTimeout(function () { jtop(print); }, 2000); + * var t = setInterval(function () { jtop(print); }, 2000); * * The above call prints threads in sorted order for every 2 seconds. * The print output goes to OS console window from which jconsole was * started. The timer can be cancelled later by clearTimeout() function * as shown below: - * - * clearTimeout(t); + * + * clearInterval(t); */ /** @@ -62,10 +62,10 @@ function getThreadList() { var tmbean = newPlatformMXBeanProxy( "java.lang:type=Threading", - java.lang.management.ThreadMXBean); + java.lang.management.ThreadMXBean.class); if (!tmbean.isThreadCpuTimeSupported()) { - return; + return java.util.Collections.EMPTY_LIST; } tmbean.setThreadCpuTimeEnabled(true); diff --git a/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/sysprops.js b/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/sysprops.js index d15d482ae57..5ff958d836e 100644 --- a/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/sysprops.js +++ b/jdk/src/share/demo/scripting/jconsole-plugin/src/scripts/sysprops.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,16 +43,16 @@ * properties.'sysprops' function which can be called once or periodically * from a timer thread (calling it periodically would slow down the target * application). To call this once, just call 'sysprops()' in script - * console prompt. To call jtop in a timer thread, you can use + * console prompt. To call sysprops in a timer thread, you can use * - * var t = setTimeout(function () { sysprops(print); }, 5000); + * var t = setInterval(function () { sysprops(print); }, 5000); * * The above call prints threads in sorted order for every 5 seconds. * The print output goes to OS console window from which jconsole was * started. The timer can be cancelled later by clearTimeout() function * as shown below: * - * clearTimeout(t); + * clearInterval(t); */ @@ -62,7 +62,7 @@ function getSystemProps() { var runtimeBean = newPlatformMXBeanProxy( "java.lang:type=Runtime", - java.lang.management.RuntimeMXBean); + java.lang.management.RuntimeMXBean.class); return runtimeBean.systemProperties; } diff --git a/jdk/src/share/sample/scripting/scriptpad/README.txt b/jdk/src/share/sample/scripting/scriptpad/README.txt index 446feae4e0b..ab4bd5fed96 100644 --- a/jdk/src/share/sample/scripting/scriptpad/README.txt +++ b/jdk/src/share/sample/scripting/scriptpad/README.txt @@ -108,7 +108,7 @@ under the ./src/scripts directory. java -Dcom.sun.management.jmxremote.port=1090 \ -Dcom.sun.management.jmxremote.ssl=false \ -Dcom.sun.management.jmxremote.authenticate=false \ - -jar $JDK_HOME/demo/jfc/Java2D/Java2Demo.jar + -jar $JDK_HOME/demo/jfc/Font2DTest/Font2DTest.jar (2) Start scriptpad and click on "Tools->JMX Connect" menu. In the prompt, enter "localhost:1090" to connect to the above diff --git a/jdk/src/share/sample/scripting/scriptpad/src/resources/conc.js b/jdk/src/share/sample/scripting/scriptpad/src/resources/conc.js index 7e56fad4703..aaca49aea79 100644 --- a/jdk/src/share/sample/scripting/scriptpad/src/resources/conc.js +++ b/jdk/src/share/sample/scripting/scriptpad/src/resources/conc.js @@ -221,7 +221,7 @@ sleep.docString = "wrapper for java.lang.Thread.sleep method"; * @return timeout ID (which is nothing but Thread instance) */ function setTimeout(callback, interval) { - if (! (callback instanceof Function) && typeof callback !== "function") { + if (! (callback instanceof Function)) { callback = new Function(callback); } @@ -255,7 +255,7 @@ clearTimeout.docString = "interrupt a setTimeout timer"; * @return timeout ID (which is nothing but Thread instance) */ function setInterval(callback, interval) { - if (! (callback instanceof Function) && typeof callback !== "function") { + if (! (callback instanceof Function)) { callback = new Function(callback); } diff --git a/jdk/src/share/sample/scripting/scriptpad/src/resources/mm.js b/jdk/src/share/sample/scripting/scriptpad/src/resources/mm.js index 2b75f243bfc..07efad27801 100644 --- a/jdk/src/share/sample/scripting/scriptpad/src/resources/mm.js +++ b/jdk/src/share/sample/scripting/scriptpad/src/resources/mm.js @@ -159,22 +159,12 @@ queryMBeans.docString = "return MBeans using given ObjectName and optional query // wraps a script array as java.lang.Object[] function objectArray(array) { - var len = array.length; - var res = java.lang.reflect.Array.newInstance(java.lang.Object, len); - for (var i = 0; i < array.length; i++) { - res[i] = array[i]; - } - return res; + return Java.to(array, "java.lang.Object[]"); } // wraps a script (string) array as java.lang.String[] function stringArray(array) { - var len = array.length; - var res = java.lang.reflect.Array.newInstance(java.lang.String, len); - for (var i = 0; i < array.length; i++) { - res[i] = String(array[i]); - } - return res; + return Java.to(array, "java.lang.String[]"); } // script array to Java List @@ -284,26 +274,35 @@ function mbean(objName, async) { __get__: function (name) { if (isAttribute(name)) { if (async) { - return getMBeanAttribute.future(objName, name); + return getMBeanAttribute.future(objName, name); } else { - return getMBeanAttribute(objName, name); + return getMBeanAttribute(objName, name); } - } else if (isOperation(name)) { + } else { + return undefined; + } + }, + __call__: function(name) { + if (isOperation(name)) { var oper = operMap[name]; - return function() { - var params = objectArray(arguments); - var sigs = oper.signature; - var sigNames = new Array(sigs.length); - for (var index in sigs) { - sigNames[index] = sigs[index].getType(); - } - if (async) { - return invokeMBean.future(objName, name, - params, sigNames); - } else { - return invokeMBean(objName, name, params, sigNames); - } - }; + + var params = []; + for (var j = 1; j < arguments.length; j++) { + params[j-1]= arguments[j]; + } + + var sigs = oper.signature; + + var sigNames = new Array(sigs.length); + for (var index in sigs) { + sigNames[index] = sigs[index].getType(); + } + + if (async) { + return invokeMBean.future(objName, name, params, sigNames); + } else { + return invokeMBean(objName, name, params, sigNames); + } } else { return undefined; } From c05c2330cf5f27f660fc3677d0deefb73267f70a Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Mon, 5 Aug 2013 19:12:33 -0700 Subject: [PATCH 17/39] 8020854: change RMI javadocs to specify that remote objects are exported to the wildcard address Reviewed-by: rgallard, alanb --- .../java/rmi/server/RMISocketFactory.java | 40 +++++++++++++++++-- .../java/rmi/server/UnicastRemoteObject.java | 22 +++++++++- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java b/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java index ccff225c87d..e7b7581820b 100644 --- a/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java +++ b/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -33,15 +33,47 @@ import java.net.*; * in order to obtain client and server sockets for RMI calls. An * application may use the setSocketFactory method to * request that the RMI runtime use its socket factory instance - * instead of the default implementation.

    + * instead of the default implementation. * - * The default socket factory implementation used goes through a + *

    The default socket factory implementation performs a * three-tiered approach to creating client sockets. First, a direct * socket connection to the remote VM is attempted. If that fails * (due to a firewall), the runtime uses HTTP with the explicit port * number of the server. If the firewall does not allow this type of * communication, then HTTP to a cgi-bin script on the server is used - * to POST the RMI call.

    + * to POST the RMI call. + * + *

    The default socket factory implementation creates server sockets that + * are bound to the wildcard address, which accepts requests from all network + * interfaces. + * + * @implNote + *

    You can use the {@code RMISocketFactory} class to create a server socket that + * is bound to a specific address, restricting the origin of requests. For example, + * the following code implements a socket factory that binds server sockets to the + * loopback address. This restricts RMI to processing requests only from the local host. + * + *

    {@code
    + *     class LoopbackSocketFactory extends RMISocketFactory {
    + *         public ServerSocket createServerSocket(int port) throws IOException {
    + *             return new ServerSocket(port, 5, InetAddress.getLoopbackAddress());
    + *         }
    + *
    + *         public Socket createSocket(String host, int port) throws IOException {
    + *             // just call the default client socket factory
    + *             return RMISocketFactory.getDefaultSocketFactory()
    + *                                    .createSocket(host, port);
    + *         }
    + *     }
    + *
    + *     // ...
    + *
    + *     RMISocketFactory.setSocketFactory(new LoopbackSocketFactory());
    + * }
    + * + * Set the {@code java.rmi.server.hostname} system property + * to a host name (typically {@code localhost}) that resolves to the loopback + * interface to ensure that the generated stubs use the right network interface. * * @author Ann Wollrath * @author Peter Jones diff --git a/jdk/src/share/classes/java/rmi/server/UnicastRemoteObject.java b/jdk/src/share/classes/java/rmi/server/UnicastRemoteObject.java index 7764627bceb..be86c275246 100644 --- a/jdk/src/share/classes/java/rmi/server/UnicastRemoteObject.java +++ b/jdk/src/share/classes/java/rmi/server/UnicastRemoteObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -100,6 +100,26 @@ import sun.rmi.server.UnicastServerRef2; * * * + *

    If an object is exported with the + * {@link #exportObject(Remote) exportObject(Remote)} + * or + * {@link #exportObject(Remote, int) exportObject(Remote, port)} + * methods, or if a subclass constructor invokes one of the + * {@link #UnicastRemoteObject()} + * or + * {@link #UnicastRemoteObject(int) UnicastRemoteObject(port)} + * constructors, the object is exported with a server socket created using the + * {@link RMISocketFactory} + * class. + * + * @implNote + *

    By default, server sockets created by the {@link RMISocketFactory} class + * listen on all network interfaces. See the + * {@link RMISocketFactory} class and the section + * RMI Socket Factories + * in the + * Java RMI Specification. + * * @author Ann Wollrath * @author Peter Jones * @since JDK1.1 From b65847a20663e72b88bb81c3e8da858b30858b9b Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Tue, 6 Aug 2013 14:04:49 +0400 Subject: [PATCH 18/39] 8011038: sourceObj validation during desereliazation of RelationNotification should be relaxed SourceObj could be set to null by setSource() relax a validation of deserialized object. Reviewed-by: sjiang, skoivu, dfuchs --- .../relation/RelationNotification.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/javax/management/relation/RelationNotification.java b/jdk/src/share/classes/javax/management/relation/RelationNotification.java index a05aa719b1b..7edbc895ac2 100644 --- a/jdk/src/share/classes/javax/management/relation/RelationNotification.java +++ b/jdk/src/share/classes/javax/management/relation/RelationNotification.java @@ -260,7 +260,7 @@ public class RelationNotification extends Notification { super(notifType, sourceObj, sequence, timeStamp, message); - if (!isValidBasic(notifType,sourceObj,id,typeName) || !isValidCreate(notifType)) { + if (!isValidBasicStrict(notifType,sourceObj,id,typeName) || !isValidCreate(notifType)) { throw new IllegalArgumentException("Invalid parameter."); } @@ -310,7 +310,7 @@ public class RelationNotification extends Notification { super(notifType, sourceObj, sequence, timeStamp, message); - if (!isValidBasic(notifType,sourceObj,id,typeName) || !isValidUpdate(notifType,name,newValue,oldValue)) { + if (!isValidBasicStrict(notifType,sourceObj,id,typeName) || !isValidUpdate(notifType,name,newValue,oldValue)) { throw new IllegalArgumentException("Invalid parameter."); } @@ -457,14 +457,26 @@ public class RelationNotification extends Notification { // - no role old value (for role update) // - no role new value (for role update) + // Despite the fact, that validation in constructor of RelationNotification prohibit + // creation of the class instance with null sourceObj its possible to set it to null later + // by public setSource() method. + // So we should relax validation rules to preserve serialization behavior compatibility. + + private boolean isValidBasicStrict(String notifType, Object sourceObj, String id, String typeName){ + if (sourceObj == null) { + return false; + } + return isValidBasic(notifType,sourceObj,id,typeName); + } + private boolean isValidBasic(String notifType, Object sourceObj, String id, String typeName){ - if (notifType == null || sourceObj == null || - id == null || typeName == null) { + if (notifType == null || id == null || typeName == null) { return false; } - if (!(sourceObj instanceof RelationService) && - !(sourceObj instanceof ObjectName)) { + if (sourceObj != null && ( + !(sourceObj instanceof RelationService) && + !(sourceObj instanceof ObjectName))) { return false; } From 04449cd1a910973c5e5d8656fe4bc29a0d9fdf29 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 6 Aug 2013 15:35:20 +0100 Subject: [PATCH 19/39] 8022344: Additional debug info for test/java/net/NetworkInterface/IndexTest.java Reviewed-by: michaelm, alanb --- .../java/net/NetworkInterface/IndexTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/jdk/test/java/net/NetworkInterface/IndexTest.java b/jdk/test/java/net/NetworkInterface/IndexTest.java index f52c56ac788..4d5a0150be9 100644 --- a/jdk/test/java/net/NetworkInterface/IndexTest.java +++ b/jdk/test/java/net/NetworkInterface/IndexTest.java @@ -27,7 +27,10 @@ */ import java.net.*; +import java.util.Arrays; +import java.util.Collections; import java.util.Enumeration; +import static java.lang.System.out; public class IndexTest { public static void main(String[] args) throws Exception { @@ -39,12 +42,17 @@ public class IndexTest { if (index >= 0) { NetworkInterface nif2 = NetworkInterface.getByIndex(index); if (! nif.equals(nif2)) { + out.printf("%nExpected interfaces to be the same, but got:%n"); + displayInterfaceInformation(nif); + displayInterfaceInformation(nif2); throw new RuntimeException("both interfaces should be equal"); } } } try { nif = NetworkInterface.getByIndex(-1); + out.printf("%ngetByIndex(-1) should have thrown, but instead returned:%n"); + displayInterfaceInformation(nif); throw new RuntimeException("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException e) { // OK @@ -52,7 +60,29 @@ public class IndexTest { // In all likelyhood, this interface should not exist. nif = NetworkInterface.getByIndex(Integer.MAX_VALUE - 1); if (nif != null) { + out.printf("%ngetByIndex(MAX_VALUE - 1), expected null, got:%n"); + displayInterfaceInformation(nif); throw new RuntimeException("getByIndex() should have returned null"); } } + + static void displayInterfaceInformation(NetworkInterface netint) throws SocketException { + out.printf("Display name: %s%n", netint.getDisplayName()); + out.printf("Name: %s%n", netint.getName()); + Enumeration inetAddresses = netint.getInetAddresses(); + + for (InetAddress inetAddress : Collections.list(inetAddresses)) + out.printf("InetAddress: %s%n", inetAddress); + + out.printf("Up? %s%n", netint.isUp()); + out.printf("Loopback? %s%n", netint.isLoopback()); + out.printf("PointToPoint? %s%n", netint.isPointToPoint()); + out.printf("Supports multicast? %s%n", netint.supportsMulticast()); + out.printf("Virtual? %s%n", netint.isVirtual()); + out.printf("Hardware address: %s%n", + Arrays.toString(netint.getHardwareAddress())); + out.printf("MTU: %s%n", netint.getMTU()); + out.printf("Index: %s%n", netint.getIndex()); + out.printf("%n"); + } } From 78255f5c55ead4e04878b066da3befb1a68582c9 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Tue, 6 Aug 2013 08:31:24 -0700 Subject: [PATCH 20/39] 8022120: JCK test api/javax_xml/crypto/dsig/TransformService/index_ParamMethods fails TransformService.init and marshalParams must throw NullPointerException when parent parameter is null Reviewed-by: xuelei --- .../internal/dom/ApacheCanonicalizer.java | 10 ++- .../dsig/internal/dom/ApacheTransform.java | 10 ++- .../dsig/TransformService/NullParent.java | 63 +++++++++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 jdk/test/javax/xml/crypto/dsig/TransformService/NullParent.java diff --git a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java index 97554e4d200..ec6e9c6b722 100644 --- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java +++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java @@ -75,7 +75,10 @@ public abstract class ApacheCanonicalizer extends TransformService { throw new ClassCastException ("context must be of type DOMCryptoContext"); } - if (parent == null || !(parent instanceof javax.xml.crypto.dom.DOMStructure)) { + if (parent == null) { + throw new NullPointerException(); + } + if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) { throw new ClassCastException("parent must be of type DOMStructure"); } transformElem = (Element) @@ -90,7 +93,10 @@ public abstract class ApacheCanonicalizer extends TransformService { throw new ClassCastException ("context must be of type DOMCryptoContext"); } - if (parent == null || !(parent instanceof javax.xml.crypto.dom.DOMStructure)) { + if (parent == null) { + throw new NullPointerException(); + } + if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) { throw new ClassCastException("parent must be of type DOMStructure"); } transformElem = (Element) diff --git a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java index 7df11e6204a..aac051804b0 100644 --- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java +++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java @@ -76,7 +76,10 @@ public abstract class ApacheTransform extends TransformService { throw new ClassCastException ("context must be of type DOMCryptoContext"); } - if (parent == null || !(parent instanceof javax.xml.crypto.dom.DOMStructure)) { + if (parent == null) { + throw new NullPointerException(); + } + if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) { throw new ClassCastException("parent must be of type DOMStructure"); } transformElem = (Element) @@ -91,7 +94,10 @@ public abstract class ApacheTransform extends TransformService { throw new ClassCastException ("context must be of type DOMCryptoContext"); } - if (parent == null || !(parent instanceof javax.xml.crypto.dom.DOMStructure)) { + if (parent == null) { + throw new NullPointerException(); + } + if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) { throw new ClassCastException("parent must be of type DOMStructure"); } transformElem = (Element) diff --git a/jdk/test/javax/xml/crypto/dsig/TransformService/NullParent.java b/jdk/test/javax/xml/crypto/dsig/TransformService/NullParent.java new file mode 100644 index 00000000000..79c03174d20 --- /dev/null +++ b/jdk/test/javax/xml/crypto/dsig/TransformService/NullParent.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013, 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. + */ + +/** + * @test + * @bug 8022120 + * @summary check that the init and marshalParams methods throw + * NullPointerException when the parent parameter is null + */ + +import javax.xml.crypto.dsig.CanonicalizationMethod; +import javax.xml.crypto.dsig.Transform; +import javax.xml.crypto.dsig.TransformService; + +public class NullParent { + + public static void main(String[] args) throws Exception { + String[] transforms = new String[] + { Transform.BASE64, Transform.ENVELOPED, Transform.XPATH, + Transform.XPATH2, Transform.XSLT, + CanonicalizationMethod.EXCLUSIVE, + CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS, + CanonicalizationMethod.INCLUSIVE, + CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS }; + + for (String transform : transforms) { + System.out.println("Testing " + transform); + TransformService ts = TransformService.getInstance(transform, + "DOM"); + try { + ts.init(null, null); + throw new Exception("init must throw NullPointerException " + + "when the parent parameter is null"); + } catch (NullPointerException npe) { } + try { + ts.marshalParams(null, null); + throw new Exception("marshalParams must throw " + + "NullPointerException when the parent " + + "parameter is null"); + } catch (NullPointerException npe) { } + } + } +} From 0f4a06a92a7a2605e9fc55ad17aa54c927b82279 Mon Sep 17 00:00:00 2001 From: Amy Lu Date: Tue, 6 Aug 2013 18:54:02 +0200 Subject: [PATCH 21/39] 7184826: (reflect) Add support for Project Lambda concepts in core reflection Reviewed-by: darcy, jfranck --- .../DefaultStaticInvokeTest.java | 307 ++++++++++++++ .../DefaultStaticTestData.java | 401 ++++++++++++++++++ .../DefaultStaticTest/helper/Declared.java | 35 ++ .../reflect/DefaultStaticTest/helper/Mod.java | 37 ++ .../reflect/Method/DefaultMethodModeling.java | 31 +- .../lang/reflect/Method/IsDefaultTest.java | 66 +++ 6 files changed, 876 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java create mode 100644 jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java create mode 100644 jdk/test/java/lang/reflect/DefaultStaticTest/helper/Declared.java create mode 100644 jdk/test/java/lang/reflect/DefaultStaticTest/helper/Mod.java diff --git a/jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java b/jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java new file mode 100644 index 00000000000..28d49be6896 --- /dev/null +++ b/jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @summary Test locating and invoking default/static method that defined + * in interfaces and/or in inheritance + * @bug 7184826 + * @build helper.Mod helper.Declared DefaultStaticTestData + * @run testng DefaultStaticInvokeTest + * @author Yong Lu + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import org.testng.annotations.Test; + +import static helper.Mod.*; +import static helper.Declared.*; +import helper.Mod; + +public class DefaultStaticInvokeTest { + + @Test(dataProvider = "testCasesAll", + dataProviderClass = DefaultStaticTestData.class) + public void testGetMethods(String testTarget, Object param) + throws Exception { + // test the methods retrieved by getMethods() + testMethods(ALL_METHODS, testTarget, param); + } + + @Test(dataProvider = "testCasesAll", + dataProviderClass = DefaultStaticTestData.class) + public void testGetDeclaredMethods(String testTarget, Object param) + throws Exception { + // test the methods retrieved by getDeclaredMethods() + testMethods(DECLARED_ONLY, testTarget, param); + } + + @Test(dataProvider = "testCasesAll", + dataProviderClass = DefaultStaticTestData.class) + public void testMethodInvoke(String testTarget, Object param) + throws Exception { + Class typeUnderTest = Class.forName(testTarget); + MethodDesc[] expectedMethods = typeUnderTest.getAnnotationsByType(MethodDesc.class); + + // test the method retrieved by Class.getMethod(String, Object[]) + for (MethodDesc toTest : expectedMethods) { + String name = toTest.name(); + Method m = getTestMethod(typeUnderTest, name, param); + testThisMethod(toTest, m, typeUnderTest, param); + } + } + + @Test(dataProvider = "testCasesAll", + dataProviderClass = DefaultStaticTestData.class) + public void testMethodHandleInvoke(String testTarget, Object param) + throws Throwable { + Class typeUnderTest = Class.forName(testTarget); + MethodDesc[] expectedMethods = typeUnderTest.getAnnotationsByType(MethodDesc.class); + + for (MethodDesc toTest : expectedMethods) { + String mName = toTest.name(); + Mod mod = toTest.mod(); + if (mod != STATIC && typeUnderTest.isInterface()) { + return; + } + + String result = null; + String expectedReturn = toTest.retval(); + + MethodHandle methodHandle = getTestMH(typeUnderTest, mName, param); + if (mName.equals("staticMethod")) { + result = (param == null) + ? (String) methodHandle.invoke() + : (String) methodHandle.invoke(param); + } else { + result = (param == null) + ? (String) methodHandle.invoke(typeUnderTest.newInstance()) + : (String) methodHandle.invoke(typeUnderTest.newInstance(), param); + } + + assertEquals(result, expectedReturn); + } + + } + + @Test(dataProvider = "testClasses", + dataProviderClass = DefaultStaticTestData.class) + public void testIAE(String testTarget, Object param) + throws ClassNotFoundException { + + Class typeUnderTest = Class.forName(testTarget); + MethodDesc[] expectedMethods = typeUnderTest.getAnnotationsByType(MethodDesc.class); + + for (MethodDesc toTest : expectedMethods) { + String mName = toTest.name(); + Mod mod = toTest.mod(); + if (mod != STATIC && typeUnderTest.isInterface()) { + return; + } + Exception caught = null; + try { + getTestMH(typeUnderTest, mName, param, true); + } catch (Exception e) { + caught = e; + } + assertTrue(caught != null); + assertEquals(caught.getClass(), IllegalAccessException.class); + } + } + private static final String[] OBJECT_METHOD_NAMES = { + "equals", + "hashCode", + "getClass", + "notify", + "notifyAll", + "toString", + "wait", + "wait", + "wait",}; + private static final String LAMBDA_METHOD_NAMES = "lambda$"; + private static final HashSet OBJECT_NAMES = new HashSet<>(Arrays.asList(OBJECT_METHOD_NAMES)); + private static final boolean DECLARED_ONLY = true; + private static final boolean ALL_METHODS = false; + + private void testMethods(boolean declaredOnly, String testTarget, Object param) + throws Exception { + Class typeUnderTest = Class.forName(testTarget); + Method[] methods = declaredOnly + ? typeUnderTest.getDeclaredMethods() + : typeUnderTest.getMethods(); + + MethodDesc[] baseExpectedMethods = typeUnderTest.getAnnotationsByType(MethodDesc.class); + MethodDesc[] expectedMethods; + + // If only declared filter out non-declared from expected result + if (declaredOnly) { + int nonDeclared = 0; + for (MethodDesc desc : baseExpectedMethods) { + if (desc.declared() == NO) { + nonDeclared++; + } + } + expectedMethods = new MethodDesc[baseExpectedMethods.length - nonDeclared]; + int i = 0; + for (MethodDesc desc : baseExpectedMethods) { + if (desc.declared() == YES) { + expectedMethods[i++] = desc; + } + } + } else { + expectedMethods = baseExpectedMethods; + } + + HashMap myMethods = new HashMap<>(methods.length); + for (Method m : methods) { + String mName = m.getName(); + // don't add Object methods and method created from lambda expression + if ((!OBJECT_NAMES.contains(mName)) && (!mName.contains(LAMBDA_METHOD_NAMES))) { + myMethods.put(mName, m); + } + } + assertEquals(expectedMethods.length, myMethods.size()); + + for (MethodDesc toTest : expectedMethods) { + + String name = toTest.name(); + Method candidate = myMethods.get(name); + + assertNotNull(candidate); + myMethods.remove(name); + + testThisMethod(toTest, candidate, typeUnderTest, param); + + } + + // Should be no methods left since we remove all we expect to see + assertTrue(myMethods.isEmpty()); + } + + private void testThisMethod(MethodDesc toTest, Method method, + Class typeUnderTest, Object param) throws Exception { + // Test modifiers, and invoke + Mod mod = toTest.mod(); + String expectedReturn = toTest.retval(); + switch (mod) { + case STATIC: + //assert candidate is static + assertTrue(Modifier.isStatic(method.getModifiers())); + assertFalse(method.isDefault()); + + // Test invoke it + assertEquals(tryInvoke(method, null, param), expectedReturn); + break; + case DEFAULT: + // if typeUnderTest is a class then instantiate and invoke + if (!typeUnderTest.isInterface()) { + assertEquals(tryInvoke( + method, + typeUnderTest, + param), + expectedReturn); + } + + //assert candidate is default + assertFalse(Modifier.isStatic(method.getModifiers())); + assertTrue(method.isDefault()); + break; + case REGULAR: + // if typeUnderTest must be a class + assertEquals(tryInvoke( + method, + typeUnderTest, + param), + expectedReturn); + + //assert candidate is neither default nor static + assertFalse(Modifier.isStatic(method.getModifiers())); + assertFalse(method.isDefault()); + break; + case ABSTRACT: + //assert candidate is neither default nor static + assertFalse(Modifier.isStatic(method.getModifiers())); + assertFalse(method.isDefault()); + break; + default: + assertFalse(true); //this should never happen + break; + } + + } + + private Object tryInvoke(Method m, Class receiverType, Object param) + throws Exception { + Object receiver = receiverType == null ? null : receiverType.newInstance(); + Object result = null; + if (param == null) { + result = m.invoke(receiver); + } else { + result = m.invoke(receiver, param); + } + return result; + } + + private Method getTestMethod(Class clazz, String methodName, Object param) + throws NoSuchMethodException { + Class[] paramsType = (param != null) + ? new Class[]{Object.class} + : new Class[]{}; + return clazz.getMethod(methodName, paramsType); + } + + private MethodHandle getTestMH(Class clazz, String methodName, Object param) + throws Exception { + return getTestMH(clazz, methodName, param, false); + } + + private MethodHandle getTestMH(Class clazz, String methodName, + Object param, boolean isNegativeTest) + throws Exception { + MethodType mType = (param != null) + ? MethodType.genericMethodType(1) + : MethodType.methodType(String.class); + MethodHandles.Lookup lookup = MethodHandles.lookup(); + if (!isNegativeTest) { + return methodName.equals("staticMethod") + ? lookup.findStatic(clazz, methodName, mType) + : lookup.findVirtual(clazz, methodName, mType); + } else { + return methodName.equals("staticMethod") + ? lookup.findVirtual(clazz, methodName, mType) + : lookup.findStatic(clazz, methodName, mType); + } + } +} diff --git a/jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java b/jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java new file mode 100644 index 00000000000..ef9dec71616 --- /dev/null +++ b/jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * Test Data used for testing default/static method + * + * @author Yong Lu + */ + +import java.util.Arrays; +import java.util.List; + +import org.testng.annotations.DataProvider; +import org.testng.collections.Lists; + +import static helper.Mod.*; +import static helper.Declared.*; +import helper.Mod; +import helper.Declared; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = YES) +interface TestIF1 { + + default String defaultMethod() { + return "TestIF1.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass1 implements TestIF1 { +} + +@MethodDesc(name = "staticMethod", retval = "TestIF2.staticMethod", mod = STATIC, declared = YES) +interface TestIF2 { + + static String staticMethod() { + return "TestIF2.staticMethod"; + } +} + +@MethodDesc(name = "method", retval = "TestIF2.staticMethod", mod = REGULAR, declared = YES) +class TestClass2 implements TestIF2 { + + public String method() { + return TestIF2.staticMethod(); + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF3.defaultMethod", mod = DEFAULT, declared = YES) +@MethodDesc(name = "method", retval = "", mod = ABSTRACT, declared = YES) +interface TestIF3 { + + String method(); + + default String defaultMethod() { + return "TestIF3.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF3.defaultMethod", mod = DEFAULT, declared = NO) +@MethodDesc(name = "method", retval = "TestClass3.method", mod = REGULAR, declared = YES) +class TestClass3 implements TestIF3 { + + public String method() { + return "TestClass3.method"; + } +} + +@MethodDesc(name = "staticMethod", retval = "TestIF4.staticMethod", mod = STATIC, declared = YES) +@MethodDesc(name = "method", retval = "", mod = ABSTRACT, declared = YES) +interface TestIF4 { + + String method(); + + static String staticMethod() { + return "TestIF4.staticMethod"; + } +} + +@MethodDesc(name = "method", retval = "TestClass4.method", mod = REGULAR, declared = YES) +class TestClass4 implements TestIF4 { + + public String method() { + return "TestClass4.method"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF5.defaultMethod", mod = DEFAULT, declared = YES) +@MethodDesc(name = "staticMethod", retval = "TestIF5.staticMethod", mod = STATIC, declared = YES) +interface TestIF5 { + + default String defaultMethod() { + return "TestIF5.defaultMethod"; + } + + static String staticMethod() { + return "TestIF5.staticMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF5.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass5 implements TestIF5 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF6.defaultMethod", mod = DEFAULT, declared = YES) +@MethodDesc(name = "staticMethod", retval = "TestIF6.staticMethod", mod = STATIC, declared = YES) +@MethodDesc(name = "method", retval = "", mod = ABSTRACT, declared = YES) +interface TestIF6 { + + String method(); + + default String defaultMethod() { + return "TestIF6.defaultMethod"; + } + + static String staticMethod() { + return "TestIF6.staticMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF6.defaultMethod", mod = DEFAULT, declared = NO) +@MethodDesc(name = "method", retval = "TestClass6.method", mod = REGULAR, declared = YES) +class TestClass6 implements TestIF6 { + + public String method() { + return "TestClass6.method"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF7.TestClass7", mod = DEFAULT, declared = YES) +interface TestIF7 { + + default T defaultMethod(T t) { + return t; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF7.TestClass7", mod = DEFAULT, declared = NO) +class TestClass7 implements TestIF7 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF8.TestClass8", mod = DEFAULT, declared = YES) +interface TestIF8 { + + default E defaultMethod(E e) { + return e; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF8.TestClass8", mod = DEFAULT, declared = NO) +class TestClass8 implements TestIF8 { +}; + +@MethodDesc(name = "defaultMethod", retval = "TestIF9.defaultMethod", mod = DEFAULT, declared = YES) +interface TestIF9 extends TestIF1 { + + default String defaultMethod() { + return "TestIF9.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF9.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass9 implements TestIF9 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF9.defaultMethod", mod = DEFAULT, declared = NO) +@MethodDesc(name = "method", retval = "TestIF9.defaultMethod", mod = REGULAR, declared = YES) +class TestClass91 implements TestIF9, TestIF1 { + + public String method() { + return defaultMethod(); + } +} + +@MethodDesc(name = "staticMethod", retval = "TestIF10.staticMethod", mod = STATIC, declared = YES) +interface TestIF10 extends TestIF2 { + + static String staticMethod() { + + return "TestIF10.staticMethod"; + } +} + +@MethodDesc(name = "staticMethod", retval = "TestIF11.staticMethod", mod = STATIC, declared = YES) +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +interface TestIF11 extends TestIF1 { + + static String staticMethod() { + return "TestIF11.staticMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass11 implements TestIF11 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF12.defaultMethod", mod = DEFAULT, declared = YES) +@MethodDesc(name = "staticMethod", retval = "TestIF2.staticMethod", mod = STATIC, declared = NO) +interface TestIF12 extends TestIF2 { + + default String defaultMethod() { + return "TestIF12.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF12.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass12 implements TestIF12 { +} + +//Diamond Case +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +interface TestIF1A extends TestIF1 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +interface TestIF1B extends TestIF1 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass13 implements TestIF1A, TestIF1B { +} + +//Diamond Override Case +@MethodDesc(name = "defaultMethod", retval = "TestIF1C.defaultMethod", mod = DEFAULT, declared = YES) +interface TestIF1C extends TestIF1 { + + default String defaultMethod() { + return "TestIF1C.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF1D.defaultMethod", mod = DEFAULT, declared = YES) +interface TestIF1D extends TestIF1 { + + default String defaultMethod() { + return "TestIF1D.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestClass14.defaultMethod", mod = REGULAR, declared = YES) +class TestClass14 implements TestIF1C, TestIF1D { + + public String defaultMethod() { + return "TestClass14.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "", mod = ABSTRACT, declared = YES) +interface TestIF15 extends TestIF1 { + + String defaultMethod(); +} + +@MethodDesc(name = "defaultMethod", retval = "TestClass15.defaultMethod", mod = REGULAR, declared = YES) +class TestClass15 implements TestIF15 { + + public String defaultMethod() { + return "TestClass15.defaultMethod"; + } +} + +interface FuncInterface { + + String test(T t); +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF16.defaultMethod", mod = DEFAULT, declared = YES) +interface TestIF16 { + + default String defaultMethod() { + FuncInterface fi = o -> o.toString(); + Object o = "TestIF16.defaultMethod"; + return fi.test(o); + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF16.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass16 implements TestIF16 { +}; + +@MethodDesc(name = "defaultMethod", retval = "TestIF17.defaultMethod", mod = DEFAULT, declared = YES) +@MethodDesc(name = "staticMethod", retval = "TestIF17.staticMethod", mod = STATIC, declared = YES) +interface TestIF17 { + + default String defaultMethod() { + return staticMethod().replace("staticMethod", "defaultMethod"); + } + + public static String staticMethod() { + return "TestIF17.staticMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF17.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass17 implements TestIF17 { +} + +@Retention(RetentionPolicy.RUNTIME) +@Repeatable(MethodDescs.class) +@interface MethodDesc { + String name(); + String retval(); + Mod mod(); + Declared declared(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface MethodDescs { + MethodDesc[] value(); +} + +public class DefaultStaticTestData { + + /** + * Test data for DefaultStaticInvokeTest The format of inner array is: First + * data is the name of the class under test Second data used in test as the + * arguments used for the method call. + */ + @DataProvider + static Object[][] testClasses() { + return new Object[][]{ + {"TestClass1", null}, + //{"TestClass2", null}, @ignore due to JDK-8009411 + {"TestClass3", null}, + //{"TestClass4", null}, @ignore due to JDK-8009411 + //{"TestClass5", null}, @ignore due to JDK-8009411 + //{"TestClass6", null}, @ignore due to JDK-8009411 + {"TestClass7", "TestIF7.TestClass7"}, + {"TestClass8", "TestIF8.TestClass8"}, + {"TestClass9", null}, + {"TestClass91", null}, + //{"TestClass11", null}, @ignore due to JDK-8009411 + //{"TestClass12", null}, @ignore due to JDK-8009411 + {"TestClass13", null}, + {"TestClass14", null}, + {"TestClass15", null}, + {"TestClass16", null} + //{"TestClass17", null} @ignore due to JDK-8009411 + }; + } + + /** + * Test data for DefaultStaticInvokeTest The format of inner array is: First + * data is the name of the interface under test Second data used in test as + * the arguments used for the method call. + */ + @DataProvider + static Object[][] testInterfaces() { + return new Object[][]{ + {"TestIF1", null}, + {"TestIF2", null}, + {"TestIF3", null}, + {"TestIF4", null}, + {"TestIF5", null}, + {"TestIF6", null}, + {"TestIF7", "TestIF7.TestClass7"}, + {"TestIF8", "TestIF8.TestClass8"}, + {"TestIF9", null}, + {"TestIF10", null}, + {"TestIF11", null}, + {"TestIF12", null}, + {"TestIF1A", null}, + {"TestIF1B", null}, + {"TestIF1C", null}, + {"TestIF1D", null}, + {"TestIF15", null}, + {"TestIF16", null}, + {"TestIF17", null},}; + } + + @DataProvider + static Object[][] testCasesAll() { + List result = Lists.newArrayList(); + result.addAll(Arrays.asList(testClasses())); + result.addAll(Arrays.asList(testInterfaces())); + return result.toArray(new Object[result.size()][]); + } +} diff --git a/jdk/test/java/lang/reflect/DefaultStaticTest/helper/Declared.java b/jdk/test/java/lang/reflect/DefaultStaticTest/helper/Declared.java new file mode 100644 index 00000000000..1e10b85da9b --- /dev/null +++ b/jdk/test/java/lang/reflect/DefaultStaticTest/helper/Declared.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * Helper class used for testing default/static method + * + * @author Yong Lu + */ + +package helper; + +public enum Declared { + YES, + NO +} diff --git a/jdk/test/java/lang/reflect/DefaultStaticTest/helper/Mod.java b/jdk/test/java/lang/reflect/DefaultStaticTest/helper/Mod.java new file mode 100644 index 00000000000..ed1451cd9ba --- /dev/null +++ b/jdk/test/java/lang/reflect/DefaultStaticTest/helper/Mod.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * Helper class used for testing default/static method + * + * @author Yong Lu + */ + +package helper; + +public enum Mod { + DEFAULT, + STATIC, + REGULAR, + ABSTRACT +} diff --git a/jdk/test/java/lang/reflect/Method/DefaultMethodModeling.java b/jdk/test/java/lang/reflect/Method/DefaultMethodModeling.java index 99ecd24b221..83a3d0bd546 100644 --- a/jdk/test/java/lang/reflect/Method/DefaultMethodModeling.java +++ b/jdk/test/java/lang/reflect/Method/DefaultMethodModeling.java @@ -43,7 +43,7 @@ public class DefaultMethodModeling { SuperIwithDefault.class, SuperIwithDefaultChild.class, Base.class, Combo1.class, Combo2.class, SonSuperIwithDefault.class, DaughterSuperIwithDefault.class, GrandchildSuperIwithDefault.class, D.class, - B.class, C.class + B.class, C.class, B1.class, D1.class }; for(Class clazz : classes) { @@ -202,6 +202,17 @@ class D implements GrandchildSuperIwithDefault { public void quux(){} } +class D1 implements SonSuperIwithDefault, DaughterSuperIwithDefault { + @ExpectedModel(declaringClass=D1.class) + public void foo(){} + + @ExpectedModel(declaringClass=D1.class) + public void baz(){} + + @ExpectedModel(declaringClass=D1.class) + public void quux(){} +} + // -=-=-=- // What does re-abstraction look like? @@ -222,3 +233,21 @@ class C extends B implements SuperIwithDefault { @ExpectedModel(declaringClass=C.class) public void bar(){} } + +abstract class A1 implements SonSuperIwithDefault { + @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=A1.class) + public abstract void baz(); + + @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=A1.class) + public abstract void foo(); +} + +class B1 extends A1 { + @ExpectedModel(declaringClass=B1.class) + @Override + public void foo(){;} + + @ExpectedModel(declaringClass=B1.class) + @Override + public void baz(){} +} diff --git a/jdk/test/java/lang/reflect/Method/IsDefaultTest.java b/jdk/test/java/lang/reflect/Method/IsDefaultTest.java index 1dd67aeb874..97967ee4fe4 100644 --- a/jdk/test/java/lang/reflect/Method/IsDefaultTest.java +++ b/jdk/test/java/lang/reflect/Method/IsDefaultTest.java @@ -42,6 +42,12 @@ public class IsDefaultTest { classList.add(TestType2.class); classList.add(TestType3.class); classList.add(TestType4.class); + classList.add(TestType2.nestedTestType2.class); + classList.add(TestType5.class); + classList.add(TestType5.nestedTestType5.class); + classList.add(TestType6.class); + classList.add(TestType6.nestedTestType6.class); + classList.add(TestType7.class); for(Class clazz: classList) { for(Method method: clazz.getDeclaredMethods()) { @@ -78,11 +84,22 @@ interface TestType1 { @ExpectedIsDefault(true) default void bar() {}; // Default method + + @ExpectedIsDefault(true) + default void bar(int i) {}; // Default method + + @ExpectedIsDefault(true) + default void bar(String i) {}; // Default method } class TestType2 { @ExpectedIsDefault(false) void bar() {}; + + interface nestedTestType2 { + @ExpectedIsDefault(true) + default void nestedBar() {}; + } } class TestType3 implements TestType1 { @@ -92,6 +109,10 @@ class TestType3 implements TestType1 { @ExpectedIsDefault(false) @Override public void bar() {}; + + @ExpectedIsDefault(false) + @Override + public void bar(int i) {}; } @interface TestType4 { @@ -102,6 +123,51 @@ class TestType3 implements TestType1 { String anotherValue() default ""; } +interface TestType5 { + @ExpectedIsDefault(false) + abstract void aFoo(); + + @ExpectedIsDefault(false) + static void sFoo() {}; + + @ExpectedIsDefault(true) + public default void pBar() {}; + + @ExpectedIsDefault(true) + public default String sBar() {return "";}; + + interface nestedTestType5{ + @ExpectedIsDefault(false) + void nestedFoo(); + + @ExpectedIsDefault(true) + default void nestedBar() {}; + } +} + +class TestType6{ + interface nestedTestType6 { + @ExpectedIsDefault(true) + default void nestedBar() {}; + + @ExpectedIsDefault(false) + void nestedFoo(); + } + + @ExpectedIsDefault(false) + void foo(nestedTestType6 n) {} +} + +class TestType7 implements TestType6.nestedTestType6 { + + @ExpectedIsDefault(false) + public void nestedFoo() {} + + @ExpectedIsDefault(false) + @Override + public void nestedBar() {}; +} + @Retention(RetentionPolicy.RUNTIME) @interface ExpectedIsDefault { boolean value(); From ae54a3c9653c397c0e3a5a9ddbdd9cd9769c67d0 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 6 Aug 2013 13:25:04 -0700 Subject: [PATCH 22/39] 8022174: Fix doclint warnings in javax.sound 8022404: Fix doclint issues in java.applet Reviewed-by: prr --- jdk/src/share/classes/java/applet/AppletContext.java | 6 +++--- .../share/classes/javax/sound/midi/MetaMessage.java | 2 +- .../share/classes/javax/sound/midi/MidiDevice.java | 6 +++--- .../classes/javax/sound/midi/MidiDeviceReceiver.java | 6 ++++-- .../javax/sound/midi/MidiDeviceTransmitter.java | 6 ++++-- .../classes/javax/sound/midi/MidiFileFormat.java | 3 ++- .../share/classes/javax/sound/midi/MidiMessage.java | 8 ++++++-- .../share/classes/javax/sound/midi/MidiSystem.java | 5 ++++- .../share/classes/javax/sound/midi/ShortMessage.java | 11 ++++++----- .../share/classes/javax/sound/midi/Synthesizer.java | 10 +++++----- .../share/classes/javax/sound/midi/SysexMessage.java | 3 ++- jdk/src/share/classes/javax/sound/midi/Track.java | 5 +++-- .../classes/javax/sound/sampled/AudioFileFormat.java | 3 ++- .../classes/javax/sound/sampled/AudioFormat.java | 3 ++- .../classes/javax/sound/sampled/AudioSystem.java | 3 ++- .../classes/javax/sound/sampled/BooleanControl.java | 3 ++- jdk/src/share/classes/javax/sound/sampled/Mixer.java | 4 +++- .../sound/sampled/spi/FormatConversionProvider.java | 5 ++++- 18 files changed, 58 insertions(+), 34 deletions(-) diff --git a/jdk/src/share/classes/java/applet/AppletContext.java b/jdk/src/share/classes/java/applet/AppletContext.java index 87623ee334f..f28308cfb11 100644 --- a/jdk/src/share/classes/java/applet/AppletContext.java +++ b/jdk/src/share/classes/java/applet/AppletContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2013, 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 @@ -56,7 +56,7 @@ public interface AppletContext { /** * Returns an Image object that can then be painted on - * the screen. The url argument that is + * the screen. The url argument that is * passed as an argument must specify an absolute URL. *

    * This method always returns immediately, whether or not the image @@ -157,7 +157,7 @@ public interface AppletContext { * @param stream stream to be associated with the specified key. If this * parameter is null, the specified key is removed * in this applet context. - * @throws IOException if the stream size exceeds a certain + * @throws IOException if the stream size exceeds a certain * size limit. Size limit is decided by the implementor of this * interface. * @since 1.4 diff --git a/jdk/src/share/classes/javax/sound/midi/MetaMessage.java b/jdk/src/share/classes/javax/sound/midi/MetaMessage.java index b7c235565f3..6378435acc7 100644 --- a/jdk/src/share/classes/javax/sound/midi/MetaMessage.java +++ b/jdk/src/share/classes/javax/sound/midi/MetaMessage.java @@ -149,7 +149,7 @@ public class MetaMessage extends MidiMessage { * @param data the data bytes in the MIDI message * @param length the number of bytes in the data * byte array - * @throws InvalidMidiDataException if the + * @throws InvalidMidiDataException if the * parameter values do not specify a valid MIDI meta message */ public void setMessage(int type, byte[] data, int length) throws InvalidMidiDataException { diff --git a/jdk/src/share/classes/javax/sound/midi/MidiDevice.java b/jdk/src/share/classes/javax/sound/midi/MidiDevice.java index 75d6638f681..be950e8aa48 100644 --- a/jdk/src/share/classes/javax/sound/midi/MidiDevice.java +++ b/jdk/src/share/classes/javax/sound/midi/MidiDevice.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -86,13 +86,13 @@ import java.util.List; * To detect if a MidiDevice represents a hardware MIDI port, the * following programming technique can be used: * - *

    + * 
    {@code
      * MidiDevice device = ...;
      * if ( ! (device instanceof Sequencer) && ! (device instanceof Synthesizer)) {
      *   // we're now sure that device represents a MIDI port
      *   // ...
      * }
    - * 
    + * }
    * *

    * A MidiDevice includes a {@link MidiDevice.Info} object diff --git a/jdk/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java b/jdk/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java index 9ea1df7c38e..550c7a4ccb8 100644 --- a/jdk/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java +++ b/jdk/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -33,7 +33,9 @@ package javax.sound.midi; * @since 1.7 */ public interface MidiDeviceReceiver extends Receiver { - /** Obtains a MidiDevice object which is an owner of this Receiver. + /** + * Obtains a MidiDevice object which is an owner of this Receiver. + * @return a MidiDevice object which is an owner of this Receiver */ public MidiDevice getMidiDevice(); } diff --git a/jdk/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java b/jdk/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java index b6a827188e2..730628c5e8d 100644 --- a/jdk/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java +++ b/jdk/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -35,7 +35,9 @@ package javax.sound.midi; */ public interface MidiDeviceTransmitter extends Transmitter { - /** Obtains a MidiDevice object which is an owner of this Transmitter. + /** + * Obtains a MidiDevice object which is an owner of this Transmitter. + * @return a MidiDevice object which is an owner of this Transmitter */ public MidiDevice getMidiDevice(); } diff --git a/jdk/src/share/classes/javax/sound/midi/MidiFileFormat.java b/jdk/src/share/classes/javax/sound/midi/MidiFileFormat.java index 4c399dbbe72..1d4669a2458 100644 --- a/jdk/src/share/classes/javax/sound/midi/MidiFileFormat.java +++ b/jdk/src/share/classes/javax/sound/midi/MidiFileFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -50,6 +50,7 @@ import java.util.Map; * be used in implementations: * * + * * * diff --git a/jdk/src/share/classes/javax/sound/midi/MidiMessage.java b/jdk/src/share/classes/javax/sound/midi/MidiMessage.java index 244757f27d7..7cc840bd775 100644 --- a/jdk/src/share/classes/javax/sound/midi/MidiMessage.java +++ b/jdk/src/share/classes/javax/sound/midi/MidiMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -55,7 +55,7 @@ package javax.sound.midi; * processing MIDI data that originated outside Java Sound and now * is encoded as signed bytes, the bytes can * can be converted to integers using this conversion: - *
    int i = (int)(byte & 0xFF)
    + *
    {@code int i = (int)(byte & 0xFF)}
    *

    * If you simply need to pass a known MIDI byte value as a method parameter, * it can be expressed directly as an integer, using (for example) decimal or @@ -118,6 +118,10 @@ public abstract class MidiMessage implements Cloneable { * method is called by concrete subclasses, which should * ensure that the data array specifies a complete, valid MIDI * message. + * + * @param data the data bytes in the MIDI message + * @param length the number of bytes in the data byte array + * @throws InvalidMidiDataException if the parameter values do not specify a valid MIDI meta message */ protected void setMessage(byte[] data, int length) throws InvalidMidiDataException { if (length < 0 || (length > 0 && length > data.length)) { diff --git a/jdk/src/share/classes/javax/sound/midi/MidiSystem.java b/jdk/src/share/classes/javax/sound/midi/MidiSystem.java index 9d6763a6406..4e390f11998 100644 --- a/jdk/src/share/classes/javax/sound/midi/MidiSystem.java +++ b/jdk/src/share/classes/javax/sound/midi/MidiSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -80,6 +80,7 @@ import com.sun.media.sound.MidiDeviceTransmitterEnvelope; * consider them: * *

    MIDI File Format Properties
    Property keyValue type
    + * * * * @@ -425,6 +426,8 @@ public class MidiSystem { * it is used to identify the default sequencer. * For details, refer to the {@link MidiSystem class description}. * + * @param connected whether or not the returned {@code Sequencer} + * is connected to the default {@code Synthesizer} * @return the default sequencer * @throws MidiUnavailableException if the sequencer is not * available due to resource restrictions, diff --git a/jdk/src/share/classes/javax/sound/midi/ShortMessage.java b/jdk/src/share/classes/javax/sound/midi/ShortMessage.java index f2ccdd23f94..1445201f3fe 100644 --- a/jdk/src/share/classes/javax/sound/midi/ShortMessage.java +++ b/jdk/src/share/classes/javax/sound/midi/ShortMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -283,7 +283,7 @@ public class ShortMessage extends MidiMessage { /** * Sets the parameters for a MIDI message that takes no data bytes. * @param status the MIDI status byte - * @throws InvalidMidiDataException if status does not + * @throws InvalidMidiDataException if status does not * specify a valid MIDI status byte for a message that requires no data bytes. * @see #setMessage(int, int, int) * @see #setMessage(int, int, int, int) @@ -307,7 +307,7 @@ public class ShortMessage extends MidiMessage { * @param status the MIDI status byte * @param data1 the first data byte * @param data2 the second data byte - * @throws InvalidMidiDataException if the + * @throws InvalidMidiDataException if the * the status byte, or all data bytes belonging to the message, do * not specify a valid MIDI message. * @see #setMessage(int, int, int, int) @@ -357,7 +357,7 @@ public class ShortMessage extends MidiMessage { * @param channel the channel associated with the message * @param data1 the first data byte * @param data2 the second data byte - * @throws InvalidMidiDataException if the + * @throws InvalidMidiDataException if the * status byte or all data bytes belonging to the message, do * not specify a valid MIDI message * @@ -397,6 +397,7 @@ public class ShortMessage extends MidiMessage { * Obtains the MIDI command associated with this event. This method * assumes that the event is a MIDI channel message; if not, the return * value will not be meaningful. + * @return the MIDI command associated with this event * @see #setMessage(int, int, int, int) */ public int getCommand() { @@ -450,7 +451,7 @@ public class ShortMessage extends MidiMessage { * status byte value. * @param status status byte value, which must represent a short MIDI message * @return data length in bytes (0, 1, or 2) - * @throws InvalidMidiDataException if the + * @throws InvalidMidiDataException if the * status argument does not represent the status byte for any * short message */ diff --git a/jdk/src/share/classes/javax/sound/midi/Synthesizer.java b/jdk/src/share/classes/javax/sound/midi/Synthesizer.java index f9701c62c43..6740479b389 100644 --- a/jdk/src/share/classes/javax/sound/midi/Synthesizer.java +++ b/jdk/src/share/classes/javax/sound/midi/Synthesizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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,7 +170,7 @@ public interface Synthesizer extends MidiDevice { * already had been), false if the instrument could not be * loaded (for example, if the synthesizer has insufficient * memory to load it) - * @throws IllegalArgumentException if this + * @throws IllegalArgumentException if this * Synthesizer doesn't support the specified instrument's * soundbank * @see #unloadInstrument @@ -186,7 +186,7 @@ public interface Synthesizer extends MidiDevice { /** * Unloads a particular instrument. * @param instrument instrument to unload - * @throws IllegalArgumentException if this + * @throws IllegalArgumentException if this * Synthesizer doesn't support the specified instrument's * soundbank * @see #loadInstrument @@ -214,10 +214,10 @@ public interface Synthesizer extends MidiDevice { * of the old instrument, it should be loaded into the synthesizer * @return true if the instrument succeessfully remapped, * false if feature is not implemented by synthesizer - * @throws IllegalArgumentException if instrument + * @throws IllegalArgumentException if instrument * from or instrument to aren't supported by * synthesizer or if instrument to is not loaded - * @throws NullPointerException if from or + * @throws NullPointerException if from or * to parameters have null value * @see #loadInstrument * @see #loadInstruments diff --git a/jdk/src/share/classes/javax/sound/midi/SysexMessage.java b/jdk/src/share/classes/javax/sound/midi/SysexMessage.java index c86519bff34..ae4e418e8e6 100644 --- a/jdk/src/share/classes/javax/sound/midi/SysexMessage.java +++ b/jdk/src/share/classes/javax/sound/midi/SysexMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -204,6 +204,7 @@ public class SysexMessage extends MidiMessage { * @param data the system exclusive message data * @param length the length of the valid message data in * the array + * @throws InvalidMidiDataException if the status byte is invalid for a sysex message */ public void setMessage(int status, byte[] data, int length) throws InvalidMidiDataException { if ( (status != 0xF0) && (status != 0xF7) ) { diff --git a/jdk/src/share/classes/javax/sound/midi/Track.java b/jdk/src/share/classes/javax/sound/midi/Track.java index ad1ff52d202..4e54a8aa3dd 100644 --- a/jdk/src/share/classes/javax/sound/midi/Track.java +++ b/jdk/src/share/classes/javax/sound/midi/Track.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -211,10 +211,11 @@ public class Track { /** * Obtains the event at the specified index. * @param index the location of the desired event in the event vector - * @throws ArrayIndexOutOfBoundsException if the + * @throws ArrayIndexOutOfBoundsException if the * specified index is negative or not less than the current size of * this track. * @see #size + * @return the event at the specified index */ public MidiEvent get(int index) throws ArrayIndexOutOfBoundsException { try { diff --git a/jdk/src/share/classes/javax/sound/sampled/AudioFileFormat.java b/jdk/src/share/classes/javax/sound/sampled/AudioFileFormat.java index 30fe82be365..d1216e207a7 100644 --- a/jdk/src/share/classes/javax/sound/sampled/AudioFileFormat.java +++ b/jdk/src/share/classes/javax/sound/sampled/AudioFileFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -57,6 +57,7 @@ import java.util.Map; * be used in implementations: * *
    MIDI System Property Keys
    Property KeyInterface
    + * * * * diff --git a/jdk/src/share/classes/javax/sound/sampled/AudioFormat.java b/jdk/src/share/classes/javax/sound/sampled/AudioFormat.java index 7457f8220eb..2e679784ea3 100644 --- a/jdk/src/share/classes/javax/sound/sampled/AudioFormat.java +++ b/jdk/src/share/classes/javax/sound/sampled/AudioFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -85,6 +85,7 @@ import java.util.Map; * service providers should use, if applicable: * *
    Audio File Format Property Keys
    Property keyValue type
    + * * * * diff --git a/jdk/src/share/classes/javax/sound/sampled/AudioSystem.java b/jdk/src/share/classes/javax/sound/sampled/AudioSystem.java index cf06ca25741..6c8bfaf9f5e 100644 --- a/jdk/src/share/classes/javax/sound/sampled/AudioSystem.java +++ b/jdk/src/share/classes/javax/sound/sampled/AudioSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -75,6 +75,7 @@ import com.sun.media.sound.JDK13Services; * consider them: * *
    Audio Format Property Keys
    Property keyValue type
    + * * * * diff --git a/jdk/src/share/classes/javax/sound/sampled/BooleanControl.java b/jdk/src/share/classes/javax/sound/sampled/BooleanControl.java index 047b2f00803..e48e06c339c 100644 --- a/jdk/src/share/classes/javax/sound/sampled/BooleanControl.java +++ b/jdk/src/share/classes/javax/sound/sampled/BooleanControl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -125,6 +125,7 @@ public abstract class BooleanControl extends Control { /** * Obtains the label for the specified state. + * @param state the state whose label will be returned * @return the label for the specified state, such as "true" or "on" * for true, or "false" or "off" for false. */ diff --git a/jdk/src/share/classes/javax/sound/sampled/Mixer.java b/jdk/src/share/classes/javax/sound/sampled/Mixer.java index c4d0ccbef03..755ab913342 100644 --- a/jdk/src/share/classes/javax/sound/sampled/Mixer.java +++ b/jdk/src/share/classes/javax/sound/sampled/Mixer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -133,6 +133,8 @@ public interface Mixer extends Line { * DataLine. * * @param info describes the desired line + * @return a line that is available for use and that matches the description + * in the specified {@code Line.Info} object * @throws LineUnavailableException if a matching line * is not available due to resource restrictions * @throws IllegalArgumentException if this mixer does diff --git a/jdk/src/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java b/jdk/src/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java index 194582f17dd..a27184a0b87 100644 --- a/jdk/src/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java +++ b/jdk/src/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -116,6 +116,7 @@ public abstract class FormatConversionProvider { * given a particular source format. * If no target format encodings are supported for this source format, * an array of length 0 is returned. + * @param sourceFormat format of the incoming data * @return array of supported target format encodings. */ public abstract AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat); @@ -146,6 +147,8 @@ public abstract class FormatConversionProvider { * supported by the format converter * If no target formats with the specified encoding are supported * for this source format, an array of length 0 is returned. + * @param targetEncoding desired encoding of the stream after processing + * @param sourceFormat format of the incoming data * @return array of supported target formats. */ public abstract AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat); From cd162a777df6b84a2682ad40e27ff6c5fed7bc76 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren Date: Tue, 6 Aug 2013 12:56:18 -0700 Subject: [PATCH 23/39] 8022412: Fixed warnings in java.util root, except for HashMap Reviewed-by: mduigou, darcy --- .../classes/java/util/ArrayPrefixHelpers.java | 5 +- .../share/classes/java/util/Collections.java | 53 +++++++++++-------- .../share/classes/java/util/Comparator.java | 5 +- .../share/classes/java/util/Comparators.java | 4 +- .../share/classes/java/util/Hashtable.java | 2 + .../classes/java/util/IdentityHashMap.java | 2 + jdk/src/share/classes/java/util/Vector.java | 7 +-- .../share/classes/java/util/WeakHashMap.java | 2 + 8 files changed, 47 insertions(+), 33 deletions(-) diff --git a/jdk/src/share/classes/java/util/ArrayPrefixHelpers.java b/jdk/src/share/classes/java/util/ArrayPrefixHelpers.java index ef59ec7d478..afa872c5855 100644 --- a/jdk/src/share/classes/java/util/ArrayPrefixHelpers.java +++ b/jdk/src/share/classes/java/util/ArrayPrefixHelpers.java @@ -128,6 +128,7 @@ class ArrayPrefixHelpers { this.lo = lo; this.hi = hi; } + @SuppressWarnings("unchecked") public final void compute() { final BinaryOperator fn; final T[] a; @@ -692,6 +693,4 @@ class ArrayPrefixHelpers { } } } - - -} \ No newline at end of file +} diff --git a/jdk/src/share/classes/java/util/Collections.java b/jdk/src/share/classes/java/util/Collections.java index 43ce42eeea6..97555f567fa 100644 --- a/jdk/src/share/classes/java/util/Collections.java +++ b/jdk/src/share/classes/java/util/Collections.java @@ -1143,6 +1143,7 @@ public class Collections { public boolean removeIf(Predicate filter) { throw new UnsupportedOperationException(); } + @SuppressWarnings("unchecked") @Override public Spliterator spliterator() { return (Spliterator)c.spliterator(); @@ -1900,7 +1901,7 @@ public class Collections { private static final long serialVersionUID = -2239321462712562324L; - EmptyNavigableMap() { super(new TreeMap()); } + EmptyNavigableMap() { super(new TreeMap()); } @Override public NavigableSet navigableKeySet() @@ -1928,46 +1929,52 @@ public class Collections { public K ceilingKey(K key) { return nm.ceilingKey(key); } public K higherKey(K key) { return nm.higherKey(key); } + @SuppressWarnings("unchecked") public Entry lowerEntry(K key) { Entry lower = (Entry) nm.lowerEntry(key); return (null != lower) - ? new UnmodifiableEntrySet.UnmodifiableEntry(lower) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(lower) : null; } + @SuppressWarnings("unchecked") public Entry floorEntry(K key) { Entry floor = (Entry) nm.floorEntry(key); return (null != floor) - ? new UnmodifiableEntrySet.UnmodifiableEntry(floor) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(floor) : null; } + @SuppressWarnings("unchecked") public Entry ceilingEntry(K key) { Entry ceiling = (Entry) nm.ceilingEntry(key); return (null != ceiling) - ? new UnmodifiableEntrySet.UnmodifiableEntry(ceiling) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(ceiling) : null; } + @SuppressWarnings("unchecked") public Entry higherEntry(K key) { Entry higher = (Entry) nm.higherEntry(key); return (null != higher) - ? new UnmodifiableEntrySet.UnmodifiableEntry(higher) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(higher) : null; } + @SuppressWarnings("unchecked") public Entry firstEntry() { Entry first = (Entry) nm.firstEntry(); return (null != first) - ? new UnmodifiableEntrySet.UnmodifiableEntry(first) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(first) : null; } + @SuppressWarnings("unchecked") public Entry lastEntry() { Entry last = (Entry) nm.lastEntry(); return (null != last) - ? new UnmodifiableEntrySet.UnmodifiableEntry(last) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(last) : null; } @@ -2360,7 +2367,7 @@ public class Collections { } public NavigableSet tailSet(E fromElement) { synchronized (mutex) { - return new SynchronizedNavigableSet(ns.tailSet(fromElement, true), mutex); + return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, true), mutex); } } @@ -2925,7 +2932,7 @@ public class Collections { public NavigableMap descendingMap() { synchronized (mutex) { return - new SynchronizedNavigableMap(nm.descendingMap(), mutex); + new SynchronizedNavigableMap<>(nm.descendingMap(), mutex); } } @@ -2935,13 +2942,13 @@ public class Collections { public NavigableSet navigableKeySet() { synchronized (mutex) { - return new SynchronizedNavigableSet(nm.navigableKeySet(), mutex); + return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); } } public NavigableSet descendingKeySet() { synchronized (mutex) { - return new SynchronizedNavigableSet(nm.descendingKeySet(), mutex); + return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); } } @@ -2959,27 +2966,27 @@ public class Collections { } public SortedMap tailMap(K fromKey) { synchronized (mutex) { - return new SynchronizedNavigableMap<>(nm.tailMap(fromKey, true),mutex); + return new SynchronizedNavigableMap<>(nm.tailMap(fromKey, true),mutex); } } public NavigableMap subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { synchronized (mutex) { - return new SynchronizedNavigableMap( + return new SynchronizedNavigableMap<>( nm.subMap(fromKey, fromInclusive, toKey, toInclusive), mutex); } } public NavigableMap headMap(K toKey, boolean inclusive) { synchronized (mutex) { - return new SynchronizedNavigableMap( + return new SynchronizedNavigableMap<>( nm.headMap(toKey, inclusive), mutex); } } public NavigableMap tailMap(K fromKey, boolean inclusive) { synchronized (mutex) { - return new SynchronizedNavigableMap( + return new SynchronizedNavigableMap<>( nm.tailMap(fromKey, inclusive), mutex); } } @@ -4081,7 +4088,7 @@ public class Collections { public Entry lowerEntry(K key) { Entry lower = nm.lowerEntry(key); return (null != lower) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(lower, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(lower, valueType) : null; } @@ -4090,7 +4097,7 @@ public class Collections { public Entry floorEntry(K key) { Entry floor = nm.floorEntry(key); return (null != floor) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(floor, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(floor, valueType) : null; } @@ -4099,7 +4106,7 @@ public class Collections { public Entry ceilingEntry(K key) { Entry ceiling = nm.ceilingEntry(key); return (null != ceiling) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(ceiling, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(ceiling, valueType) : null; } @@ -4108,7 +4115,7 @@ public class Collections { public Entry higherEntry(K key) { Entry higher = nm.higherEntry(key); return (null != higher) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(higher, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(higher, valueType) : null; } @@ -4117,14 +4124,14 @@ public class Collections { public Entry firstEntry() { Entry first = nm.firstEntry(); return (null != first) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(first, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(first, valueType) : null; } public Entry lastEntry() { Entry last = nm.lastEntry(); return (null != last) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(last, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(last, valueType) : null; } @@ -4132,14 +4139,14 @@ public class Collections { Entry entry = nm.pollFirstEntry(); return (null == entry) ? null - : new CheckedMap.CheckedEntrySet.CheckedEntry(entry, valueType); + : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType); } public Entry pollLastEntry() { Entry entry = nm.pollLastEntry(); return (null == entry) ? null - : new CheckedMap.CheckedEntrySet.CheckedEntry(entry, valueType); + : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType); } public NavigableMap descendingMap() { diff --git a/jdk/src/share/classes/java/util/Comparator.java b/jdk/src/share/classes/java/util/Comparator.java index cd65ca4ea06..55d5efb9866 100644 --- a/jdk/src/share/classes/java/util/Comparator.java +++ b/jdk/src/share/classes/java/util/Comparator.java @@ -352,6 +352,7 @@ public interface Comparator { * @see Comparable * @since 1.8 */ + @SuppressWarnings("unchecked") public static > Comparator naturalOrder() { return (Comparator) Comparators.NaturalOrderComparator.INSTANCE; } @@ -374,7 +375,7 @@ public interface Comparator { * @since 1.8 */ public static Comparator nullsFirst(Comparator comparator) { - return new Comparators.NullComparator(true, comparator); + return new Comparators.NullComparator<>(true, comparator); } /** @@ -395,7 +396,7 @@ public interface Comparator { * @since 1.8 */ public static Comparator nullsLast(Comparator comparator) { - return new Comparators.NullComparator(false, comparator); + return new Comparators.NullComparator<>(false, comparator); } /** diff --git a/jdk/src/share/classes/java/util/Comparators.java b/jdk/src/share/classes/java/util/Comparators.java index a9038321085..ee806798d7a 100644 --- a/jdk/src/share/classes/java/util/Comparators.java +++ b/jdk/src/share/classes/java/util/Comparators.java @@ -87,12 +87,12 @@ class Comparators { @Override public Comparator thenComparing(Comparator other) { Objects.requireNonNull(other); - return new NullComparator(nullFirst, real == null ? other : real.thenComparing(other)); + return new NullComparator<>(nullFirst, real == null ? other : real.thenComparing(other)); } @Override public Comparator reversed() { - return new NullComparator(!nullFirst, real == null ? null : real.reversed()); + return new NullComparator<>(!nullFirst, real == null ? null : real.reversed()); } } } diff --git a/jdk/src/share/classes/java/util/Hashtable.java b/jdk/src/share/classes/java/util/Hashtable.java index a481719be0c..518bd17f5b7 100644 --- a/jdk/src/share/classes/java/util/Hashtable.java +++ b/jdk/src/share/classes/java/util/Hashtable.java @@ -928,6 +928,7 @@ public class Hashtable return (null == result) ? defaultValue : result; } + @SuppressWarnings("unchecked") @Override public synchronized void forEach(BiConsumer action) { Objects.requireNonNull(action); // explicit check required in case @@ -947,6 +948,7 @@ public class Hashtable } } + @SuppressWarnings("unchecked") @Override public synchronized void replaceAll(BiFunction function) { Objects.requireNonNull(function); // explicit check required in case diff --git a/jdk/src/share/classes/java/util/IdentityHashMap.java b/jdk/src/share/classes/java/util/IdentityHashMap.java index 3064588c901..a4bdc4b9efd 100644 --- a/jdk/src/share/classes/java/util/IdentityHashMap.java +++ b/jdk/src/share/classes/java/util/IdentityHashMap.java @@ -1339,6 +1339,7 @@ public class IdentityHashMap tab[i + 1] = value; } + @SuppressWarnings("unchecked") @Override public void forEach(BiConsumer action) { Objects.requireNonNull(action); @@ -1357,6 +1358,7 @@ public class IdentityHashMap } } + @SuppressWarnings("unchecked") @Override public void replaceAll(BiFunction function) { Objects.requireNonNull(function); diff --git a/jdk/src/share/classes/java/util/Vector.java b/jdk/src/share/classes/java/util/Vector.java index 18cc6f2f0aa..6146957dfd6 100644 --- a/jdk/src/share/classes/java/util/Vector.java +++ b/jdk/src/share/classes/java/util/Vector.java @@ -1164,12 +1164,13 @@ public class Vector if (i >= size) { return; } - final Object[] elementData = Vector.this.elementData; + @SuppressWarnings("unchecked") + final E[] elementData = (E[]) Vector.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { - action.accept((E) elementData[i++]); + action.accept(elementData[i++]); } // update once at end of iteration to reduce heap write traffic cursor = i; @@ -1311,8 +1312,8 @@ public class Vector modCount++; } - @Override @SuppressWarnings("unchecked") + @Override public synchronized void sort(Comparator c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, elementCount, c); diff --git a/jdk/src/share/classes/java/util/WeakHashMap.java b/jdk/src/share/classes/java/util/WeakHashMap.java index eb2e636e2ba..0299d296638 100644 --- a/jdk/src/share/classes/java/util/WeakHashMap.java +++ b/jdk/src/share/classes/java/util/WeakHashMap.java @@ -1038,6 +1038,7 @@ public class WeakHashMap } } + @SuppressWarnings("unchecked") @Override public void forEach(BiConsumer action) { Objects.requireNonNull(action); @@ -1059,6 +1060,7 @@ public class WeakHashMap } } + @SuppressWarnings("unchecked") @Override public void replaceAll(BiFunction function) { Objects.requireNonNull(function); From ebb9d2fb06d142f25f123e9656e38c9f5660cf10 Mon Sep 17 00:00:00 2001 From: Jason Uh Date: Tue, 6 Aug 2013 13:46:15 -0700 Subject: [PATCH 24/39] 8022439: Fix lint warnings in sun.security.ec Reviewed-by: darcy --- jdk/src/share/classes/sun/security/ec/ECDSASignature.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jdk/src/share/classes/sun/security/ec/ECDSASignature.java b/jdk/src/share/classes/sun/security/ec/ECDSASignature.java index c831259f5ad..1e80694207e 100644 --- a/jdk/src/share/classes/sun/security/ec/ECDSASignature.java +++ b/jdk/src/share/classes/sun/security/ec/ECDSASignature.java @@ -323,6 +323,7 @@ abstract class ECDSASignature extends SignatureSpi { // set parameter, not supported. See JCA doc @Override + @Deprecated protected void engineSetParameter(String param, Object value) throws InvalidParameterException { throw new UnsupportedOperationException("setParameter() not supported"); @@ -330,6 +331,7 @@ abstract class ECDSASignature extends SignatureSpi { // get parameter, not supported. See JCA doc @Override + @Deprecated protected Object engineGetParameter(String param) throws InvalidParameterException { throw new UnsupportedOperationException("getParameter() not supported"); From 6ecdd925d1d66588fae4274a6e111600c07cfc61 Mon Sep 17 00:00:00 2001 From: Jason Uh Date: Tue, 6 Aug 2013 14:10:06 -0700 Subject: [PATCH 25/39] 8022443: Fix lint warnings in sun.security.pkcs12 Reviewed-by: darcy --- .../share/classes/sun/security/pkcs12/PKCS12KeyStore.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java index 32f1da53afa..35564498c0e 100644 --- a/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java +++ b/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java @@ -775,7 +775,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi { } } if (params != null) { - if (algorithm.equals(pbes2_OID)) { + if (algorithm.equals((Object)pbes2_OID)) { algParams = AlgorithmParameters.getInstance("PBES2"); } else { algParams = AlgorithmParameters.getInstance("PBE"); @@ -912,7 +912,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi { private static String mapPBEParamsToAlgorithm(ObjectIdentifier algorithm, AlgorithmParameters algParams) throws NoSuchAlgorithmException { // Check for PBES2 algorithms - if (algorithm.equals(pbes2_OID) && algParams != null) { + if (algorithm.equals((Object)pbes2_OID) && algParams != null) { return algParams.toString(); } return algorithm.toString(); @@ -1921,7 +1921,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi { } safeContentsData = safeContents.getData(); - } else if (contentType.equals(ContentInfo.ENCRYPTED_DATA_OID)) { + } else if (contentType.equals((Object)ContentInfo.ENCRYPTED_DATA_OID)) { if (password == null) { continue; } From 6c4cb951711550d80f5aee766208edaf03462d70 Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Tue, 6 Aug 2013 14:24:05 -0700 Subject: [PATCH 26/39] 8022440: suppress deprecation warnings in sun.rmi Reviewed-by: mduigou --- jdk/src/share/classes/sun/rmi/runtime/Log.java | 3 ++- jdk/src/share/classes/sun/rmi/server/ActivatableRef.java | 3 ++- jdk/src/share/classes/sun/rmi/server/Dispatcher.java | 3 ++- jdk/src/share/classes/sun/rmi/server/LoaderHandler.java | 3 ++- jdk/src/share/classes/sun/rmi/server/UnicastRef.java | 5 +++-- jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java | 3 ++- jdk/src/share/classes/sun/rmi/server/Util.java | 3 ++- jdk/src/share/classes/sun/rmi/transport/DGCImpl.java | 3 ++- .../share/classes/sun/rmi/transport/StreamRemoteCall.java | 3 ++- jdk/src/share/classes/sun/rmi/transport/Transport.java | 3 ++- .../sun/rmi/transport/proxy/RMIMasterSocketFactory.java | 3 ++- .../classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java | 3 ++- .../share/classes/sun/rmi/transport/tcp/TCPTransport.java | 3 ++- 13 files changed, 27 insertions(+), 14 deletions(-) diff --git a/jdk/src/share/classes/sun/rmi/runtime/Log.java b/jdk/src/share/classes/sun/rmi/runtime/Log.java index 7a1b0982fba..62d03614dfe 100644 --- a/jdk/src/share/classes/sun/rmi/runtime/Log.java +++ b/jdk/src/share/classes/sun/rmi/runtime/Log.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -61,6 +61,7 @@ import java.util.HashMap; * @author Laird Dornin * @since 1.4 */ +@SuppressWarnings("deprecation") public abstract class Log { /** Logger re-definition of old RMI log values */ diff --git a/jdk/src/share/classes/sun/rmi/server/ActivatableRef.java b/jdk/src/share/classes/sun/rmi/server/ActivatableRef.java index 6224ff35655..7e6668c389e 100644 --- a/jdk/src/share/classes/sun/rmi/server/ActivatableRef.java +++ b/jdk/src/share/classes/sun/rmi/server/ActivatableRef.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -41,6 +41,7 @@ import java.rmi.server.RemoteObjectInvocationHandler; import java.rmi.server.RemoteRef; import java.rmi.server.RemoteStub; +@SuppressWarnings("deprecation") public class ActivatableRef implements RemoteRef { private static final long serialVersionUID = 7579060052569229166L; diff --git a/jdk/src/share/classes/sun/rmi/server/Dispatcher.java b/jdk/src/share/classes/sun/rmi/server/Dispatcher.java index 947aa4176e2..a2ec6dcf264 100644 --- a/jdk/src/share/classes/sun/rmi/server/Dispatcher.java +++ b/jdk/src/share/classes/sun/rmi/server/Dispatcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -31,6 +31,7 @@ import java.rmi.server.RemoteCall; * The Dispatcher interface allows the transport to make * the upcall to the server side remote reference. */ +@SuppressWarnings("deprecation") public interface Dispatcher { /** diff --git a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java index 7830ed354bb..c35da195ad2 100644 --- a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java +++ b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -67,6 +67,7 @@ import sun.security.action.GetPropertyAction; * @author Peter Jones * @author Laird Dornin */ +@SuppressWarnings("deprecation") public final class LoaderHandler { /** RMI class loader log level */ diff --git a/jdk/src/share/classes/sun/rmi/server/UnicastRef.java b/jdk/src/share/classes/sun/rmi/server/UnicastRef.java index 3ea4bd34ce5..9b95724094a 100644 --- a/jdk/src/share/classes/sun/rmi/server/UnicastRef.java +++ b/jdk/src/share/classes/sun/rmi/server/UnicastRef.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -49,7 +49,8 @@ import sun.security.action.GetBooleanAction; * NOTE: There is a JDK-internal dependency on the existence of this * class's getLiveRef method (as it is inherited by UnicastRef2) in * the implementation of javax.management.remote.rmi.RMIConnector. - **/ + */ +@SuppressWarnings("deprecation") public class UnicastRef implements RemoteRef { /** diff --git a/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java b/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java index b47b4ed6e20..180a6252304 100644 --- a/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java +++ b/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -67,6 +67,7 @@ import sun.security.action.GetBooleanAction; * @author Roger Riggs * @author Peter Jones */ +@SuppressWarnings("deprecation") public class UnicastServerRef extends UnicastRef implements ServerRef, Dispatcher { diff --git a/jdk/src/share/classes/sun/rmi/server/Util.java b/jdk/src/share/classes/sun/rmi/server/Util.java index 0f6c7ddee50..0f82a84c9b1 100644 --- a/jdk/src/share/classes/sun/rmi/server/Util.java +++ b/jdk/src/share/classes/sun/rmi/server/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -64,6 +64,7 @@ import sun.security.action.GetPropertyAction; * A utility class with static methods for creating stubs/proxies and * skeletons for remote objects. */ +@SuppressWarnings("deprecation") public final class Util { /** "server" package log level */ diff --git a/jdk/src/share/classes/sun/rmi/transport/DGCImpl.java b/jdk/src/share/classes/sun/rmi/transport/DGCImpl.java index b5ce50cacc7..88ac91b648d 100644 --- a/jdk/src/share/classes/sun/rmi/transport/DGCImpl.java +++ b/jdk/src/share/classes/sun/rmi/transport/DGCImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -59,6 +59,7 @@ import sun.security.action.GetPropertyAction; * * @author Ann Wollrath */ +@SuppressWarnings("deprecation") final class DGCImpl implements DGC { /* dgc system log */ diff --git a/jdk/src/share/classes/sun/rmi/transport/StreamRemoteCall.java b/jdk/src/share/classes/sun/rmi/transport/StreamRemoteCall.java index 5971405d970..915ed6f9262 100644 --- a/jdk/src/share/classes/sun/rmi/transport/StreamRemoteCall.java +++ b/jdk/src/share/classes/sun/rmi/transport/StreamRemoteCall.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -45,6 +45,7 @@ import sun.rmi.transport.tcp.TCPEndpoint; * * @author Ann Wollrath */ +@SuppressWarnings("deprecation") public class StreamRemoteCall implements RemoteCall { private ConnectionInputStream in = null; private ConnectionOutputStream out = null; diff --git a/jdk/src/share/classes/sun/rmi/transport/Transport.java b/jdk/src/share/classes/sun/rmi/transport/Transport.java index 286682dff8a..217c93682bd 100644 --- a/jdk/src/share/classes/sun/rmi/transport/Transport.java +++ b/jdk/src/share/classes/sun/rmi/transport/Transport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -47,6 +47,7 @@ import sun.rmi.server.UnicastServerRef; * * @author Ann Wollrath */ +@SuppressWarnings("deprecation") public abstract class Transport { /** "transport" package log level */ diff --git a/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java b/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java index d3dbf6f1da4..e77e224597f 100644 --- a/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java +++ b/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -44,6 +44,7 @@ import sun.security.action.GetLongAction; * connect to the same host will automatically use the same * mechanism. */ +@SuppressWarnings("deprecation") public class RMIMasterSocketFactory extends RMISocketFactory { /** "proxy" package log level */ diff --git a/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java b/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java index b12809a26bf..d1b6cbf7e15 100644 --- a/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java +++ b/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -43,6 +43,7 @@ import sun.rmi.runtime.Log; * * @author Peter Jones */ +@SuppressWarnings("deprecation") final class ConnectionMultiplexer { /** "multiplex" log level */ diff --git a/jdk/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java b/jdk/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java index 54d6d21d9e6..24655c2f0b5 100644 --- a/jdk/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java +++ b/jdk/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -84,6 +84,7 @@ import sun.security.action.GetPropertyAction; * @author Ann Wollrath * @author Peter Jones */ +@SuppressWarnings("deprecation") public class TCPTransport extends Transport { /* tcp package log */ From bcf263eb10ddd769d0584d3256ad21da00b29611 Mon Sep 17 00:00:00 2001 From: Dan Xu Date: Tue, 6 Aug 2013 14:33:56 -0700 Subject: [PATCH 27/39] 8022410: Fix Javac Warnings in com.sun.security.auth Package Reviewed-by: darcy --- .../com/sun/security/auth/PolicyFile.java | 68 ++++++++++--------- .../sun/security/auth/SubjectCodeSource.java | 62 ++++++++--------- 2 files changed, 63 insertions(+), 67 deletions(-) diff --git a/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java b/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java index 447eb395b69..2ea13fb3169 100644 --- a/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java +++ b/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -47,6 +47,10 @@ import javax.security.auth.PrivateCredentialPermission; import sun.security.util.PropertyExpander; +import sun.security.provider.PolicyParser.PrincipalEntry; +import sun.security.provider.PolicyParser.GrantEntry; +import sun.security.provider.PolicyParser.PermissionEntry; + /** * This class represents a default implementation for * javax.security.auth.Policy. @@ -469,7 +473,8 @@ public class PolicyFile extends javax.security.auth.Policy { * @param policyFile the policy Reader object. */ private void init(URL policy) { - PolicyParser pp = new PolicyParser(expandProperties); + sun.security.provider.PolicyParser pp = + new sun.security.provider.PolicyParser(expandProperties); try { InputStreamReader isr = new InputStreamReader(getInputStream(policy)); @@ -477,12 +482,12 @@ public class PolicyFile extends javax.security.auth.Policy { isr.close(); KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(), pp.getKeyStoreType()); - Enumeration enum_ = pp.grantElements(); + Enumeration enum_ = pp.grantElements(); while (enum_.hasMoreElements()) { - PolicyParser.GrantEntry ge = enum_.nextElement(); + GrantEntry ge = enum_.nextElement(); addGrantEntry(ge, keyStore); } - } catch (PolicyParser.ParsingException pe) { + } catch (sun.security.provider.PolicyParser.ParsingException pe) { System.err.println(AUTH_POLICY + rb.getString(".error.parsing.") + policy); System.err.println(AUTH_POLICY + @@ -521,8 +526,8 @@ public class PolicyFile extends javax.security.auth.Policy { * * @return null if signedBy alias is not recognized */ - CodeSource getCodeSource(PolicyParser.GrantEntry ge, KeyStore keyStore) - throws java.net.MalformedURLException + CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore) + throws java.net.MalformedURLException { Certificate[] certs = null; if (ge.signedBy != null) { @@ -559,20 +564,18 @@ public class PolicyFile extends javax.security.auth.Policy { /** * Add one policy entry to the vector. */ - private void addGrantEntry(PolicyParser.GrantEntry ge, - KeyStore keyStore) { + private void addGrantEntry(GrantEntry ge, KeyStore keyStore) { if (debug != null) { debug.println("Adding policy entry: "); debug.println(" signedBy " + ge.signedBy); debug.println(" codeBase " + ge.codeBase); if (ge.principals != null && ge.principals.size() > 0) { - ListIterator li = - ge.principals.listIterator(); + ListIterator li = ge.principals.listIterator(); while (li.hasNext()) { - PolicyParser.PrincipalEntry pppe = li.next(); - debug.println(" " + pppe.principalClass + - " " + pppe.principalName); + PrincipalEntry pppe = li.next(); + debug.println(" " + pppe.getPrincipalClass() + + " " + pppe.getPrincipalName()); } } debug.println(); @@ -584,10 +587,9 @@ public class PolicyFile extends javax.security.auth.Policy { if (codesource == null) return; PolicyEntry entry = new PolicyEntry(codesource); - Enumeration enum_ = - ge.permissionElements(); + Enumeration enum_ = ge.permissionElements(); while (enum_.hasMoreElements()) { - PolicyParser.PermissionEntry pe = enum_.nextElement(); + PermissionEntry pe = enum_.nextElement(); try { // XXX special case PrivateCredentialPermission-SELF Permission perm; @@ -998,11 +1000,11 @@ public class PolicyFile extends javax.security.auth.Policy { return true; } - ListIterator pli = - scs.getPrincipals().listIterator(); + ListIterator pli = + scs.getPrincipals().listIterator(); while (pli.hasNext()) { - PolicyParser.PrincipalEntry principal = pli.next(); + PrincipalEntry principal = pli.next(); // XXX // if the Policy entry's Principal does not contain a @@ -1050,30 +1052,29 @@ public class PolicyFile extends javax.security.auth.Policy { * if (y == 1), it's the principal name. */ private String[][] getPrincipalInfo - (PolicyParser.PrincipalEntry principal, - final CodeSource accCs) { + (PrincipalEntry principal, final CodeSource accCs) { // there are 3 possibilities: // 1) the entry's Principal class and name are not wildcarded // 2) the entry's Principal name is wildcarded only // 3) the entry's Principal class and name are wildcarded - if (!principal.principalClass.equals - (PolicyParser.PrincipalEntry.WILDCARD_CLASS) && - !principal.principalName.equals - (PolicyParser.PrincipalEntry.WILDCARD_NAME)) { + if (!principal.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) && + !principal.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME)) { // build a PrivateCredentialPermission for the principal // from the Policy entry String[][] info = new String[1][2]; - info[0][0] = principal.principalClass; - info[0][1] = principal.principalName; + info[0][0] = principal.getPrincipalClass(); + info[0][1] = principal.getPrincipalName(); return info; - } else if (!principal.principalClass.equals - (PolicyParser.PrincipalEntry.WILDCARD_CLASS) && - principal.principalName.equals - (PolicyParser.PrincipalEntry.WILDCARD_NAME)) { + } else if (!principal.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) && + principal.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME)) { // build a PrivateCredentialPermission for all // the Subject's principals that are instances of principalClass @@ -1088,7 +1089,7 @@ public class PolicyFile extends javax.security.auth.Policy { // If it doesn't, we should stop here with a ClassCastException. @SuppressWarnings("unchecked") Class pClass = (Class) - Class.forName(principal.principalClass, false, + Class.forName(principal.getPrincipalClass(), false, ClassLoader.getSystemClassLoader()); principalSet = scs.getSubject().getPrincipals(pClass); } catch (Exception e) { @@ -1387,6 +1388,7 @@ public class PolicyFile extends javax.security.auth.Policy { } } +@SuppressWarnings("deprecation") class PolicyPermissions extends PermissionCollection { private static final long serialVersionUID = -1954188373270545523L; diff --git a/jdk/src/share/classes/com/sun/security/auth/SubjectCodeSource.java b/jdk/src/share/classes/com/sun/security/auth/SubjectCodeSource.java index 35d3bf1c410..7e38a087420 100644 --- a/jdk/src/share/classes/com/sun/security/auth/SubjectCodeSource.java +++ b/jdk/src/share/classes/com/sun/security/auth/SubjectCodeSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -33,6 +33,7 @@ import java.security.cert.Certificate; import java.lang.reflect.Constructor; import javax.security.auth.Subject; +import sun.security.provider.PolicyParser.PrincipalEntry; /** *

    This SubjectCodeSource class contains @@ -57,7 +58,7 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { }); private Subject subject; - private LinkedList principals; + private LinkedList principals; private static final Class[] PARAMS = { String.class }; private static final sun.security.util.Debug debug = sun.security.util.Debug.getInstance("auth", "\t[Auth Access]"); @@ -87,14 +88,14 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { * SubjectCodeSource

    */ SubjectCodeSource(Subject subject, - LinkedList principals, + LinkedList principals, URL url, Certificate[] certs) { super(url, certs); this.subject = subject; this.principals = (principals == null ? - new LinkedList() : - new LinkedList(principals)); + new LinkedList() : + new LinkedList(principals)); sysClassLoader = java.security.AccessController.doPrivileged (new java.security.PrivilegedAction() { public ClassLoader run() { @@ -114,7 +115,7 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { * SubjectCodeSource as a LinkedList * of PolicyParser.PrincipalEntry objects. */ - LinkedList getPrincipals() { + LinkedList getPrincipals() { return principals; } @@ -167,7 +168,7 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { */ public boolean implies(CodeSource codesource) { - LinkedList subjectList = null; + LinkedList subjectList = null; if (codesource == null || !(codesource instanceof SubjectCodeSource) || @@ -197,20 +198,19 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { return false; } - ListIterator li = - this.principals.listIterator(0); + ListIterator li = this.principals.listIterator(0); while (li.hasNext()) { - PolicyParser.PrincipalEntry pppe = li.next(); + PrincipalEntry pppe = li.next(); try { // handle PrincipalComparators Class principalComparator = Class.forName( - pppe.principalClass, true, sysClassLoader); + pppe.getPrincipalClass(), true, sysClassLoader); Constructor c = principalComparator.getConstructor(PARAMS); PrincipalComparator pc = (PrincipalComparator)c.newInstance - (new Object[] { pppe.principalName }); + (new Object[] { pppe.getPrincipalName() }); if (!pc.implies(that.getSubject())) { if (debug != null) @@ -236,11 +236,10 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { Iterator i = that.getSubject().getPrincipals().iterator(); - subjectList = new LinkedList(); + subjectList = new LinkedList(); while (i.hasNext()) { Principal p = i.next(); - PolicyParser.PrincipalEntry spppe = - new PolicyParser.PrincipalEntry + PrincipalEntry spppe = new PrincipalEntry (p.getClass().getName(), p.getName()); subjectList.add(spppe); } @@ -281,23 +280,19 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { * pppe argument. */ private boolean subjectListImpliesPrincipalEntry( - LinkedList subjectList, - PolicyParser.PrincipalEntry pppe) { + LinkedList subjectList, PrincipalEntry pppe) { - ListIterator li = - subjectList.listIterator(0); + ListIterator li = subjectList.listIterator(0); while (li.hasNext()) { - PolicyParser.PrincipalEntry listPppe = li.next(); + PrincipalEntry listPppe = li.next(); - if (pppe.principalClass.equals - (PolicyParser.PrincipalEntry.WILDCARD_CLASS) || - pppe.principalClass.equals - (listPppe.principalClass)) { - - if (pppe.principalName.equals - (PolicyParser.PrincipalEntry.WILDCARD_NAME) || - pppe.principalName.equals - (listPppe.principalName)) + if (pppe.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) || + pppe.getPrincipalClass().equals(listPppe.getPrincipalClass())) + { + if (pppe.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME) || + pppe.getPrincipalName().equals(listPppe.getPrincipalName())) return true; } } @@ -390,13 +385,12 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { } } if (principals != null) { - ListIterator li = - principals.listIterator(); + ListIterator li = principals.listIterator(); while (li.hasNext()) { - PolicyParser.PrincipalEntry pppe = li.next(); + PrincipalEntry pppe = li.next(); returnMe = returnMe + rb.getString("NEWLINE") + - pppe.principalClass + " " + - pppe.principalName; + pppe.getPrincipalClass() + " " + + pppe.getPrincipalName(); } } return returnMe; From 10f964a32464c5c751bfeeec942d3c9a69fc418b Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 6 Aug 2013 16:01:39 -0700 Subject: [PATCH 28/39] 8022406: Fix doclint issues in java.beans Reviewed-by: prr --- .../classes/java/beans/AppletInitializer.java | 3 +- jdk/src/share/classes/java/beans/Beans.java | 9 ++-- .../java/beans/ConstructorProperties.java | 4 +- .../beans/DefaultPersistenceDelegate.java | 3 +- .../classes/java/beans/EventHandler.java | 5 ++- .../share/classes/java/beans/Expression.java | 6 ++- .../java/beans/IndexedPropertyDescriptor.java | 4 ++ .../classes/java/beans/Introspector.java | 13 +++++- .../java/beans/PersistenceDelegate.java | 3 +- .../java/beans/PropertyChangeSupport.java | 6 +-- .../java/beans/PropertyDescriptor.java | 2 + .../share/classes/java/beans/Transient.java | 12 ++++-- .../java/beans/VetoableChangeSupport.java | 10 ++--- .../java/beans/beancontext/BeanContext.java | 14 +++--- .../beans/beancontext/BeanContextChild.java | 4 +- .../beancontext/BeanContextChildSupport.java | 6 ++- .../BeanContextMembershipEvent.java | 3 +- .../beancontext/BeanContextServices.java | 5 ++- .../BeanContextServicesSupport.java | 27 ++++++++++-- .../beans/beancontext/BeanContextSupport.java | 43 ++++++++++++++----- 20 files changed, 130 insertions(+), 52 deletions(-) diff --git a/jdk/src/share/classes/java/beans/AppletInitializer.java b/jdk/src/share/classes/java/beans/AppletInitializer.java index 9e4b7239d61..2c271a236ca 100644 --- a/jdk/src/share/classes/java/beans/AppletInitializer.java +++ b/jdk/src/share/classes/java/beans/AppletInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -68,7 +68,6 @@ public interface AppletInitializer { * the Applet with its Container during the subsequent invocation of its * addChildren() method. * - *

    * * @param newAppletBean The newly instantiated JavaBean * @param bCtxt The BeanContext intended for this Applet, or diff --git a/jdk/src/share/classes/java/beans/Beans.java b/jdk/src/share/classes/java/beans/Beans.java index 2183d224167..58a411691fd 100644 --- a/jdk/src/share/classes/java/beans/Beans.java +++ b/jdk/src/share/classes/java/beans/Beans.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -62,7 +62,7 @@ public class Beans { *

    * Instantiate a JavaBean. *

    - * + * @return a JavaBean * @param cls the class-loader from which we should create * the bean. If this is null, then the system * class-loader is used. @@ -82,6 +82,7 @@ public class Beans { *

    * Instantiate a JavaBean. *

    + * @return a JavaBean * * @param cls the class-loader from which we should create * the bean. If this is null, then the system @@ -137,6 +138,7 @@ public class Beans { * the JDK appletviewer (for a reference browser environment) and the * BDK BeanBox (for a reference bean container). * + * @return a JavaBean * @param cls the class-loader from which we should create * the bean. If this is null, then the system * class-loader is used. @@ -361,6 +363,8 @@ public class Beans { * This method is provided in Beans 1.0 as a hook to allow the * addition of more flexible bean behaviour in the future. * + * @return an object representing a specified type view of the + * source object * @param bean Object from which we want to obtain a view. * @param targetType The type of view we'd like to get. * @@ -384,7 +388,6 @@ public class Beans { return Introspector.isSubclass(bean.getClass(), targetType); } - /** * Test if we are in design-mode. * diff --git a/jdk/src/share/classes/java/beans/ConstructorProperties.java b/jdk/src/share/classes/java/beans/ConstructorProperties.java index 3166de31747..5ee947c1f1c 100644 --- a/jdk/src/share/classes/java/beans/ConstructorProperties.java +++ b/jdk/src/share/classes/java/beans/ConstructorProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, 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 @@ -61,7 +61,7 @@ import static java.lang.annotation.RetentionPolicy.*; the {@code getY()} method. Since parameter names are not in general available at runtime, without the annotation there would be no way to know whether the parameters correspond to {@code getX()} - and {@code getY()} or the other way around.

    + and {@code getY()} or the other way around. @since 1.6 */ diff --git a/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java b/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java index 3c6c7c2a3d3..de6a1b75178 100644 --- a/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java +++ b/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -382,6 +382,7 @@ public class DefaultPersistenceDelegate extends PersistenceDelegate { * a class such that no property value depends on the value of * a subsequent property. * + * @param type the type of the instances * @param oldInstance The instance to be copied. * @param newInstance The instance that is to be modified. * @param out The stream to which any initialization statements should be written. diff --git a/jdk/src/share/classes/java/beans/EventHandler.java b/jdk/src/share/classes/java/beans/EventHandler.java index b7635c931b7..b428f2892a1 100644 --- a/jdk/src/share/classes/java/beans/EventHandler.java +++ b/jdk/src/share/classes/java/beans/EventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -515,6 +515,7 @@ public class EventHandler implements InvocationHandler { * * * + * @param the type to create * @param listenerInterface the listener interface to create a proxy for * @param target the object that will perform the action * @param action the name of a (possibly qualified) property or method on @@ -570,6 +571,7 @@ public class EventHandler implements InvocationHandler { * * * + * @param the type to create * @param listenerInterface the listener interface to create a proxy for * @param target the object that will perform the action * @param action the name of a (possibly qualified) property or method on @@ -659,6 +661,7 @@ public class EventHandler implements InvocationHandler { * * * + * @param the type to create * @param listenerInterface the listener interface to create a proxy for * @param target the object that will perform the action * @param action the name of a (possibly qualified) property or method on diff --git a/jdk/src/share/classes/java/beans/Expression.java b/jdk/src/share/classes/java/beans/Expression.java index f7a15c3464a..ce6fafb104e 100644 --- a/jdk/src/share/classes/java/beans/Expression.java +++ b/jdk/src/share/classes/java/beans/Expression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -139,7 +139,7 @@ public class Expression extends Statement { * replaces this default value in the same way that any other value * would, ensuring that expressions are never evaluated more than once. *

    - * See the excecute method for details on how + * See the execute method for details on how * methods are chosen using the dynamic types of the target * and arguments. * @@ -147,6 +147,8 @@ public class Expression extends Statement { * @see #setValue * * @return The result of applying this method to these arguments. + * @throws Exception if the method with the specified methodName + * throws an exception */ public Object getValue() throws Exception { if (value == unbound) { diff --git a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java index d3f16d2901e..1d59f7afddb 100644 --- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java +++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java @@ -207,6 +207,8 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { * Sets the method that should be used to read an indexed property value. * * @param readMethod The new indexed read method. + * @throws IntrospectionException if an exception occurs during + * introspection. */ public synchronized void setIndexedReadMethod(Method readMethod) throws IntrospectionException { @@ -285,6 +287,8 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { * Sets the method that should be used to write an indexed property value. * * @param writeMethod The new indexed write method. + * @throws IntrospectionException if an exception occurs during + * introspection. */ public synchronized void setIndexedWriteMethod(Method writeMethod) throws IntrospectionException { diff --git a/jdk/src/share/classes/java/beans/Introspector.java b/jdk/src/share/classes/java/beans/Introspector.java index 783fcbef315..acc0f77f389 100644 --- a/jdk/src/share/classes/java/beans/Introspector.java +++ b/jdk/src/share/classes/java/beans/Introspector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -93,8 +93,17 @@ import sun.reflect.misc.ReflectUtil; public class Introspector { // Flags that can be used to control getBeanInfo: + /** + * Flag to indicate to use of all beaninfo. + */ public final static int USE_ALL_BEANINFO = 1; + /** + * Flag to indicate to ignore immediate beaninfo. + */ public final static int IGNORE_IMMEDIATE_BEANINFO = 2; + /** + * Flag to indicate to ignore all beaninfo. + */ public final static int IGNORE_ALL_BEANINFO = 3; // Static Caches to speed up introspection. @@ -202,7 +211,7 @@ public class Introspector { * If the BeanInfo class for a Java Bean has been previously Introspected * based on the same arguments, then the BeanInfo class is retrieved * from the BeanInfo cache. - * + * @return the BeanInfo for the bean * @param beanClass The bean class to be analyzed. * @param stopClass The baseclass at which to stop the analysis. Any * methods/properties/events in the stopClass or in its baseclasses diff --git a/jdk/src/share/classes/java/beans/PersistenceDelegate.java b/jdk/src/share/classes/java/beans/PersistenceDelegate.java index 01c5bb12387..bbdcdbf060c 100644 --- a/jdk/src/share/classes/java/beans/PersistenceDelegate.java +++ b/jdk/src/share/classes/java/beans/PersistenceDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -197,6 +197,7 @@ public abstract class PersistenceDelegate { * The default implementation, calls the initialize * method of the type's superclass. * + * @param type the type of the instances * @param oldInstance The instance to be copied. * @param newInstance The instance that is to be modified. * @param out The stream to which any initialization statements should be written. diff --git a/jdk/src/share/classes/java/beans/PropertyChangeSupport.java b/jdk/src/share/classes/java/beans/PropertyChangeSupport.java index c3c73179b1a..d55ae76efc8 100644 --- a/jdk/src/share/classes/java/beans/PropertyChangeSupport.java +++ b/jdk/src/share/classes/java/beans/PropertyChangeSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -156,7 +156,7 @@ public class PropertyChangeSupport implements Serializable { * PropertyChangeListenerProxy, perform the cast, and examine * the parameter. * - *

    +     * 
    {@code
          * PropertyChangeListener[] listeners = bean.getPropertyChangeListeners();
          * for (int i = 0; i < listeners.length; i++) {
          *   if (listeners[i] instanceof PropertyChangeListenerProxy) {
    @@ -168,7 +168,7 @@ public class PropertyChangeSupport implements Serializable {
          *     }
          *   }
          * }
    -     *
    + * }
    * * @see PropertyChangeListenerProxy * @return all of the PropertyChangeListeners added or an diff --git a/jdk/src/share/classes/java/beans/PropertyDescriptor.java b/jdk/src/share/classes/java/beans/PropertyDescriptor.java index 0abdcad972b..c519b504d58 100644 --- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java +++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java @@ -243,6 +243,7 @@ public class PropertyDescriptor extends FeatureDescriptor { * Sets the method that should be used to read the property value. * * @param readMethod The new read method. + * @throws IntrospectionException if the read method is invalid */ public synchronized void setReadMethod(Method readMethod) throws IntrospectionException { @@ -313,6 +314,7 @@ public class PropertyDescriptor extends FeatureDescriptor { * Sets the method that should be used to write the property value. * * @param writeMethod The new write method. + * @throws IntrospectionException if the write method is invalid */ public synchronized void setWriteMethod(Method writeMethod) throws IntrospectionException { diff --git a/jdk/src/share/classes/java/beans/Transient.java b/jdk/src/share/classes/java/beans/Transient.java index 0a2761ce8b9..165621b39fd 100644 --- a/jdk/src/share/classes/java/beans/Transient.java +++ b/jdk/src/share/classes/java/beans/Transient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2013, 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 @@ -40,7 +40,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * A {@code true} value for the "transient" attribute * indicates to encoders derived from {@link Encoder} * that this feature should be ignored. - *

    + *

    * The {@code Transient} annotation may be be used * in any of the methods that are involved * in a {@link FeatureDescriptor} subclass @@ -49,7 +49,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * to put the annotation and it is this declaration * that takes precedence in the case of multiple annotations * being defined for the same feature. - *

    + *

    * To declare a feature non-transient in a class * whose superclass declares it transient, * use {@code @Transient(false)}. @@ -64,5 +64,11 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({METHOD}) @Retention(RUNTIME) public @interface Transient { + /** + * Returns whether or not the {@code Introspector} should + * construct artifacts for the annotated method. + * @return whether or not the {@code Introspector} should + * construct artifacts for the annotated method + */ boolean value() default true; } diff --git a/jdk/src/share/classes/java/beans/VetoableChangeSupport.java b/jdk/src/share/classes/java/beans/VetoableChangeSupport.java index 6b7e268eba7..293ae5af2c6 100644 --- a/jdk/src/share/classes/java/beans/VetoableChangeSupport.java +++ b/jdk/src/share/classes/java/beans/VetoableChangeSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -42,7 +42,7 @@ import java.util.Map.Entry; *

    * Here is an example of {@code VetoableChangeSupport} usage that follows * the rules and recommendations laid out in the JavaBeans™ specification: - *

    + * 
    {@code
      * public class MyBean {
      *     private final VetoableChangeSupport vcs = new VetoableChangeSupport(this);
      *
    @@ -68,7 +68,7 @@ import java.util.Map.Entry;
      *
      *     [...]
      * }
    - * 
    + * }
    *

    * A {@code VetoableChangeSupport} instance is thread-safe. *

    @@ -156,7 +156,7 @@ public class VetoableChangeSupport implements Serializable { * VetoableChangeListenerProxy, perform the cast, and examine * the parameter. * - *

    +     * 
    {@code
          * VetoableChangeListener[] listeners = bean.getVetoableChangeListeners();
          * for (int i = 0; i < listeners.length; i++) {
          *        if (listeners[i] instanceof VetoableChangeListenerProxy) {
    @@ -168,7 +168,7 @@ public class VetoableChangeSupport implements Serializable {
          *     }
          *   }
          * }
    -     *
    + * }
    * * @see VetoableChangeListenerProxy * @return all of the VetoableChangeListeners added or an diff --git a/jdk/src/share/classes/java/beans/beancontext/BeanContext.java b/jdk/src/share/classes/java/beans/beancontext/BeanContext.java index c6217289faf..308147b9e3c 100644 --- a/jdk/src/share/classes/java/beans/beancontext/BeanContext.java +++ b/jdk/src/share/classes/java/beans/beancontext/BeanContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -64,10 +64,12 @@ public interface BeanContext extends BeanContextChild, Collection, DesignMode, V * and is defined by the * java.beans.Beans.instantiate() method. * + * @return a javaBean named as a child of this + * BeanContext * @param beanName The name of the JavaBean to instantiate * as a child of this BeanContext - * @throws IOException - * @throws ClassNotFoundException if the class identified + * @throws IOException if an IO problem occurs + * @throws ClassNotFoundException if the class identified * by the beanName parameter is not found */ Object instantiateChild(String beanName) throws IOException, ClassNotFoundException; @@ -83,7 +85,7 @@ public interface BeanContext extends BeanContextChild, Collection, DesignMode, V * @return an InputStream for reading the resource, * or null if the resource could not * be found. - * @throws IllegalArgumentException if + * @throws IllegalArgumentException if * the resource is not valid */ InputStream getResourceAsStream(String name, BeanContextChild bcc) throws IllegalArgumentException; @@ -98,7 +100,7 @@ public interface BeanContext extends BeanContextChild, Collection, DesignMode, V * @param bcc the specified child * @return a URL for the named * resource for the specified child - * @throws IllegalArgumentException + * @throws IllegalArgumentException * if the resource is not valid */ URL getResource(String name, BeanContextChild bcc) throws IllegalArgumentException; @@ -109,7 +111,7 @@ public interface BeanContext extends BeanContextChild, Collection, DesignMode, V * this BeanContext whenever it adds * or removes a child Component(s). * - * @param bcml the BeanContextMembershipListener to be added + * @param bcml the BeanContextMembershipListener to be added */ void addBeanContextMembershipListener(BeanContextMembershipListener bcml); diff --git a/jdk/src/share/classes/java/beans/beancontext/BeanContextChild.java b/jdk/src/share/classes/java/beans/beancontext/BeanContextChild.java index 841e3ccbc5e..e84b7a7eeb5 100644 --- a/jdk/src/share/classes/java/beans/beancontext/BeanContextChild.java +++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextChild.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -82,7 +82,7 @@ public interface BeanContextChild { *

    * @param bc The BeanContext with which * to associate this BeanContextChild. - * @throws PropertyVetoException if the + * @throws PropertyVetoException if the * addition of the specified BeanContext is refused. */ void setBeanContext(BeanContext bc) throws PropertyVetoException; diff --git a/jdk/src/share/classes/java/beans/beancontext/BeanContextChildSupport.java b/jdk/src/share/classes/java/beans/beancontext/BeanContextChildSupport.java index 056913b654a..b2b855867b5 100644 --- a/jdk/src/share/classes/java/beans/beancontext/BeanContextChildSupport.java +++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextChildSupport.java @@ -78,6 +78,7 @@ public class BeanContextChildSupport implements BeanContextChild, BeanContextSer * construct a BeanContextChildSupport where the JavaBean component * itself implements BeanContextChild, and encapsulates this, delegating * that interface to this implementation + * @param bcc the underlying bean context child */ public BeanContextChildSupport(BeanContextChild bcc) { @@ -94,7 +95,7 @@ public class BeanContextChildSupport implements BeanContextChild, BeanContextSer * this BeanContextChildSupport. * @param bc the new value to be assigned to the BeanContext * property - * @throws PropertyVetoException if the change is rejected + * @throws PropertyVetoException if the change is rejected */ public synchronized void setBeanContext(BeanContext bc) throws PropertyVetoException { if (bc == beanContext) return; @@ -361,6 +362,9 @@ public class BeanContextChildSupport implements BeanContextChild, BeanContextSer */ protected VetoableChangeSupport vcSupport; + /** + * The bean context. + */ protected transient BeanContext beanContext; /** diff --git a/jdk/src/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java b/jdk/src/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java index 6b5f4f5609c..24406d4e7db 100644 --- a/jdk/src/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java +++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -103,6 +103,7 @@ public class BeanContextMembershipEvent extends BeanContextEvent { * Is the child specified affected by the event? * @return true if affected, false * if not + * @param child the object to check for being affected */ public boolean contains(Object child) { return children.contains(child); diff --git a/jdk/src/share/classes/java/beans/beancontext/BeanContextServices.java b/jdk/src/share/classes/java/beans/beancontext/BeanContextServices.java index 168056c260d..0348817bfe8 100644 --- a/jdk/src/share/classes/java/beans/beancontext/BeanContextServices.java +++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextServices.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -60,6 +60,7 @@ public interface BeanContextServices extends BeanContext, BeanContextServicesLis * @param serviceClass the service to add * @param serviceProvider the BeanContextServiceProvider * associated with the service + * @return true if the service was successful added, false otherwise */ boolean addService(Class serviceClass, BeanContextServiceProvider serviceProvider); @@ -108,7 +109,7 @@ public interface BeanContextServices extends BeanContext, BeanContextServicesLis * @param bcsrl the * BeanContextServiceRevokedListener to notify * if the service should later become revoked - * @throws TooManyListenersException + * @throws TooManyListenersException if there are too many listeners * @return a reference to this context's named * Service as requested or null */ diff --git a/jdk/src/share/classes/java/beans/beancontext/BeanContextServicesSupport.java b/jdk/src/share/classes/java/beans/beancontext/BeanContextServicesSupport.java index 94d104b14bd..ca0942efef9 100644 --- a/jdk/src/share/classes/java/beans/beancontext/BeanContextServicesSupport.java +++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextServicesSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -603,12 +603,16 @@ public class BeanContextServicesSupport extends BeanContextSupport serviceProvider = bcsp; } + /** + * Returns the service provider. + * @return the service provider + */ protected BeanContextServiceProvider getServiceProvider() { return serviceProvider; } - /* - * fields + /** + * The service provider. */ protected BeanContextServiceProvider serviceProvider; @@ -618,6 +622,9 @@ public class BeanContextServicesSupport extends BeanContextSupport * subclasses can override this method to create new subclasses of * BCSSServiceProvider without having to overrride addService() in * order to instantiate. + * @param sc the class + * @param bcsp the service provider + * @return a service provider without overriding addService() */ protected BCSSServiceProvider createBCSSServiceProvider(Class sc, BeanContextServiceProvider bcsp) { @@ -629,7 +636,7 @@ public class BeanContextServicesSupport extends BeanContextSupport /** * add a BeanContextServicesListener * - * @throws NullPointerException + * @throws NullPointerException if the argument is null */ public void addBeanContextServicesListener(BeanContextServicesListener bcsl) { @@ -660,6 +667,8 @@ public class BeanContextServicesSupport extends BeanContextSupport /** * add a service + * @param serviceClass the service class + * @param bcsp the service provider */ public boolean addService(Class serviceClass, BeanContextServiceProvider bcsp) { @@ -668,6 +677,10 @@ public class BeanContextServicesSupport extends BeanContextSupport /** * add a service + * @param serviceClass the service class + * @param bcsp the service provider + * @param fireEvent whether or not an event should be fired + * @return true if the service was successfully added */ protected boolean addService(Class serviceClass, BeanContextServiceProvider bcsp, boolean fireEvent) { @@ -709,6 +722,9 @@ public class BeanContextServicesSupport extends BeanContextSupport /** * remove a service + * @param serviceClass the service class + * @param bcsp the service provider + * @param revokeCurrentServicesNow whether or not to revoke the service */ public void revokeService(Class serviceClass, BeanContextServiceProvider bcsp, boolean revokeCurrentServicesNow) { @@ -1067,6 +1083,7 @@ public class BeanContextServicesSupport extends BeanContextSupport /** * Fires a BeanContextServiceEvent notifying of a new service. + * @param serviceClass the service class */ protected final void fireServiceAdded(Class serviceClass) { BeanContextServiceAvailableEvent bcssae = new BeanContextServiceAvailableEvent(getBeanContextServicesPeer(), serviceClass); @@ -1109,6 +1126,8 @@ public class BeanContextServicesSupport extends BeanContextSupport * Fires a BeanContextServiceRevokedEvent * indicating that a particular service is * no longer available. + * @param serviceClass the service class + * @param revokeNow whether or not the event should be revoked now */ protected final void fireServiceRevoked(Class serviceClass, boolean revokeNow) { Object[] copy; diff --git a/jdk/src/share/classes/java/beans/beancontext/BeanContextSupport.java b/jdk/src/share/classes/java/beans/beancontext/BeanContextSupport.java index 85b1a5a292f..a549e2dc317 100644 --- a/jdk/src/share/classes/java/beans/beancontext/BeanContextSupport.java +++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -62,7 +62,6 @@ import java.util.Map; /** * This helper class provides a utility implementation of the * java.beans.beancontext.BeanContext interface. - *

    *

    * Since this class directly implements the BeanContext interface, the class * can, and is intended to be used either by subclassing this implementation, @@ -351,9 +350,8 @@ public class BeanContextSupport extends BeanContextChildSupport * of Child without having to override add() or the other Collection * methods that add children to the set. *

    - * * @param targetChild the child to create the Child on behalf of - * @param peer the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy + * @param peer the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy * @return Subtype-specific subclass of Child without overriding collection methods */ protected BCSChild createBCSChild(Object targetChild, Object peer) { @@ -492,6 +490,7 @@ public class BeanContextSupport extends BeanContextChildSupport * @param callChildSetBC used to indicate that * the child should be notified that it is no * longer nested in this BeanContext. + * @return whether or not was present before being removed */ protected boolean remove(Object targetChild, boolean callChildSetBC) { @@ -580,7 +579,8 @@ public class BeanContextSupport extends BeanContextChildSupport /** * add Collection to set of Children (Unsupported) * implementations must synchronized on the hierarchy lock and "children" protected field - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException thrown unconditionally by this implementation + * @return this implementation unconditionally throws {@code UnsupportedOperationException} */ public boolean addAll(Collection c) { throw new UnsupportedOperationException(); @@ -589,7 +589,9 @@ public class BeanContextSupport extends BeanContextChildSupport /** * remove all specified children (Unsupported) * implementations must synchronized on the hierarchy lock and "children" protected field - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException thrown unconditionally by this implementation + * @return this implementation unconditionally throws {@code UnsupportedOperationException} + */ public boolean removeAll(Collection c) { throw new UnsupportedOperationException(); @@ -599,7 +601,8 @@ public class BeanContextSupport extends BeanContextChildSupport /** * retain only specified children (Unsupported) * implementations must synchronized on the hierarchy lock and "children" protected field - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException thrown unconditionally by this implementation + * @return this implementation unconditionally throws {@code UnsupportedOperationException} */ public boolean retainAll(Collection c) { throw new UnsupportedOperationException(); @@ -608,7 +611,7 @@ public class BeanContextSupport extends BeanContextChildSupport /** * clear the children (Unsupported) * implementations must synchronized on the hierarchy lock and "children" protected field - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException thrown unconditionally by this implementation */ public void clear() { throw new UnsupportedOperationException(); @@ -618,7 +621,7 @@ public class BeanContextSupport extends BeanContextChildSupport * Adds a BeanContextMembershipListener * * @param bcml the BeanContextMembershipListener to add - * @throws NullPointerException + * @throws NullPointerException if the argument is null */ public void addBeanContextMembershipListener(BeanContextMembershipListener bcml) { @@ -636,7 +639,7 @@ public class BeanContextSupport extends BeanContextChildSupport * Removes a BeanContextMembershipListener * * @param bcml the BeanContextMembershipListener to remove - * @throws NullPointerException + * @throws NullPointerException if the argument is null */ public void removeBeanContextMembershipListener(BeanContextMembershipListener bcml) { @@ -655,7 +658,7 @@ public class BeanContextSupport extends BeanContextChildSupport * @param bcc the child object making the request. * * @return the requested resource as an InputStream - * @throws NullPointerException + * @throws NullPointerException if the argument is null */ public InputStream getResourceAsStream(String name, BeanContextChild bcc) { @@ -849,6 +852,8 @@ public class BeanContextSupport extends BeanContextChildSupport * * This method should not however be used by subclasses to replace their * own implementation (if any) of writeObject(). + * @param oos the {@code ObjectOutputStream} to use during serialization + * @throws IOException if serialization failed */ protected void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException { @@ -864,6 +869,9 @@ public class BeanContextSupport extends BeanContextChildSupport * * This method should not however be used by subclasses to replace their * own implementation (if any) of readObject(). + * @param ois the {@code ObjectInputStream} to use during deserialization + * @throws IOException if deserialization failed + * @throws ClassNotFoundException if needed classes are not found */ protected void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException, ClassNotFoundException { @@ -914,6 +922,8 @@ public class BeanContextSupport extends BeanContextChildSupport * used by readObject to deserialize a collection. * @param ois the ObjectInputStream to use * @param coll the Collection + * @throws IOException if deserialization failed + * @throws ClassNotFoundException if needed classes are not found */ protected final void deserialize(ObjectInputStream ois, Collection coll) throws IOException, ClassNotFoundException { int count = 0; @@ -1005,6 +1015,9 @@ public class BeanContextSupport extends BeanContextChildSupport * When an instance of this class is used as a delegate for the * implementation of the BeanContext protocols (and its subprotocols) * there exists a 'chicken and egg' problem during deserialization + * @param ois the ObjectInputStream to use + * @throws IOException if deserialization failed + * @throws ClassNotFoundException if needed classes are not found */ public final void readChildren(ObjectInputStream ois) throws IOException, ClassNotFoundException { @@ -1122,6 +1135,7 @@ public class BeanContextSupport extends BeanContextChildSupport * immediately prior to their being added to the BeanContext. *

    * + * @param targetChild the child to create the Child on behalf of * @return true iff the child may be added to this BeanContext, otherwise false. */ @@ -1136,6 +1150,7 @@ public class BeanContextSupport extends BeanContextChildSupport * immediately prior to their being removed from the BeanContext. *

    * + * @param targetChild the child to create the Child on behalf of * @return true iff the child may be removed from this BeanContext, otherwise false. */ @@ -1147,6 +1162,8 @@ public class BeanContextSupport extends BeanContextChildSupport * subclasses may override this method to simply extend add() semantics * after the child has been added and before the event notification has * occurred. The method is called with the child synchronized. + * @param child the child + * @param bcsc the BCSChild */ protected void childJustAddedHook(Object child, BCSChild bcsc) { @@ -1156,6 +1173,8 @@ public class BeanContextSupport extends BeanContextChildSupport * subclasses may override this method to simply extend remove() semantics * after the child has been removed and before the event notification has * occurred. The method is called with the child synchronized. + * @param child the child + * @param bcsc the BCSChild */ protected void childJustRemovedHook(Object child, BCSChild bcsc) { @@ -1254,6 +1273,7 @@ public class BeanContextSupport extends BeanContextChildSupport /** * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface + * @param bcme the event to fire */ protected final void fireChildrenAdded(BeanContextMembershipEvent bcme) { @@ -1267,6 +1287,7 @@ public class BeanContextSupport extends BeanContextChildSupport /** * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface + * @param bcme the event to fire */ protected final void fireChildrenRemoved(BeanContextMembershipEvent bcme) { From e11ec149ced43f1ac5fac7f4ab3bba94d5ce0703 Mon Sep 17 00:00:00 2001 From: Brian Goetz Date: Fri, 28 Jun 2013 16:26:54 -0400 Subject: [PATCH 29/39] 8015318: Extend Collector with 'finish' operation Reviewed-by: mduigou --- .../java/util/DoubleSummaryStatistics.java | 15 +- .../java/util/IntSummaryStatistics.java | 15 +- .../java/util/LongSummaryStatistics.java | 17 +- .../share/classes/java/util/StringJoiner.java | 7 +- .../classes/java/util/stream/Collector.java | 222 +++-- .../classes/java/util/stream/Collectors.java | 865 ++++++++++-------- .../java/util/stream/DelegatingStream.java | 2 +- .../java/util/stream/DoubleStream.java | 2 +- .../classes/java/util/stream/IntStream.java | 2 +- .../classes/java/util/stream/LongStream.java | 2 +- .../classes/java/util/stream/ReduceOps.java | 22 +- .../java/util/stream/ReferencePipeline.java | 17 +- .../classes/java/util/stream/Stream.java | 3 +- .../java/util/stream/package-info.java | 4 +- .../tests/java/util/FillableStringTest.java | 6 +- .../tests/java/util/stream/GroupByOpTest.java | 12 +- .../util/stream/SummaryStatisticsTest.java | 12 +- .../java/util/stream/TabulatorsTest.java | 222 ++++- .../MethodReferenceTestInstanceMethod.java | 2 +- jdk/test/jdk/lambda/separate/TestHarness.java | 4 +- 20 files changed, 909 insertions(+), 544 deletions(-) diff --git a/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java b/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java index fb79c56660b..63c887e23ce 100644 --- a/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java +++ b/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java @@ -25,6 +25,7 @@ package java.util; import java.util.function.DoubleConsumer; +import java.util.stream.Collector; /** * A state object for collecting statistics such as count, min, max, sum, and @@ -35,24 +36,24 @@ import java.util.function.DoubleConsumer; * summary statistics on a stream of doubles with: *
     {@code
      * DoubleSummaryStatistics stats = doubleStream.collect(DoubleSummaryStatistics::new,
    - *     DoubleSummaryStatistics::accept,
    - *     DoubleSummaryStatistics::combine);
    + *                                                      DoubleSummaryStatistics::accept,
    + *                                                      DoubleSummaryStatistics::combine);
      * }
    * *

    {@code DoubleSummaryStatistics} can be used as a - * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction} + * {@linkplain java.util.stream.Stream#collect(Collector) reduction} * target for a {@linkplain java.util.stream.Stream stream}. For example: * *

     {@code
      * DoubleSummaryStatistics stats = people.stream()
    - *     .collect(Collectors.toDoubleSummaryStatistics(Person::getWeight));
    + *     .collect(Collectors.summarizingDouble(Person::getWeight));
      *}
    * * This computes, in a single pass, the count of people, as well as the minimum, * maximum, sum, and average of their weights. * * @implNote This implementation is not thread safe. However, it is safe to use - * {@link java.util.stream.Collectors#toDoubleSummaryStatistics(java.util.function.ToDoubleFunction) + * {@link java.util.stream.Collectors#summarizingDouble(java.util.function.ToDoubleFunction) * Collectors.toDoubleStatistics()} on a parallel stream, because the parallel * implementation of {@link java.util.stream.Stream#collect Stream.collect()} * provides the necessary partitioning, isolation, and merging of results for @@ -152,7 +153,7 @@ public class DoubleSummaryStatistics implements DoubleConsumer { } /** - * Returns the average of values recorded, or zero if no values have been + * Returns the arithmetic mean of values recorded, or zero if no values have been * recorded. The average returned can vary depending upon the order in * which values are recorded. This is due to accumulated rounding error in * addition of values of differing magnitudes. Values sorted by increasing @@ -160,7 +161,7 @@ public class DoubleSummaryStatistics implements DoubleConsumer { * value is a {@code NaN} or the sum is at any point a {@code NaN} then the * average will be {@code NaN}. * - * @return the average of values, or zero if none + * @return the arithmetic mean of values, or zero if none */ public final double getAverage() { return getCount() > 0 ? getSum() / getCount() : 0.0d; diff --git a/jdk/src/share/classes/java/util/IntSummaryStatistics.java b/jdk/src/share/classes/java/util/IntSummaryStatistics.java index fcca3296f85..f93436e7017 100644 --- a/jdk/src/share/classes/java/util/IntSummaryStatistics.java +++ b/jdk/src/share/classes/java/util/IntSummaryStatistics.java @@ -25,6 +25,7 @@ package java.util; import java.util.function.IntConsumer; +import java.util.stream.Collector; /** * A state object for collecting statistics such as count, min, max, sum, and @@ -35,24 +36,24 @@ import java.util.function.IntConsumer; * summary statistics on a stream of ints with: *
     {@code
      * IntSummaryStatistics stats = intStream.collect(IntSummaryStatistics::new,
    - *     IntSummaryStatistics::accept,
    - *     IntSummaryStatistics::combine);
    + *                                                IntSummaryStatistics::accept,
    + *                                                IntSummaryStatistics::combine);
      * }
    * *

    {@code IntSummaryStatistics} can be used as a - * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction} + * {@linkplain java.util.stream.Stream#collect(Collector) reduction} * target for a {@linkplain java.util.stream.Stream stream}. For example: * *

     {@code
      * IntSummaryStatistics stats = people.stream()
    - *     .collect(Collectors.toIntSummaryStatistics(Person::getDependents));
    + *                                    .collect(Collectors.summarizingInt(Person::getDependents));
      *}
    * * This computes, in a single pass, the count of people, as well as the minimum, * maximum, sum, and average of their number of dependents. * * @implNote This implementation is not thread safe. However, it is safe to use - * {@link java.util.stream.Collectors#toIntSummaryStatistics(java.util.function.ToIntFunction) + * {@link java.util.stream.Collectors#summarizingInt(java.util.function.ToIntFunction) * Collectors.toIntStatistics()} on a parallel stream, because the parallel * implementation of {@link java.util.stream.Stream#collect Stream.collect()} * provides the necessary partitioning, isolation, and merging of results for @@ -140,10 +141,10 @@ public class IntSummaryStatistics implements IntConsumer { } /** - * Returns the average of values recorded, or zero if no values have been + * Returns the arithmetic mean of values recorded, or zero if no values have been * recorded. * - * @return the average of values, or zero if none + * @return the arithmetic mean of values, or zero if none */ public final double getAverage() { return getCount() > 0 ? (double) getSum() / getCount() : 0.0d; diff --git a/jdk/src/share/classes/java/util/LongSummaryStatistics.java b/jdk/src/share/classes/java/util/LongSummaryStatistics.java index 0e2da71f8bc..085aa298075 100644 --- a/jdk/src/share/classes/java/util/LongSummaryStatistics.java +++ b/jdk/src/share/classes/java/util/LongSummaryStatistics.java @@ -26,6 +26,7 @@ package java.util; import java.util.function.IntConsumer; import java.util.function.LongConsumer; +import java.util.stream.Collector; /** * A state object for collecting statistics such as count, min, max, sum, and @@ -36,24 +37,24 @@ import java.util.function.LongConsumer; * summary statistics on a stream of longs with: *
     {@code
      * LongSummaryStatistics stats = longStream.collect(LongSummaryStatistics::new,
    - *     LongSummaryStatistics::accept,
    - *     LongSummaryStatistics::combine);
    + *                                                  LongSummaryStatistics::accept,
    + *                                                  LongSummaryStatistics::combine);
      * }
    * *

    {@code LongSummaryStatistics} can be used as a - * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction} + * {@linkplain java.util.stream.Stream#collect(Collector)} reduction} * target for a {@linkplain java.util.stream.Stream stream}. For example: * *

     {@code
      * LongSummaryStatistics stats = people.stream()
    - *     .collect(Collectors.toLongSummaryStatistics(Person::getAge));
    + *                                     .collect(Collectors.summarizingLong(Person::getAge));
      *}
    * * This computes, in a single pass, the count of people, as well as the minimum, - * maximum, sum, and average of their ages in milliseconds. + * maximum, sum, and average of their ages. * * @implNote This implementation is not thread safe. However, it is safe to use - * {@link java.util.stream.Collectors#toLongSummaryStatistics(java.util.function.ToLongFunction) + * {@link java.util.stream.Collectors#summarizingLong(java.util.function.ToLongFunction) * Collectors.toLongStatistics()} on a parallel stream, because the parallel * implementation of {@link java.util.stream.Stream#collect Stream.collect()} * provides the necessary partitioning, isolation, and merging of results for @@ -152,10 +153,10 @@ public class LongSummaryStatistics implements LongConsumer, IntConsumer { } /** - * Returns the average of values recorded, or zero if no values have been + * Returns the arithmetic mean of values recorded, or zero if no values have been * recorded. * - * @return The average of values, or zero if none + * @return The arithmetic mean of values, or zero if none */ public final double getAverage() { return getCount() > 0 ? (double) getSum() / getCount() : 0.0d; diff --git a/jdk/src/share/classes/java/util/StringJoiner.java b/jdk/src/share/classes/java/util/StringJoiner.java index 66d49b64f0a..d4050a4afd5 100644 --- a/jdk/src/share/classes/java/util/StringJoiner.java +++ b/jdk/src/share/classes/java/util/StringJoiner.java @@ -49,16 +49,17 @@ package java.util; *

    * A {@code StringJoiner} may be employed to create formatted output from a * {@link java.util.stream.Stream} using - * {@link java.util.stream.Collectors#toStringJoiner}. For example: + * {@link java.util.stream.Collectors#joining(CharSequence)}. For example: * *

     {@code
      * List numbers = Arrays.asList(1, 2, 3, 4);
      * String commaSeparatedNumbers = numbers.stream()
      *     .map(i -> i.toString())
    - *     .collect(Collectors.toStringJoiner(", ")).toString();
    + *     .collect(Collectors.joining(", "));
      * }
    * - * @see java.util.stream.Collectors#toStringJoiner + * @see java.util.stream.Collectors#joining(CharSequence) + * @see java.util.stream.Collectors#joining(CharSequence, CharSequence, CharSequence) * @since 1.8 */ public final class StringJoiner { diff --git a/jdk/src/share/classes/java/util/stream/Collector.java b/jdk/src/share/classes/java/util/stream/Collector.java index 71bb2276f7b..49629176032 100644 --- a/jdk/src/share/classes/java/util/stream/Collector.java +++ b/jdk/src/share/classes/java/util/stream/Collector.java @@ -25,40 +25,45 @@ package java.util.stream; import java.util.Collections; +import java.util.EnumSet; import java.util.Set; -import java.util.function.BiFunction; +import java.util.function.BiConsumer; import java.util.function.BinaryOperator; +import java.util.function.Function; import java.util.function.Supplier; /** * A reduction operation that - * supports folding input elements into a cumulative result. The result may be - * a value or may be a mutable result container. Examples of operations - * accumulating results into a mutable result container include: accumulating - * input elements into a {@code Collection}; concatenating strings into a - * {@code StringBuilder}; computing summary information about elements such as - * sum, min, max, or average; computing "pivot table" summaries such as "maximum - * valued transaction by seller", etc. Reduction operations can be performed - * either sequentially or in parallel. + * folds input elements into a mutable result container, optionally transforming + * the accumulated result into a final representation after all input elements + * have been processed. + * + *

    Examples of mutable reduction operations include: + * accumulating elements into a {@code Collection}; concatenating + * strings using a {@code StringBuilder}; computing summary information about + * elements such as sum, min, max, or average; computing "pivot table" summaries + * such as "maximum valued transaction by seller", etc. Reduction operations + * can be performed either sequentially or in parallel. * *

    The following are examples of using the predefined {@code Collector} * implementations in {@link Collectors} with the {@code Stream} API to perform * mutable reduction tasks: *

    {@code
    - *     // Accumulate elements into a List
    - *     List list = stream.collect(Collectors.toList());
    + *     // Accumulate names into a List
    + *     List list = people.stream().map(Person::getName).collect(Collectors.toList());
      *
    - *     // Accumulate elements into a TreeSet
    - *     Set list = stream.collect(Collectors.toCollection(TreeSet::new));
    + *     // Accumulate names into a TreeSet
    + *     Set list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
      *
      *     // Convert elements to strings and concatenate them, separated by commas
    - *     String joined = stream.map(Object::toString)
    - *                           .collect(Collectors.toStringJoiner(", "))
    - *                           .toString();
    + *     String joined = things.stream()
    + *                           .map(Object::toString)
    + *                           .collect(Collectors.joining(", "));
      *
      *     // Find highest-paid employee
      *     Employee highestPaid = employees.stream()
    - *                                     .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)));
    + *                                     .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)))
    + *                                     .get();
      *
      *     // Group employees by department
      *     Map> byDept
    @@ -66,7 +71,7 @@ import java.util.function.Supplier;
      *                    .collect(Collectors.groupingBy(Employee::getDepartment));
      *
      *     // Find highest-paid employee by department
    - *     Map highestPaidByDept
    + *     Map> highestPaidByDept
      *         = employees.stream()
      *                    .collect(Collectors.groupingBy(Employee::getDepartment,
      *                                                   Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
    @@ -74,43 +79,42 @@ import java.util.function.Supplier;
      *     // Partition students into passing and failing
      *     Map> passingFailing =
      *         students.stream()
    - *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD);
    + *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
      *
      * }
    * - *

    A {@code Collector} is specified by three functions that work together to - * manage a result or result container. They are: creation of an initial - * result, incorporating a new data element into a result, and combining two - * results into one. The last function -- combining two results into one -- is - * used during parallel operations, where subsets of the input are accumulated - * in parallel, and then the subresults merged into a combined result. The - * result may be a mutable container or a value. If the result is mutable, the - * accumulation and combination functions may either mutate their left argument - * and return that (such as adding elements to a collection), or return a new - * result, in which case it should not perform any mutation. + *

    A {@code Collector} is specified by four functions that work together to + * accumulate entries into a mutable result container, and optionally perform + * a final transform on the result. They are: creation of a new result container, + * incorporating a new data element into a result container, combining two + * result containers into one, and performing a final transform on the container. + * The combiner function is used during parallel operations, where + * subsets of the input are accumulated into separate result + * containers, and then the subresults merged into a combined result. The + * combiner function may merge one set of subresults into the other and return + * that, or it may return a new object to describe the combined results. * - *

    Collectors also have a set of characteristics, including - * {@link Characteristics#CONCURRENT} and - * {@link Characteristics#STRICTLY_MUTATIVE}. These characteristics provide + *

    Collectors also have a set of characteristics, such as + * {@link Characteristics#CONCURRENT}. These characteristics provide * hints that can be used by a reduction implementation to provide better * performance. * *

    Libraries that implement reduction based on {@code Collector}, such as * {@link Stream#collect(Collector)}, must adhere to the following constraints: *

    @@ -536,7 +535,7 @@ refer to the following built-in variables. Example: print number of classes that have specific name pattern
     
    -    select count(heap.classes(), "/java.io./(it.name)")
    +    select count(heap.classes(), "/java.io./.test(it.name)")
     
     
    @@ -559,14 +558,14 @@ Examples:
  • show all classes that have java.io.* name pattern
     
    -    select filter(heap.classes(), "/java.io./(it.name)")
    +    select filter(heap.classes(), "/java.io./.test(it.name)")
     
     
  • show all referrers of URL object where the referrer is not from java.net package
     
    -    select filter(referrers(u), "! /java.net./(classof(it).name)")
    +    select filter(referrers(u), "! /java.net./.test(classof(it).name)")
         from java.net.URL u
     
     
    @@ -619,13 +618,13 @@ Examples:
  • find the maximum length of any String instance
     
    -    select max(map(heap.objects('java.lang.String', false), 'it.count'))
    +    select max(map(heap.objects('java.lang.String', false), 'it.value.length'))
     
     
  • find string instance that has the maximum length
     
    -    select max(heap.objects('java.lang.String'), 'lhs.count > rhs.count')
    +    select max(heap.objects('java.lang.String'), 'lhs.value.length > rhs.value.length')
     
     
    @@ -775,7 +774,7 @@ and walk until parent is null using the callback function to map call.
     
    -   select map(filter(heap.findClass('java.lang.System').props.table, 'it != null'), 
    +   select map(filter(heap.findClass('java.lang.System').statics.props.table, 'it != null'), 
                 function (it) {
                     var res = "";
                     while (it != null) {
    
    From 4cb22654f8fba1f118ee435f1a335c742cd8a5e6 Mon Sep 17 00:00:00 2001
    From: Xue-Lei Andrew Fan 
    Date: Wed, 7 Aug 2013 06:42:06 -0700
    Subject: [PATCH 36/39] 8013809: deadlock in SSLSocketImpl between between
     write and close
    
    Reviewed-by: wetmore
    ---
     jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
    index ffa8f4528e8..dfe612966e0 100644
    --- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
    +++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
    @@ -169,7 +169,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
         /*
          * Drives the protocol state machine.
          */
    -    private int                 connectionState;
    +    private volatile int        connectionState;
     
         /*
          * Flag indicating if the next record we receive MUST be a Finished
    @@ -1467,7 +1467,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
          */
         @Override
         public boolean isClosed() {
    -        return getConnectionState() == cs_APP_CLOSED;
    +        return connectionState == cs_APP_CLOSED;
         }
     
         /**
    
    From 5409730fdee8f9d4cfa279c6688d9f76d7fa854e Mon Sep 17 00:00:00 2001
    From: Marcus Lagergren 
    Date: Wed, 7 Aug 2013 08:08:57 -0700
    Subject: [PATCH 37/39] 8022454: Fixed various serializations and deprecation
     warnings in java.util, java.net and sun.tools
    
    Reviewed-by: darcy
    ---
     .../share/classes/java/net/SocketAddress.java |  3 +++
     .../java/util/logging/XMLFormatter.java       | 27 ++++++++++---------
     .../classes/sun/tools/jar/JarException.java   |  3 +++
     3 files changed, 20 insertions(+), 13 deletions(-)
    
    diff --git a/jdk/src/share/classes/java/net/SocketAddress.java b/jdk/src/share/classes/java/net/SocketAddress.java
    index 5cdd4a519cb..a3ee4ee52f5 100644
    --- a/jdk/src/share/classes/java/net/SocketAddress.java
    +++ b/jdk/src/share/classes/java/net/SocketAddress.java
    @@ -39,4 +39,7 @@ package java.net;
      * @since 1.4
      */
     public abstract class SocketAddress implements java.io.Serializable {
    +
    +    static final long serialVersionUID = 5215720748342549866L;
    +
     }
    diff --git a/jdk/src/share/classes/java/util/logging/XMLFormatter.java b/jdk/src/share/classes/java/util/logging/XMLFormatter.java
    index 6b0a58a7130..d32d978dbe5 100644
    --- a/jdk/src/share/classes/java/util/logging/XMLFormatter.java
    +++ b/jdk/src/share/classes/java/util/logging/XMLFormatter.java
    @@ -47,7 +47,7 @@ public class XMLFormatter extends Formatter {
         private LogManager manager = LogManager.getLogManager();
     
         // Append a two digit number.
    -    private void a2(StringBuffer sb, int x) {
    +    private void a2(StringBuilder sb, int x) {
             if (x < 10) {
                 sb.append('0');
             }
    @@ -55,25 +55,26 @@ public class XMLFormatter extends Formatter {
         }
     
         // Append the time and date in ISO 8601 format
    -    private void appendISO8601(StringBuffer sb, long millis) {
    -        Date date = new Date(millis);
    -        sb.append(date.getYear() + 1900);
    +    private void appendISO8601(StringBuilder sb, long millis) {
    +        GregorianCalendar cal = new GregorianCalendar();
    +        cal.setTimeInMillis(millis);
    +        sb.append(cal.get(Calendar.YEAR) + 1900);
             sb.append('-');
    -        a2(sb, date.getMonth() + 1);
    +        a2(sb, cal.get(Calendar.MONTH) + 1);
             sb.append('-');
    -        a2(sb, date.getDate());
    +        a2(sb, cal.get(Calendar.DAY_OF_MONTH));
             sb.append('T');
    -        a2(sb, date.getHours());
    +        a2(sb, cal.get(Calendar.HOUR_OF_DAY));
             sb.append(':');
    -        a2(sb, date.getMinutes());
    +        a2(sb, cal.get(Calendar.MINUTE));
             sb.append(':');
    -        a2(sb, date.getSeconds());
    +        a2(sb, cal.get(Calendar.SECOND));
         }
     
    -    // Append to the given StringBuffer an escaped version of the
    +    // Append to the given StringBuilder an escaped version of the
         // given text string where XML special characters have been escaped.
         // For a null string we append ""
    -    private void escape(StringBuffer sb, String text) {
    +    private void escape(StringBuilder sb, String text) {
             if (text == null) {
                 text = "";
             }
    @@ -102,7 +103,7 @@ public class XMLFormatter extends Formatter {
          * @return a formatted log record
          */
         public String format(LogRecord record) {
    -        StringBuffer sb = new StringBuffer(500);
    +        StringBuilder sb = new StringBuilder(500);
             sb.append("\n");
     
             sb.append("  ");
    @@ -224,7 +225,7 @@ public class XMLFormatter extends Formatter {
          * @return  a valid XML string
          */
         public String getHead(Handler h) {
    -        StringBuffer sb = new StringBuffer();
    +        StringBuilder sb = new StringBuilder();
             String encoding;
             sb.append("
    Date: Wed, 7 Aug 2013 12:13:34 -0700
    Subject: [PATCH 38/39] 8022554: Fix Warnings in sun.invoke.anon Package
    
    Reviewed-by: darcy, mduigou, lancea
    ---
     jdk/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/jdk/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java b/jdk/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java
    index 259d4b2336e..b4fde055034 100644
    --- a/jdk/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java
    +++ b/jdk/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java
    @@ -418,7 +418,7 @@ public class ConstantPoolPatch {
     
         private static final Map, Byte> CONSTANT_VALUE_CLASS_TAG
             = new IdentityHashMap, Byte>();
    -    private static final Class[] CONSTANT_VALUE_CLASS = new Class[16];
    +    private static final Class[] CONSTANT_VALUE_CLASS = new Class[16];
         static {
             Object[][] values = {
                 {Integer.class, CONSTANT_Integer},
    
    From 0982c856e53cf998ce0ad4909d8394f1e312f36a Mon Sep 17 00:00:00 2001
    From: Stuart Marks 
    Date: Wed, 7 Aug 2013 16:29:36 -0700
    Subject: [PATCH 39/39] 8022479: clean up warnings from sun.tools.asm
    
    Reviewed-by: lancea, darcy
    ---
     .../classes/sun/tools/asm/Assembler.java      | 90 ++++++++++---------
     .../classes/sun/tools/asm/ConstantPool.java   | 12 +--
     .../classes/sun/tools/asm/Instruction.java    | 17 ++--
     .../classes/sun/tools/asm/SwitchData.java     | 38 ++++----
     .../share/classes/sun/tools/asm/TryData.java  |  6 +-
     5 files changed, 87 insertions(+), 76 deletions(-)
    
    diff --git a/jdk/src/share/classes/sun/tools/asm/Assembler.java b/jdk/src/share/classes/sun/tools/asm/Assembler.java
    index 1bf406e182e..b4fc8b1d290 100644
    --- a/jdk/src/share/classes/sun/tools/asm/Assembler.java
    +++ b/jdk/src/share/classes/sun/tools/asm/Assembler.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1994, 2013, 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
    @@ -91,9 +91,9 @@ class Assembler implements Constants {
             add(new Instruction(where, opc, flagNoCovered));
         }
     
    -    static Vector SourceClassList = new Vector();
    +    static Vector SourceClassList = new Vector<>();
     
    -    static Vector TmpCovTable = new Vector();
    +    static Vector TmpCovTable = new Vector<>();
     
         static int[]  JcovClassCountArray = new int[CT_LAST_KIND + 1];
     
    @@ -177,8 +177,8 @@ class Assembler implements Constants {
                   case opc_lookupswitch: {
                     SwitchData sw = (SwitchData)inst.value;
                     optimize(env, sw.defaultLabel);
    -                for (Enumeration e = sw.tab.elements() ; e.hasMoreElements();) {
    -                    optimize(env, (Label)e.nextElement());
    +                for (Enumeration
  • Audio System Property Keys
    Property KeyInterface