--- a/jdk/make/java/java/mapfile-vers Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/make/java/java/mapfile-vers Tue Apr 16 01:44:58 2013 -0700
@@ -217,7 +217,7 @@
Java_java_lang_Throwable_fillInStackTrace;
Java_java_lang_Throwable_getStackTraceDepth;
Java_java_lang_Throwable_getStackTraceElement;
- Java_java_lang_UNIXProcess_initIDs;
+ Java_java_lang_UNIXProcess_init;
Java_java_lang_UNIXProcess_waitForProcessExit;
Java_java_lang_UNIXProcess_forkAndExec;
Java_java_lang_UNIXProcess_destroyProcess;
--- a/jdk/makefiles/mapfiles/libjava/mapfile-vers Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/makefiles/mapfiles/libjava/mapfile-vers Tue Apr 16 01:44:58 2013 -0700
@@ -217,7 +217,7 @@
Java_java_lang_Throwable_fillInStackTrace;
Java_java_lang_Throwable_getStackTraceDepth;
Java_java_lang_Throwable_getStackTraceElement;
- Java_java_lang_UNIXProcess_initIDs;
+ Java_java_lang_UNIXProcess_init;
Java_java_lang_UNIXProcess_waitForProcessExit;
Java_java_lang_UNIXProcess_forkAndExec;
Java_java_lang_UNIXProcess_destroyProcess;
--- a/jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Tue Apr 16 01:44:58 2013 -0700
@@ -184,7 +184,7 @@
for (int i=0; i<markerInterfaces.length; i++) {
interfaces[i+1] = markerInterfaces[i].getName().replace('.', '/');
}
- cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL,
+ cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL + ACC_SYNTHETIC,
lambdaClassName, null,
NAME_MAGIC_ACCESSOR_IMPL, interfaces);
--- a/jdk/src/share/classes/java/nio/file/attribute/FileTime.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileTime.java Tue Apr 16 01:44:58 2013 -0700
@@ -25,12 +25,10 @@
package java.nio.file.attribute;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.Date;
-import java.util.Formatter;
-import java.util.Locale;
-import java.util.TimeZone;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
@@ -51,14 +49,22 @@
implements Comparable<FileTime>
{
/**
+ * The unit of granularity to interpret the value. Null if
+ * this {@code FileTime} is converted from an {@code Instant},
+ * the {@code value} and {@code unit} pair will not be used
+ * in this scenario.
+ */
+ private final TimeUnit unit;
+
+ /**
* The value since the epoch; can be negative.
*/
private final long value;
/**
- * The unit of granularity to interpret the value.
+ * The value as Instant (created lazily, if not from an instant)
*/
- private final TimeUnit unit;
+ private Instant instant;
/**
* The value return by toString (created lazily)
@@ -66,27 +72,12 @@
private String valueAsString;
/**
- * The value in days and excess nanos (created lazily)
- */
- private DaysAndNanos daysAndNanos;
-
- /**
- * Returns a DaysAndNanos object representing the value.
- */
- private DaysAndNanos asDaysAndNanos() {
- if (daysAndNanos == null)
- daysAndNanos = new DaysAndNanos(value, unit);
- return daysAndNanos;
- }
-
- /**
* Initializes a new instance of this class.
*/
- private FileTime(long value, TimeUnit unit) {
- if (unit == null)
- throw new NullPointerException();
+ private FileTime(long value, TimeUnit unit, Instant instant) {
this.value = value;
this.unit = unit;
+ this.instant = instant;
}
/**
@@ -102,7 +93,8 @@
* @return a {@code FileTime} representing the given value
*/
public static FileTime from(long value, TimeUnit unit) {
- return new FileTime(value, unit);
+ Objects.requireNonNull(unit, "unit");
+ return new FileTime(value, unit, null);
}
/**
@@ -115,7 +107,22 @@
* @return a {@code FileTime} representing the given value
*/
public static FileTime fromMillis(long value) {
- return new FileTime(value, TimeUnit.MILLISECONDS);
+ return new FileTime(value, TimeUnit.MILLISECONDS, null);
+ }
+
+ /**
+ * Returns a {@code FileTime} representing the same point of time value
+ * on the time-line as the provided {@code Instant} object.
+ *
+ * @param instant
+ * the instant to convert
+ * @return a {@code FileTime} representing the same point on the time-line
+ * as the provided instant
+ * @since 1.8
+ */
+ public static FileTime from(Instant instant) {
+ Objects.requireNonNull(instant, "instant");
+ return new FileTime(0, null, instant);
}
/**
@@ -132,7 +139,22 @@
* since the epoch (1970-01-01T00:00:00Z); can be negative
*/
public long to(TimeUnit unit) {
- return unit.convert(this.value, this.unit);
+ Objects.requireNonNull(unit, "unit");
+ if (this.unit != null) {
+ return unit.convert(this.value, this.unit);
+ } else {
+ long secs = unit.convert(instant.getEpochSecond(), TimeUnit.SECONDS);
+ if (secs == Long.MIN_VALUE || secs == Long.MAX_VALUE) {
+ return secs;
+ }
+ long nanos = unit.convert(instant.getNano(), TimeUnit.NANOSECONDS);
+ long r = secs + nanos;
+ // Math.addExact() variant
+ if (((secs ^ r) & (nanos ^ r)) < 0) {
+ return (secs < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
+ }
+ return r;
+ }
}
/**
@@ -145,7 +167,110 @@
* @return the value in milliseconds, since the epoch (1970-01-01T00:00:00Z)
*/
public long toMillis() {
- return unit.toMillis(value);
+ if (unit != null) {
+ return unit.toMillis(value);
+ } else {
+ long secs = instant.getEpochSecond();
+ int nanos = instant.getNano();
+ // Math.multiplyExact() variant
+ long r = secs * 1000;
+ long ax = Math.abs(secs);
+ if (((ax | 1000) >>> 31 != 0)) {
+ if ((r / 1000) != secs) {
+ return (secs < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
+ }
+ }
+ return r + nanos / 1000_000;
+ }
+ }
+
+ /**
+ * Time unit constants for conversion.
+ */
+ private static final long HOURS_PER_DAY = 24L;
+ private static final long MINUTES_PER_HOUR = 60L;
+ private static final long SECONDS_PER_MINUTE = 60L;
+ private static final long SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
+ private static final long SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY;
+ private static final long MILLIS_PER_SECOND = 1000L;
+ private static final long MICROS_PER_SECOND = 1000_000L;
+ private static final long NANOS_PER_SECOND = 1000_000_000L;
+ private static final int NANOS_PER_MILLI = 1000_000;
+ private static final int NANOS_PER_MICRO = 1000;
+ // The epoch second of Instant.MIN.
+ private static final long MIN_SECOND = -31557014167219200L;
+ // The epoch second of Instant.MAX.
+ private static final long MAX_SECOND = 31556889864403199L;
+
+ /*
+ * Scale d by m, checking for overflow.
+ */
+ private static long scale(long d, long m, long over) {
+ if (d > over) return Long.MAX_VALUE;
+ if (d < -over) return Long.MIN_VALUE;
+ return d * m;
+ }
+
+ /**
+ * Converts this {@code FileTime} object to an {@code Instant}.
+ *
+ * <p> The conversion creates an {@code Instant} that represents the
+ * same point on the time-line as this {@code FileTime}.
+ *
+ * <p> {@code FileTime} can store points on the time-line further in the
+ * future and further in the past than {@code Instant}. Conversion
+ * from such further time points saturates to {@link Instant.MIN} if
+ * earlier than {@code Instant.MIN} or {@link Instant.MAX} if later
+ * than {@code Instant.MAX}.
+ *
+ * @return an instant representing the same point on the time-line as
+ * this {@code FileTime} object
+ * @since 1.8
+ */
+ public Instant toInstant() {
+ if (instant == null) {
+ long secs = 0L;
+ int nanos = 0;
+ switch (unit) {
+ case DAYS:
+ secs = scale(value, SECONDS_PER_DAY,
+ Long.MAX_VALUE/SECONDS_PER_DAY);
+ break;
+ case HOURS:
+ secs = scale(value, SECONDS_PER_HOUR,
+ Long.MAX_VALUE/SECONDS_PER_HOUR);
+ break;
+ case MINUTES:
+ secs = scale(value, SECONDS_PER_MINUTE,
+ Long.MAX_VALUE/SECONDS_PER_MINUTE);
+ break;
+ case SECONDS:
+ secs = value;
+ break;
+ case MILLISECONDS:
+ secs = Math.floorDiv(value, MILLIS_PER_SECOND);
+ nanos = (int)Math.floorMod(value, MILLIS_PER_SECOND)
+ * NANOS_PER_MILLI;
+ break;
+ case MICROSECONDS:
+ secs = Math.floorDiv(value, MICROS_PER_SECOND);
+ nanos = (int)Math.floorMod(value, MICROS_PER_SECOND)
+ * NANOS_PER_MICRO;
+ break;
+ case NANOSECONDS:
+ secs = Math.floorDiv(value, NANOS_PER_SECOND);
+ nanos = (int)Math.floorMod(value, NANOS_PER_SECOND);
+ break;
+ default : throw new AssertionError("Unit not handled");
+ }
+ if (secs <= MIN_SECOND)
+ instant = Instant.MIN;
+ else if (secs >= MAX_SECOND)
+ instant = Instant.MAX;
+ else
+ instant = Instant.ofEpochSecond(secs, nanos);
+ }
+ return instant;
}
/**
@@ -176,8 +301,25 @@
*/
@Override
public int hashCode() {
- // hashcode of days/nanos representation to satisfy contract with equals
- return asDaysAndNanos().hashCode();
+ // hashcode of instant representation to satisfy contract with equals
+ return toInstant().hashCode();
+ }
+
+ private long toDays() {
+ if (unit != null) {
+ return unit.toDays(value);
+ } else {
+ return TimeUnit.SECONDS.toDays(toInstant().getEpochSecond());
+ }
+ }
+
+ private long toExcessNanos(long days) {
+ if (unit != null) {
+ return unit.toNanos(value - unit.convert(days, TimeUnit.DAYS));
+ } else {
+ return TimeUnit.SECONDS.toNanos(toInstant().getEpochSecond()
+ - TimeUnit.DAYS.toSeconds(days));
+ }
}
/**
@@ -194,14 +336,52 @@
@Override
public int compareTo(FileTime other) {
// same granularity
- if (unit == other.unit) {
- return (value < other.value) ? -1 : (value == other.value ? 0 : 1);
+ if (unit != null && unit == other.unit) {
+ return Long.compare(value, other.value);
} else {
- // compare using days/nanos representation when unit differs
- return asDaysAndNanos().compareTo(other.asDaysAndNanos());
+ // compare using instant representation when unit differs
+ long secs = toInstant().getEpochSecond();
+ long secsOther = other.toInstant().getEpochSecond();
+ int cmp = Long.compare(secs, secsOther);
+ if (cmp != 0) {
+ return cmp;
+ }
+ cmp = Long.compare(toInstant().getNano(), other.toInstant().getNano());
+ if (cmp != 0) {
+ return cmp;
+ }
+ if (secs != MAX_SECOND && secs != MIN_SECOND) {
+ return 0;
+ }
+ // if both this and other's Instant reps are MIN/MAX,
+ // use daysSinceEpoch and nanosOfDays, which will not
+ // saturate during calculation.
+ long days = toDays();
+ long daysOther = other.toDays();
+ if (days == daysOther) {
+ return Long.compare(toExcessNanos(days), other.toExcessNanos(daysOther));
+ }
+ return Long.compare(days, daysOther);
}
}
+ // days in a 400 year cycle = 146097
+ // days in a 10,000 year cycle = 146097 * 25
+ // seconds per day = 86400
+ private static final long DAYS_PER_10000_YEARS = 146097L * 25L;
+ private static final long SECONDS_PER_10000_YEARS = 146097L * 25L * 86400L;
+ private static final long SECONDS_0000_TO_1970 = ((146097L * 5L) - (30L * 365L + 7L)) * 86400L;
+
+ // append year/month/day/hour/minute/second/nano with width and 0 padding
+ private StringBuilder append(StringBuilder sb, int w, int d) {
+ while (w > 0) {
+ sb.append((char)(d/w + '0'));
+ d = d % w;
+ w /= 10;
+ }
+ return sb;
+ }
+
/**
* Returns the string representation of this {@code FileTime}. The string
* is returned in the <a
@@ -229,135 +409,67 @@
*/
@Override
public String toString() {
- String v = valueAsString;
- if (v == null) {
- // overflow saturates to Long.MIN_VALUE or Long.MAX_VALUE so this
- // limits the range:
- // [-292275056-05-16T16:47:04.192Z,292278994-08-17T07:12:55.807Z]
- long ms = toMillis();
-
- // nothing to do when seconds/minutes/hours/days
- String fractionAsString = "";
- if (unit.compareTo(TimeUnit.SECONDS) < 0) {
- long fraction = asDaysAndNanos().fractionOfSecondInNanos();
- if (fraction != 0L) {
- // fraction must be positive
- if (fraction < 0L) {
- final long MAX_FRACTION_PLUS_1 = 1000L * 1000L * 1000L;
- fraction += MAX_FRACTION_PLUS_1;
- if (ms != Long.MIN_VALUE) ms--;
- }
-
- // convert to String, adding leading zeros as required and
- // stripping any trailing zeros
- String s = Long.toString(fraction);
- int len = s.length();
- int width = 9 - len;
- StringBuilder sb = new StringBuilder(".");
- while (width-- > 0) {
- sb.append('0');
- }
- if (s.charAt(len-1) == '0') {
- // drop trailing zeros
- len--;
- while (s.charAt(len-1) == '0')
- len--;
- sb.append(s.substring(0, len));
- } else {
- sb.append(s);
- }
- fractionAsString = sb.toString();
+ if (valueAsString == null) {
+ long secs = 0L;
+ int nanos = 0;
+ if (instant == null && unit.compareTo(TimeUnit.SECONDS) >= 0) {
+ secs = unit.toSeconds(value);
+ } else {
+ secs = toInstant().getEpochSecond();
+ nanos = toInstant().getNano();
+ }
+ LocalDateTime ldt;
+ int year = 0;
+ if (secs >= -SECONDS_0000_TO_1970) {
+ // current era
+ long zeroSecs = secs - SECONDS_PER_10000_YEARS + SECONDS_0000_TO_1970;
+ long hi = Math.floorDiv(zeroSecs, SECONDS_PER_10000_YEARS) + 1;
+ long lo = Math.floorMod(zeroSecs, SECONDS_PER_10000_YEARS);
+ ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);
+ year = ldt.getYear() + (int)hi * 10000;
+ } else {
+ // before current era
+ long zeroSecs = secs + SECONDS_0000_TO_1970;
+ long hi = zeroSecs / SECONDS_PER_10000_YEARS;
+ long lo = zeroSecs % SECONDS_PER_10000_YEARS;
+ ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);
+ year = ldt.getYear() + (int)hi * 10000;
+ }
+ if (year <= 0) {
+ year = year - 1;
+ }
+ int fraction = ldt.getNano();
+ StringBuilder sb = new StringBuilder(64);
+ sb.append(year < 0 ? "-" : "");
+ year = Math.abs(year);
+ if (year < 10000) {
+ append(sb, 1000, Math.abs(year));
+ } else {
+ sb.append(String.valueOf(year));
+ }
+ sb.append('-');
+ append(sb, 10, ldt.getMonthValue());
+ sb.append('-');
+ append(sb, 10, ldt.getDayOfMonth());
+ sb.append('T');
+ append(sb, 10, ldt.getHour());
+ sb.append(':');
+ append(sb, 10, ldt.getMinute());
+ sb.append(':');
+ append(sb, 10, ldt.getSecond());
+ if (fraction != 0) {
+ sb.append('.');
+ // adding leading zeros and stripping any trailing zeros
+ int w = 100_000_000;
+ while (fraction % 10 == 0) {
+ fraction /= 10;
+ w /= 10;
}
+ append(sb, w, fraction);
}
-
- // create calendar to use with formatter.
- GregorianCalendar cal =
- new GregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.ROOT);
- if (value < 0L)
- cal.setGregorianChange(new Date(Long.MIN_VALUE));
- cal.setTimeInMillis(ms);
-
- // years are negative before common era
- String sign = (cal.get(Calendar.ERA) == GregorianCalendar.BC) ? "-" : "";
-
- // [-]YYYY-MM-DDThh:mm:ss[.s]Z
- v = new Formatter(Locale.ROOT)
- .format("%s%tFT%tR:%tS%sZ", sign, cal, cal, cal, fractionAsString)
- .toString();
- valueAsString = v;
+ sb.append('Z');
+ valueAsString = sb.toString();
}
- return v;
- }
-
- /**
- * Represents a FileTime's value as two longs: the number of days since
- * the epoch, and the excess (in nanoseconds). This is used for comparing
- * values with different units of granularity.
- */
- private static class DaysAndNanos implements Comparable<DaysAndNanos> {
- // constants for conversion
- private static final long C0 = 1L;
- private static final long C1 = C0 * 24L;
- private static final long C2 = C1 * 60L;
- private static final long C3 = C2 * 60L;
- private static final long C4 = C3 * 1000L;
- private static final long C5 = C4 * 1000L;
- private static final long C6 = C5 * 1000L;
-
- /**
- * The value (in days) since the epoch; can be negative.
- */
- private final long days;
-
- /**
- * The excess (in nanoseconds); can be negative if days <= 0.
- */
- private final long excessNanos;
-
- /**
- * Initializes a new instance of this class.
- */
- DaysAndNanos(long value, TimeUnit unit) {
- long scale;
- switch (unit) {
- case DAYS : scale = C0; break;
- case HOURS : scale = C1; break;
- case MINUTES : scale = C2; break;
- case SECONDS : scale = C3; break;
- case MILLISECONDS : scale = C4; break;
- case MICROSECONDS : scale = C5; break;
- case NANOSECONDS : scale = C6; break;
- default : throw new AssertionError("Unit not handled");
- }
- this.days = unit.toDays(value);
- this.excessNanos = unit.toNanos(value - (this.days * scale));
- }
-
- /**
- * Returns the fraction of a second, in nanoseconds.
- */
- long fractionOfSecondInNanos() {
- return excessNanos % (1000L * 1000L * 1000L);
- }
-
- @Override
- public boolean equals(Object obj) {
- return (obj instanceof DaysAndNanos) ?
- compareTo((DaysAndNanos)obj) == 0 : false;
- }
-
- @Override
- public int hashCode() {
- return (int)(days ^ (days >>> 32) ^
- excessNanos ^ (excessNanos >>> 32));
- }
-
- @Override
- public int compareTo(DaysAndNanos other) {
- if (this.days != other.days)
- return (this.days < other.days) ? -1 : 1;
- return (this.excessNanos < other.excessNanos) ? -1 :
- (this.excessNanos == other.excessNanos) ? 0 : 1;
- }
+ return valueAsString;
}
}
--- a/jdk/src/share/classes/java/util/ArrayList.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/share/classes/java/util/ArrayList.java Tue Apr 16 01:44:58 2013 -0700
@@ -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
@@ -105,8 +105,20 @@
private static final long serialVersionUID = 8683452581122892189L;
/**
+ * Default initial capacity.
+ */
+ private static final int DEFAULT_CAPACITY = 10;
+
+ /**
+ * Shared empty array instance used for empty instances.
+ */
+ private static final Object[] EMPTY_ELEMENTDATA = {};
+
+ /**
* The array buffer into which the elements of the ArrayList are stored.
- * The capacity of the ArrayList is the length of this array buffer.
+ * The capacity of the ArrayList is the length of this array buffer. Any
+ * empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to
+ * DEFAULT_CAPACITY when the first element is added.
*/
private transient Object[] elementData;
@@ -136,7 +148,8 @@
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
- this(10);
+ super();
+ this.elementData = EMPTY_ELEMENTDATA;
}
/**
@@ -162,8 +175,7 @@
*/
public void trimToSize() {
modCount++;
- int oldCapacity = elementData.length;
- if (size < oldCapacity) {
+ if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size);
}
}
@@ -176,12 +188,29 @@
* @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
- if (minCapacity > 0)
- ensureCapacityInternal(minCapacity);
+ int minExpand = (elementData != EMPTY_ELEMENTDATA)
+ // any size if real element table
+ ? 0
+ // larger than default for empty table. It's already supposed to be
+ // at default size.
+ : DEFAULT_CAPACITY;
+
+ if (minCapacity > minExpand) {
+ ensureExplicitCapacity(minCapacity);
+ }
}
private void ensureCapacityInternal(int minCapacity) {
+ if (elementData == EMPTY_ELEMENTDATA) {
+ minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
+ }
+
+ ensureExplicitCapacity(minCapacity);
+ }
+
+ private void ensureExplicitCapacity(int minCapacity) {
modCount++;
+
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
@@ -450,7 +479,7 @@
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
- elementData[--size] = null; // Let gc do its work
+ elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
@@ -495,7 +524,7 @@
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
- elementData[--size] = null; // Let gc do its work
+ elementData[--size] = null; // clear to let GC do its work
}
/**
@@ -505,7 +534,7 @@
public void clear() {
modCount++;
- // Let gc do its work
+ // clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
@@ -586,10 +615,12 @@
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
- // Let gc do its work
+ // clear to let GC do its work
int newSize = size - (toIndex-fromIndex);
- while (size != newSize)
- elementData[--size] = null;
+ for (int i = newSize; i < size; i++) {
+ elementData[i] = null;
+ }
+ size = newSize;
}
/**
@@ -677,6 +708,7 @@
w += size - r;
}
if (w != size) {
+ // clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
@@ -701,17 +733,17 @@
int expectedModCount = modCount;
s.defaultWriteObject();
- // Write out array length
- s.writeInt(elementData.length);
+ // Write out size as capacity for behavioural compatibility with clone()
+ s.writeInt(size);
// Write out all elements in the proper order.
- for (int i=0; i<size; i++)
+ for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
+ }
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
-
}
/**
@@ -720,16 +752,24 @@
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
+ elementData = EMPTY_ELEMENTDATA;
+
// Read in size, and any hidden stuff
s.defaultReadObject();
- // Read in array length and allocate array
- int arrayLength = s.readInt();
- Object[] a = elementData = new Object[arrayLength];
+ // Read in capacity
+ s.readInt(); // ignored
+
+ if (size > 0) {
+ // be like clone(), allocate array based upon size not capacity
+ ensureCapacityInternal(size);
- // Read in all elements in the proper order.
- for (int i=0; i<size; i++)
- a[i] = s.readObject();
+ Object[] a = elementData;
+ // Read in all elements in the proper order.
+ for (int i=0; i<size; i++) {
+ a[i] = s.readObject();
+ }
+ }
}
/**
--- a/jdk/src/share/classes/java/util/Comparators.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/share/classes/java/util/Comparators.java Tue Apr 16 01:44:58 2013 -0700
@@ -261,6 +261,7 @@
* according to the supplied {@code Comparator}
*/
public static<T> BinaryOperator<T> lesserOf(Comparator<? super T> comparator) {
+ Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
@@ -274,6 +275,7 @@
* according to the supplied {@code Comparator}
*/
public static<T> BinaryOperator<T> greaterOf(Comparator<? super T> comparator) {
+ Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
}
--- a/jdk/src/share/classes/java/util/HashMap.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/share/classes/java/util/HashMap.java Tue Apr 16 01:44:58 2013 -0700
@@ -129,7 +129,7 @@
/**
* The default initial capacity - MUST be a power of two.
*/
- static final int DEFAULT_INITIAL_CAPACITY = 16;
+ static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/**
* The maximum capacity, used if a higher value is implicitly specified
@@ -144,9 +144,14 @@
static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
+ * An empty table instance to share when the table is not inflated.
+ */
+ static final Entry<?,?>[] EMPTY_TABLE = {};
+
+ /**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
- transient Entry<?,?>[] table;
+ transient Entry<?,?>[] table = EMPTY_TABLE;
/**
* The number of key-value mappings contained in this map.
@@ -157,6 +162,8 @@
* The next size value at which to resize (capacity * load factor).
* @serial
*/
+ // If table == EMPTY_TABLE then this is the initial capacity at which the
+ // table will be created when inflated.
int threshold;
/**
@@ -223,14 +230,8 @@
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
- // Find a power of 2 >= initialCapacity
- int capacity = 1;
- while (capacity < initialCapacity)
- capacity <<= 1;
-
this.loadFactor = loadFactor;
- threshold = (int)Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
- table = new Entry<?,?>[capacity];
+ threshold = initialCapacity;
init();
}
@@ -265,9 +266,33 @@
public HashMap(Map<? extends K, ? extends V> m) {
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
+ inflateTable(threshold);
+
putAllForCreate(m);
}
+ private static int roundUpToPowerOf2(int number) {
+ // assert number >= 0 : "number must be non-negative";
+ int rounded = number >= MAXIMUM_CAPACITY
+ ? MAXIMUM_CAPACITY
+ : (rounded = Integer.highestOneBit(number)) != 0
+ ? (Integer.bitCount(number) > 1) ? rounded << 1 : rounded
+ : 1;
+
+ return rounded;
+ }
+
+ /**
+ * Inflates the table.
+ */
+ private void inflateTable(int toSize) {
+ // Find a power of 2 >= toSize
+ int capacity = roundUpToPowerOf2(toSize);
+
+ threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
+ table = new Entry[capacity];
+ }
+
// internal utilities
/**
@@ -305,6 +330,7 @@
* Returns index for hash code h.
*/
static int indexFor(int h, int length) {
+ // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
return h & (length-1);
}
@@ -369,6 +395,10 @@
*/
@SuppressWarnings("unchecked")
final Entry<K,V> getEntry(Object key) {
+ if (isEmpty()) {
+ return null;
+ }
+
int hash = (key == null) ? 0 : hash(key);
for (Entry<?,?> e = table[indexFor(hash, table.length)];
e != null;
@@ -381,7 +411,6 @@
return null;
}
-
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
@@ -395,6 +424,9 @@
* previously associated <tt>null</tt> with <tt>key</tt>.)
*/
public V put(K key, V value) {
+ if (table == EMPTY_TABLE) {
+ inflateTable(threshold);
+ }
if (key == null)
return putForNullKey(value);
int hash = hash(key);
@@ -529,6 +561,10 @@
if (numKeysToBeAdded == 0)
return;
+ if (table == EMPTY_TABLE) {
+ inflateTable((int) Math.max(numKeysToBeAdded * loadFactor, threshold));
+ }
+
/*
* Expand the map if the map if the number of mappings to be added
* is greater than or equal to threshold. This is conservative; the
@@ -573,6 +609,9 @@
* for this key.
*/
final Entry<K,V> removeEntryForKey(Object key) {
+ if (isEmpty()) {
+ return null;
+ }
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
@SuppressWarnings("unchecked")
@@ -605,7 +644,7 @@
* for matching.
*/
final Entry<K,V> removeMapping(Object o) {
- if (!(o instanceof Map.Entry))
+ if (isEmpty() || !(o instanceof Map.Entry))
return null;
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
@@ -641,9 +680,7 @@
*/
public void clear() {
modCount++;
- Entry<?,?>[] tab = table;
- for (int i = 0; i < tab.length; i++)
- tab[i] = null;
+ Arrays.fill(table, null);
size = 0;
}
@@ -693,7 +730,14 @@
} catch (CloneNotSupportedException e) {
// assert false;
}
- result.table = new Entry<?,?>[table.length];
+ if (result.table != EMPTY_TABLE) {
+ result.inflateTable(Math.min(
+ (int) Math.min(
+ size * Math.min(1 / loadFactor, 4.0f),
+ // we have limits...
+ HashMap.MAXIMUM_CAPACITY),
+ table.length));
+ }
result.entrySet = null;
result.modCount = 0;
result.size = 0;
@@ -749,8 +793,7 @@
}
public final int hashCode() {
- return (key==null ? 0 : key.hashCode()) ^
- (value==null ? 0 : value.hashCode());
+ return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
}
public final String toString() {
@@ -1017,14 +1060,15 @@
private void writeObject(java.io.ObjectOutputStream s)
throws IOException
{
- Iterator<Map.Entry<K,V>> i =
- (size > 0) ? entrySet0().iterator() : null;
-
// Write out the threshold, loadfactor, and any hidden stuff
s.defaultWriteObject();
// Write out number of buckets
- s.writeInt(table.length);
+ if (table==EMPTY_TABLE) {
+ s.writeInt(roundUpToPowerOf2(threshold));
+ } else {
+ s.writeInt(table.length);
+ }
// Write out size (number of Mappings)
s.writeInt(size);
@@ -1049,16 +1093,18 @@
{
// Read in the threshold (ignored), loadfactor, and any hidden stuff
s.defaultReadObject();
- if (loadFactor <= 0 || Float.isNaN(loadFactor))
+ if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
throw new InvalidObjectException("Illegal load factor: " +
loadFactor);
+ }
- // set hashMask
+ // set other fields that need values
Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET,
sun.misc.Hashing.randomHashSeed(this));
+ table = EMPTY_TABLE;
- // Read in number of buckets and allocate the bucket array;
- s.readInt(); // ignored
+ // Read in number of buckets
+ s.readInt(); // ignored.
// Read number of mappings
int mappings = s.readInt();
@@ -1066,23 +1112,21 @@
throw new InvalidObjectException("Illegal mappings count: " +
mappings);
- int initialCapacity = (int) Math.min(
- // capacity chosen by number of mappings
- // and desired load (if >= 0.25)
- mappings * Math.min(1 / loadFactor, 4.0f),
- // we have limits...
- HashMap.MAXIMUM_CAPACITY);
- int capacity = 1;
- // find smallest power of two which holds all mappings
- while (capacity < initialCapacity) {
- capacity <<= 1;
+ // capacity chosen by number of mappings and desired load (if >= 0.25)
+ int capacity = (int) Math.min(
+ mappings * Math.min(1 / loadFactor, 4.0f),
+ // we have limits...
+ HashMap.MAXIMUM_CAPACITY);
+
+ // allocate the bucket array;
+ if (mappings > 0) {
+ inflateTable(capacity);
+ } else {
+ threshold = capacity;
}
- table = new Entry<?,?>[capacity];
- threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
init(); // Give subclass a chance to do its thing.
-
// Read the keys and values, and put the mappings in the HashMap
for (int i=0; i<mappings; i++) {
@SuppressWarnings("unchecked")
--- a/jdk/src/share/classes/java/util/Objects.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/share/classes/java/util/Objects.java Tue Apr 16 01:44:58 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -25,6 +25,8 @@
package java.util;
+import java.util.function.Supplier;
+
/**
* This class consists of {@code static} utility methods for operating
* on objects. These utilities include {@code null}-safe or {@code
@@ -226,4 +228,30 @@
throw new NullPointerException(message);
return obj;
}
+
+ /**
+ * Checks that the specified object reference is not {@code null} and
+ * throws a customized {@link NullPointerException} if it is.
+ *
+ * <p>Unlike the method {@link requireNonNull(Object, String},
+ * this method allows creation of the message to be deferred until
+ * after the null check is made. While this may confer a
+ * performance advantage in the non-null case, when deciding to
+ * call this method care should be taken that the costs of
+ * creating the message supplier are less than the cost of just
+ * creating the string message directly.
+ *
+ * @param obj the object reference to check for nullity
+ * @param messageSupplier supplier of the detail message to be
+ * used in the event that a {@code NullPointerException} is thrown
+ * @param <T> the type of the reference
+ * @return {@code obj} if not {@code null}
+ * @throws NullPointerException if {@code obj} is {@code null}
+ * @since 1.8
+ */
+ public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
+ if (obj == null)
+ throw new NullPointerException(messageSupplier.get());
+ return obj;
+ }
}
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java Tue Apr 16 01:44:58 2013 -0700
@@ -466,7 +466,10 @@
if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH)
{
u.type = eSrc.type; // make it the same type
- if (!deletesrc) { // if it's not "rename", just take the data
+ if (deletesrc) { // if it's a "rename", take the data
+ u.bytes = eSrc.bytes;
+ u.file = eSrc.file;
+ } else { // if it's not "rename", copy the data
if (eSrc.bytes != null)
u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
else if (eSrc.file != null) {
@@ -1118,7 +1121,7 @@
if (old != null) {
removeFromTree(old);
}
- if (e.type == Entry.NEW || e.type == Entry.FILECH) {
+ if (e.type == Entry.NEW || e.type == Entry.FILECH || e.type == Entry.COPY) {
IndexNode parent = inodes.get(LOOKUPKEY.as(getParent(e.name)));
e.sibling = parent.child;
parent.child = e;
@@ -2326,12 +2329,12 @@
private void removeFromTree(IndexNode inode) {
IndexNode parent = inodes.get(LOOKUPKEY.as(getParent(inode.name)));
IndexNode child = parent.child;
- if (child == inode) {
+ if (child.equals(inode)) {
parent.child = child.sibling;
} else {
IndexNode last = child;
while ((child = child.sibling) != null) {
- if (child == inode) {
+ if (child.equals(inode)) {
last.sibling = child.sibling;
break;
} else {
--- a/jdk/src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h Tue Apr 16 01:44:58 2013 -0700
@@ -143,9 +143,9 @@
* structure from the information present in a given Java Composite
* object.
*/
-typedef JNIEXPORT void (JNICALL CompInfoFunc)(JNIEnv *env,
- CompositeInfo *pCompInfo,
- jobject Composite);
+typedef void (JNICALL CompInfoFunc)(JNIEnv *env,
+ CompositeInfo *pCompInfo,
+ jobject Composite);
/*
* The additional information needed to implement a primitive that
--- a/jdk/src/share/npt/npt.h Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/share/npt/npt.h Tue Apr 16 01:44:58 2013 -0700
@@ -94,13 +94,13 @@
JNIEXPORT void JNICALL nptInitialize
(NptEnv **pnpt, char *nptVersion, char *options);
-typedef JNIEXPORT void (JNICALL *NptInitialize)
- (NptEnv **pnpt, char *nptVersion, char *options);
+typedef void (JNICALL *NptInitialize)
+ (NptEnv **pnpt, char *nptVersion, char *options);
JNIEXPORT void JNICALL nptTerminate
(NptEnv* npt, char *options);
-typedef JNIEXPORT void (JNICALL *NptTerminate)
- (NptEnv* npt, char *options);
+typedef void (JNICALL *NptTerminate)
+ (NptEnv* npt, char *options);
#ifdef __cplusplus
} /* extern "C" */
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.bsd Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.bsd Tue Apr 16 01:44:58 2013 -0700
@@ -270,11 +270,10 @@
return !hasExited;
}
- /* This routine initializes JNI field offsets for the class */
- private static native void initIDs();
+ private static native void init();
static {
- initIDs();
+ init();
}
/**
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux Tue Apr 16 01:44:58 2013 -0700
@@ -270,11 +270,10 @@
return !hasExited;
}
- /* This routine initializes JNI field offsets for the class */
- private static native void initIDs();
+ private static native void init();
static {
- initIDs();
+ init();
}
/**
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris Tue Apr 16 01:44:58 2013 -0700
@@ -328,10 +328,9 @@
}
- /* This routine initializes JNI field offsets for the class */
- private static native void initIDs();
+ private static native void init();
static {
- initIDs();
+ init();
}
}
--- a/jdk/src/solaris/javavm/export/jni_md.h Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/solaris/javavm/export/jni_md.h Tue Apr 16 01:44:58 2013 -0700
@@ -26,8 +26,17 @@
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
-#define JNIEXPORT
-#define JNIIMPORT
+#ifndef __has_attribute
+ #define __has_attribute(x) 0
+#endif
+#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
+ #define JNIEXPORT __attribute__((visibility("default")))
+ #define JNIIMPORT __attribute__((visibility("default")))
+#else
+ #define JNIEXPORT
+ #define JNIIMPORT
+#endif
+
#define JNICALL
typedef int jint;
--- a/jdk/src/solaris/native/java/lang/ProcessEnvironment_md.c Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/solaris/native/java/lang/ProcessEnvironment_md.c Tue Apr 16 01:44:58 2013 -0700
@@ -31,21 +31,24 @@
#ifdef __APPLE__
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
+#else
+/* This is one of the rare times it's more portable to declare an
+ * external symbol explicitly, rather than via a system header.
+ * The declaration is standardized as part of UNIX98, but there is
+ * no standard (not even de-facto) header file where the
+ * declaration is to be found. See:
+ * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
+ * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
+ *
+ * "All identifiers in this volume of IEEE Std 1003.1-2001, except
+ * environ, are defined in at least one of the headers" (!)
+ */
+extern char **environ;
#endif
JNIEXPORT jobjectArray JNICALL
Java_java_lang_ProcessEnvironment_environ(JNIEnv *env, jclass ign)
{
- /* This is one of the rare times it's more portable to declare an
- * external symbol explicitly, rather than via a system header.
- * The declaration is standardized as part of UNIX98, but there is
- * no standard (not even de-facto) header file where the
- * declaration is to be found. See:
- * http://www.opengroup.org/onlinepubs/007908799/xbd/envvar.html */
-#ifndef __APPLE__
- extern char ** environ; /* environ[i] looks like: VAR=VALUE\0 */
-#endif
-
jsize count = 0;
jsize i, j;
jobjectArray result;
--- a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c Tue Apr 16 01:44:58 2013 -0700
@@ -52,6 +52,19 @@
#ifdef __APPLE__
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
+#else
+/* This is one of the rare times it's more portable to declare an
+ * external symbol explicitly, rather than via a system header.
+ * The declaration is standardized as part of UNIX98, but there is
+ * no standard (not even de-facto) header file where the
+ * declaration is to be found. See:
+ * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
+ * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
+ *
+ * "All identifiers in this volume of IEEE Std 1003.1-2001, except
+ * environ, are defined in at least one of the headers" (!)
+ */
+extern char **environ;
#endif
/*
@@ -152,19 +165,6 @@
} while((_result == -1) && (errno == EINTR)); \
} while(0)
-/* This is one of the rare times it's more portable to declare an
- * external symbol explicitly, rather than via a system header.
- * The declaration is standardized as part of UNIX98, but there is
- * no standard (not even de-facto) header file where the
- * declaration is to be found. See:
- * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
- * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
- *
- * "All identifiers in this volume of IEEE Std 1003.1-2001, except
- * environ, are defined in at least one of the headers" (!)
- */
-extern char **environ;
-
static void
setSIGCHLDHandler(JNIEnv *env)
@@ -241,52 +241,41 @@
}
static const char * const *
-splitPath(JNIEnv *env, const char *path)
+effectivePathv(JNIEnv *env)
{
- const char *p, *q;
- char **pathv;
+ char *p;
int i;
+ const char *path = effectivePath();
int count = countOccurrences(path, ':') + 1;
+ size_t pathvsize = sizeof(const char *) * (count+1);
+ size_t pathsize = strlen(path) + 1;
+ const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize);
- pathv = NEW(char*, count+1);
+ if (pathv == NULL)
+ return NULL;
+ p = (char *) pathv + pathvsize;
+ memcpy(p, path, pathsize);
+ /* split PATH by replacing ':' with NULs; empty components => "." */
+ for (i = 0; i < count; i++) {
+ char *q = p + strcspn(p, ":");
+ pathv[i] = (p == q) ? "." : p;
+ *q = '\0';
+ p = q + 1;
+ }
pathv[count] = NULL;
- for (p = path, i = 0; i < count; i++, p = q + 1) {
- for (q = p; (*q != ':') && (*q != '\0'); q++)
- ;
- if (q == p) /* empty PATH component => "." */
- pathv[i] = "./";
- else {
- int addSlash = ((*(q - 1)) != '/');
- pathv[i] = NEW(char, q - p + addSlash + 1);
- memcpy(pathv[i], p, q - p);
- if (addSlash)
- pathv[i][q - p] = '/';
- pathv[i][q - p + addSlash] = '\0';
- }
- }
- return (const char * const *) pathv;
+ return pathv;
}
/**
- * Cached value of JVM's effective PATH.
+ * The cached and split version of the JDK's effective PATH.
* (We don't support putenv("PATH=...") in native code)
*/
-static const char *parentPath;
-
-/**
- * Split, canonicalized version of parentPath
- */
static const char * const *parentPathv;
-static jfieldID field_exitcode;
-
JNIEXPORT void JNICALL
-Java_java_lang_UNIXProcess_initIDs(JNIEnv *env, jclass clazz)
+Java_java_lang_UNIXProcess_init(JNIEnv *env, jclass clazz)
{
- field_exitcode = (*env)->GetFieldID(env, clazz, "exitcode", "I");
-
- parentPath = effectivePath();
- parentPathv = splitPath(env, parentPath);
+ parentPathv = effectivePathv(env);
setSIGCHLDHandler(env);
}
@@ -486,6 +475,9 @@
}
/* ASCII Decimal representation uses 2.4 times as many bits as binary. */
errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum));
+ if (errmsg == NULL)
+ return;
+
sprintf(errmsg, format, errnum, detail);
s = JNU_NewStringPlatform(env, errmsg);
if (s != NULL) {
@@ -590,11 +582,13 @@
for (dirs = parentPathv; *dirs; dirs++) {
const char * dir = *dirs;
int dirlen = strlen(dir);
- if (filelen + dirlen + 1 >= PATH_MAX) {
+ if (filelen + dirlen + 2 >= PATH_MAX) {
errno = ENAMETOOLONG;
continue;
}
memcpy(expanded_file, dir, dirlen);
+ if (expanded_file[dirlen - 1] != '/')
+ expanded_file[dirlen++] = '/';
memcpy(expanded_file + dirlen, file, filelen);
expanded_file[dirlen + filelen] = '\0';
execve_with_shell_fallback(expanded_file, argv, envp);
--- a/jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c Tue Apr 16 01:44:58 2013 -0700
@@ -43,7 +43,7 @@
static void *awtHandle = NULL;
-typedef JNIEXPORT jint JNICALL JNI_OnLoad_type(JavaVM *vm, void *reserved);
+typedef jint JNICALL JNI_OnLoad_type(JavaVM *vm, void *reserved);
/* Initialize the Java VM instance variable when the library is
first loaded */
@@ -206,7 +206,7 @@
jobject frame, jstring jcommand)
{
/* type of the old backdoor function */
- typedef JNIEXPORT void JNICALL
+ typedef void JNICALL
XsessionWMcommand_type(JNIEnv *env, jobject this,
jobject frame, jstring jcommand);
@@ -234,7 +234,7 @@
JNIEXPORT void JNICALL
Java_sun_awt_motif_XsessionWMcommand_New(JNIEnv *env, jobjectArray jargv)
{
- typedef JNIEXPORT void JNICALL
+ typedef void JNICALL
XsessionWMcommand_New_type(JNIEnv *env, jobjectArray jargv);
static XsessionWMcommand_New_type *XsessionWMcommand = NULL;
--- a/jdk/test/demo/zipfs/ZipFSTester.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/test/demo/zipfs/ZipFSTester.java Tue Apr 16 01:44:58 2013 -0700
@@ -138,14 +138,31 @@
Path dst3 = Paths.get(tmpName + "_Tmp");
Files.move(dst2, dst3);
checkEqual(src, dst3);
+ if (Files.exists(dst2))
+ throw new RuntimeException("Failed!");
+
+ // copyback + move
+ Files.copy(dst3, dst);
+ Path dst4 = getPathWithParents(fs, tmpName + "_Tmp0");
+ Files.move(dst, dst4);
+ checkEqual(src, dst4);
// delete
- if (Files.exists(dst2))
+ Files.delete(dst4);
+ if (Files.exists(dst4))
throw new RuntimeException("Failed!");
Files.delete(dst3);
if (Files.exists(dst3))
throw new RuntimeException("Failed!");
+ // move (existing entry)
+ Path dst5 = fs.getPath("META-INF/MANIFEST.MF");
+ if (Files.exists(dst5)) {
+ Path dst6 = fs.getPath("META-INF/MANIFEST.MF_TMP");
+ Files.move(dst5, dst6);
+ walk(fs.getPath("/"));
+ }
+
// newInputStream on dir
Path parent = dst2.getParent();
try {
--- a/jdk/test/demo/zipfs/basic.sh Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/test/demo/zipfs/basic.sh Tue Apr 16 01:44:58 2013 -0700
@@ -22,7 +22,7 @@
#
# @test
# @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596
-# 7157656
+# 7157656 8002390
# @summary Test ZipFileSystem demo
# @build Basic PathOps ZipFSTester
# @run shell basic.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/lambda/LambdaClassFinal.java Tue Apr 16 01:44:58 2013 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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 8012028
+ * @summary Generated Lambda implementing class should be final
+ */
+
+import java.lang.reflect.Modifier;
+import java.io.Serializable;
+
+public class LambdaClassFinal {
+
+ interface I {
+ void m();
+ }
+
+ interface Iser extends Serializable {
+ void m();
+ }
+
+ static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) throws Exception {
+ new LambdaClassFinal().test();
+ }
+
+ void test() throws Exception {
+ I lam = () -> { };
+ assertTrue((lam.getClass().getModifiers() & Modifier.FINAL) != 0);
+ Iser slam = () -> { };
+ assertTrue((slam.getClass().getModifiers() & Modifier.FINAL) != 0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/lambda/LambdaClassSynthetic.java Tue Apr 16 01:44:58 2013 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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 8008941
+ * @summary Generated Lambda implementing class should be synthetic
+ */
+
+import java.lang.reflect.Modifier;
+import java.io.Serializable;
+
+public class LambdaClassSynthetic {
+
+ interface I {
+ void m();
+ }
+
+ interface Iser extends Serializable {
+ void m();
+ }
+
+ static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) throws Exception {
+ new LambdaClassFinal().test();
+ }
+
+ void test() throws Exception {
+ I lam = () -> { };
+ assertTrue(lam.getClass().isSynthetic());
+ Iser slam = () -> { };
+ assertTrue(slam.getClass().isSynthetic());
+ }
+}
--- a/jdk/test/java/nio/file/attribute/FileTime/Basic.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/test/java/nio/file/attribute/FileTime/Basic.java Tue Apr 16 01:44:58 2013 -0700
@@ -22,14 +22,17 @@
*/
/* @test
- * @bug 6844313
+ * @bug 6844313 8011647
* @summary Unit test for java.nio.file.FileTime
*/
+
import java.nio.file.attribute.FileTime;
+import java.time.Instant;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.*;
import java.util.Random;
+import java.util.EnumSet;
public class Basic {
@@ -40,27 +43,59 @@
long tomorrowInDays = TimeUnit.DAYS.convert(now, MILLISECONDS) + 1;
long yesterdayInDays = TimeUnit.DAYS.convert(now, MILLISECONDS) - 1;
+ Instant nowInstant = Instant.ofEpochMilli(now);
+
// equals
eq(now, MILLISECONDS, now, MILLISECONDS);
eq(now, MILLISECONDS, now*1000L, MICROSECONDS);
neq(now, MILLISECONDS, 0, MILLISECONDS);
neq(now, MILLISECONDS, 0, MICROSECONDS);
+ eq(nowInstant, now, MILLISECONDS);
+ eq(nowInstant, now*1000L, MICROSECONDS);
+ neq(nowInstant, 0, MILLISECONDS);
+ neq(nowInstant, 0, MICROSECONDS);
+
// compareTo
cmp(now, MILLISECONDS, now, MILLISECONDS, 0);
cmp(now, MILLISECONDS, now*1000L, MICROSECONDS, 0);
cmp(now, MILLISECONDS, now-1234, MILLISECONDS, 1);
cmp(now, MILLISECONDS, now+1234, MILLISECONDS, -1);
+
cmp(tomorrowInDays, DAYS, now, MILLISECONDS, 1);
cmp(now, MILLISECONDS, tomorrowInDays, DAYS, -1);
cmp(yesterdayInDays, DAYS, now, MILLISECONDS, -1);
cmp(now, MILLISECONDS, yesterdayInDays, DAYS, 1);
cmp(yesterdayInDays, DAYS, now, MILLISECONDS, -1);
+
cmp(Long.MAX_VALUE, DAYS, Long.MAX_VALUE, NANOSECONDS, 1);
cmp(Long.MAX_VALUE, DAYS, Long.MIN_VALUE, NANOSECONDS, 1);
cmp(Long.MIN_VALUE, DAYS, Long.MIN_VALUE, NANOSECONDS, -1);
cmp(Long.MIN_VALUE, DAYS, Long.MAX_VALUE, NANOSECONDS, -1);
+ cmp(Instant.MIN, Long.MIN_VALUE, DAYS, 1);
+ cmp(Instant.MIN, Long.MIN_VALUE, HOURS, 1);
+ cmp(Instant.MIN, Long.MIN_VALUE, MINUTES, 1);
+ cmp(Instant.MIN, Long.MIN_VALUE, SECONDS, 1);
+ cmp(Instant.MIN, Instant.MIN.getEpochSecond() - 1, SECONDS, 1);
+ cmp(Instant.MIN, Instant.MIN.getEpochSecond() - 100, SECONDS, 1);
+ cmp(Instant.MIN, Instant.MIN.getEpochSecond(), SECONDS, 0);
+
+ cmp(Instant.MAX, Long.MAX_VALUE, DAYS, -1);
+ cmp(Instant.MAX, Long.MAX_VALUE, HOURS, -1);
+ cmp(Instant.MAX, Long.MAX_VALUE, MINUTES, -1);
+ cmp(Instant.MAX, Long.MAX_VALUE, SECONDS, -1);
+ cmp(Instant.MAX, Instant.MAX.getEpochSecond() + 1, SECONDS, -1);
+ cmp(Instant.MAX, Instant.MAX.getEpochSecond() + 100, SECONDS, -1);
+ cmp(Instant.MAX, Instant.MAX.getEpochSecond(), SECONDS, 0);
+
+ cmp(nowInstant, now, MILLISECONDS, 0);
+ cmp(nowInstant, now*1000L, MICROSECONDS, 0);
+ cmp(nowInstant, now-1234, MILLISECONDS, 1);
+ cmp(nowInstant, now+1234, MILLISECONDS, -1);
+ cmp(nowInstant, tomorrowInDays, DAYS, -1);
+ cmp(nowInstant, yesterdayInDays, DAYS, 1);
+
// to(TimeUnit)
to(MILLISECONDS.convert(1, DAYS) - 1, MILLISECONDS);
to(MILLISECONDS.convert(1, DAYS) + 0, MILLISECONDS);
@@ -77,6 +112,64 @@
to(Long.MAX_VALUE, unit);
}
+ // toInstant()
+ int N = 1000;
+ for (TimeUnit unit : EnumSet.allOf(TimeUnit.class)) {
+ for (int i = 0; i < N; i++) {
+ long value = rand.nextLong();
+ FileTime ft = FileTime.from(value, unit);
+ Instant instant = ft.toInstant();
+ if (instant != Instant.MIN && instant != Instant.MAX) {
+ eqTime(value, unit, instant);
+ }
+ }
+ }
+ for (TimeUnit unit : EnumSet.allOf(TimeUnit.class)) {
+ long value = Long.MIN_VALUE;
+ FileTime ft = FileTime.from(value, unit);
+ Instant instant = ft.toInstant();
+ if (unit.compareTo(TimeUnit.SECONDS) < 0) {
+ eqTime(value, unit, instant);
+ } else if (!instant.equals(Instant.MIN)) {
+ throw new RuntimeException("should overflow to MIN");
+ }
+ value = Long.MAX_VALUE;
+ ft = FileTime.from(value, unit);
+ instant = ft.toInstant();
+ if (unit.compareTo(TimeUnit.SECONDS) < 0) {
+ eqTime(value, unit, instant);
+ } else if (!instant.equals(Instant.MAX)) {
+ throw new RuntimeException("should overflow to MAX");
+ }
+ }
+
+ // from(Instant)
+ final long MAX_SECOND = 31556889864403199L;
+ for (int i = 0; i < N; i++) {
+ long v = rand.nextLong();
+ long secs = v % MAX_SECOND;
+ Instant instant = Instant.ofEpochSecond(secs, rand.nextInt(1000_000_000));
+ FileTime ft = FileTime.from(instant);
+ if (!ft.toInstant().equals(instant) || ft.to(SECONDS) != secs) {
+ throw new RuntimeException("from(Instant) failed");
+ }
+ long millis = v;
+ instant = Instant.ofEpochMilli(millis);
+ ft = FileTime.from(instant);
+ if (!ft.toInstant().equals(instant) ||
+ ft.toMillis() != instant.toEpochMilli()) {
+ throw new RuntimeException("from(Instant) failed");
+ }
+ long nanos = v;
+ ft = FileTime.from(nanos, NANOSECONDS);
+ secs = nanos / 1000_000_000;
+ nanos = nanos % 1000_000_000;
+ instant = Instant.ofEpochSecond(secs, nanos);
+ if (!ft.equals(FileTime.from(instant))) {
+ throw new RuntimeException("from(Instant) failed");
+ }
+ }
+
// toString
ts(1L, DAYS, "1970-01-02T00:00:00Z");
ts(1L, HOURS, "1970-01-01T01:00:00Z");
@@ -108,11 +201,18 @@
// NTFS epoch in usec.
ts(-11644473600000000L, MICROSECONDS, "1601-01-01T00:00:00Z");
- // nulls
+ ts(Instant.MIN, "-1000000001-01-01T00:00:00Z");
+ ts(Instant.MAX, "1000000000-12-31T23:59:59.999999999Z");
+
try {
FileTime.from(0L, null);
throw new RuntimeException("NullPointerException expected");
} catch (NullPointerException npe) { }
+ try {
+ FileTime.from(null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException npe) { }
+
FileTime time = FileTime.fromMillis(now);
if (time.equals(null))
throw new RuntimeException("should not be equal to null");
@@ -120,6 +220,39 @@
time.compareTo(null);
throw new RuntimeException("NullPointerException expected");
} catch (NullPointerException npe) { }
+
+ // Instant + toMilli() overflow
+ overflow(Long.MAX_VALUE,
+ FileTime.from(Instant.MAX).toMillis());
+ overflow(Long.MAX_VALUE,
+ FileTime.from(Instant.ofEpochSecond(Long.MAX_VALUE / 1000 + 1))
+ .toMillis());
+ overflow(Long.MIN_VALUE,
+ FileTime.from(Instant.MIN).toMillis());
+ overflow(Long.MIN_VALUE,
+ FileTime.from(Instant.ofEpochSecond(Long.MIN_VALUE / 1000 - 1))
+ .toMillis());
+
+ // Instant + to(TimeUnit) overflow
+ overflow(Long.MAX_VALUE,
+ FileTime.from(Instant.ofEpochSecond(Long.MAX_VALUE / 1000 + 1))
+ .to(MILLISECONDS));
+ overflow(Long.MAX_VALUE,
+ FileTime.from(Instant.ofEpochSecond(Long.MAX_VALUE / 1000,
+ MILLISECONDS.toNanos(1000)))
+ .to(MILLISECONDS));
+ overflow(Long.MIN_VALUE,
+ FileTime.from(Instant.ofEpochSecond(Long.MIN_VALUE / 1000 - 1))
+ .to(MILLISECONDS));
+ overflow(Long.MIN_VALUE,
+ FileTime.from(Instant.ofEpochSecond(Long.MIN_VALUE / 1000,
+ -MILLISECONDS.toNanos(1)))
+ .to(MILLISECONDS));
+ }
+
+ static void overflow(long minmax, long v) {
+ if (v != minmax)
+ throw new RuntimeException("saturates to Long.MIN/MAX_VALUE expected");
}
static void cmp(long v1, TimeUnit u1, long v2, TimeUnit u2, int expected) {
@@ -128,6 +261,12 @@
throw new RuntimeException("unexpected order");
}
+ static void cmp(Instant ins, long v2, TimeUnit u2, int expected) {
+ int result = FileTime.from(ins).compareTo(FileTime.from(v2, u2));
+ if (result != expected)
+ throw new RuntimeException("unexpected order");
+ }
+
static void eq(long v1, TimeUnit u1, long v2, TimeUnit u2) {
FileTime t1 = FileTime.from(v1, u1);
FileTime t2 = FileTime.from(v2, u2);
@@ -137,6 +276,28 @@
throw new RuntimeException("hashCodes should be equal");
}
+ static void eq(Instant ins, long v2, TimeUnit u2) {
+ FileTime t1 = FileTime.from(ins);
+ FileTime t2 = FileTime.from(v2, u2);
+ if (!t1.equals(t2))
+ throw new RuntimeException("not equal");
+ if (t1.hashCode() != t2.hashCode())
+ throw new RuntimeException("hashCodes should be equal");
+ }
+
+ static void eqTime(long value, TimeUnit unit, Instant instant) {
+ long secs = SECONDS.convert(value, unit);
+ long nanos = NANOSECONDS.convert(value - unit.convert(secs, SECONDS), unit);
+ if (nanos < 0) { // normalize nanoOfSecond to positive
+ secs -= 1;
+ nanos += 1000_000_000;
+ }
+ if (secs != instant.getEpochSecond() || (int)nanos != instant.getNano()) {
+ System.err.println(" ins=" + instant);
+ throw new RuntimeException("ft and instant are not the same time point");
+ }
+ }
+
static void neq(long v1, TimeUnit u1, long v2, TimeUnit u2) {
FileTime t1 = FileTime.from(v1, u1);
FileTime t2 = FileTime.from(v2, u2);
@@ -144,6 +305,13 @@
throw new RuntimeException("should not be equal");
}
+ static void neq(Instant ins, long v2, TimeUnit u2) {
+ FileTime t1 = FileTime.from(ins);
+ FileTime t2 = FileTime.from(v2, u2);
+ if (t1.equals(t2))
+ throw new RuntimeException("should not be equal");
+ }
+
static void to(long v, TimeUnit unit) {
FileTime t = FileTime.from(v, unit);
for (TimeUnit u: TimeUnit.values()) {
@@ -164,4 +332,14 @@
throw new RuntimeException();
}
}
+
+ static void ts(Instant instant, String expected) {
+ String result = FileTime.from(instant).toString();
+ if (!result.equals(expected)) {
+ System.err.format("FileTime.from(%s).toString() failed\n", instant);
+ System.err.format("Expected: %s\n", expected);
+ System.err.format(" Got: %s\n", result);
+ throw new RuntimeException();
+ }
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Comparators/BasicTest.java Tue Apr 16 01:44:58 2013 -0700
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2012, 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 8001667 8010279
+ * @run testng BasicTest
+ */
+
+import java.util.Comparator;
+import java.util.Comparators;
+import java.util.AbstractMap;
+import java.util.Map;
+import org.testng.annotations.Test;
+
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+import java.util.function.ToDoubleFunction;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.fail;
+
+/**
+ * Unit tests for helper methods in Comparators
+ */
+@Test(groups = "unit")
+public class BasicTest {
+ private static class Thing {
+ public final int intField;
+ public final long longField;
+ public final double doubleField;
+ public final String stringField;
+
+ private Thing(int intField, long longField, double doubleField, String stringField) {
+ this.intField = intField;
+ this.longField = longField;
+ this.doubleField = doubleField;
+ this.stringField = stringField;
+ }
+
+ public int getIntField() {
+ return intField;
+ }
+
+ public long getLongField() {
+ return longField;
+ }
+
+ public double getDoubleField() {
+ return doubleField;
+ }
+
+ public String getStringField() {
+ return stringField;
+ }
+ }
+
+ private final int[] intValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+ private final long[] longValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+ private final double[] doubleValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+ private final String[] stringValues = { "a", "a", "b", "b", "c", "c", "d", "d", "e", "e" };
+ private final int[] comparisons = { 0, -1, 0, -1, 0, -1, 0, -1, 0 };
+
+ private<T> void assertComparisons(T[] things, Comparator<T> comp, int[] comparisons) {
+ for (int i=0; i<comparisons.length; i++) {
+ assertEquals(comparisons.length + 1, things.length);
+ assertEquals(comparisons[i], comp.compare(things[i], things[i+1]));
+ assertEquals(-comparisons[i], comp.compare(things[i+1], things[i]));
+ }
+ }
+
+ public void testIntComparator() {
+ Thing[] things = new Thing[intValues.length];
+ for (int i=0; i<intValues.length; i++)
+ things[i] = new Thing(intValues[i], 0L, 0.0, null);
+ Comparator<Thing> comp = Comparators.comparing(new ToIntFunction<BasicTest.Thing>() {
+ @Override
+ public int applyAsInt(Thing thing) {
+ return thing.getIntField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testLongComparator() {
+ Thing[] things = new Thing[longValues.length];
+ for (int i=0; i<longValues.length; i++)
+ things[i] = new Thing(0, longValues[i], 0.0, null);
+ Comparator<Thing> comp = Comparators.comparing(new ToLongFunction<BasicTest.Thing>() {
+ @Override
+ public long applyAsLong(Thing thing) {
+ return thing.getLongField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testDoubleComparator() {
+ Thing[] things = new Thing[doubleValues.length];
+ for (int i=0; i<doubleValues.length; i++)
+ things[i] = new Thing(0, 0L, doubleValues[i], null);
+ Comparator<Thing> comp = Comparators.comparing(new ToDoubleFunction<BasicTest.Thing>() {
+ @Override
+ public double applyAsDouble(Thing thing) {
+ return thing.getDoubleField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testComparing() {
+ Thing[] things = new Thing[doubleValues.length];
+ for (int i=0; i<doubleValues.length; i++)
+ things[i] = new Thing(0, 0L, 0.0, stringValues[i]);
+ Comparator<Thing> comp = Comparators.comparing(new Function<Thing, String>() {
+ @Override
+ public String apply(Thing thing) {
+ return thing.getStringField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testNaturalOrderComparator() {
+ Comparator<String> comp = Comparators.naturalOrder();
+
+ assertComparisons(stringValues, comp, comparisons);
+ }
+
+ public void testReverseComparator() {
+ Comparator<String> cmpr = Comparators.reverseOrder();
+ Comparator<String> cmp = cmpr.reverseOrder();
+
+ assertEquals(cmp.reverseOrder(), cmpr);
+ assertEquals(0, cmp.compare("a", "a"));
+ assertEquals(0, cmpr.compare("a", "a"));
+ assertTrue(cmp.compare("a", "b") < 0);
+ assertTrue(cmpr.compare("a", "b") > 0);
+ assertTrue(cmp.compare("b", "a") > 0);
+ assertTrue(cmpr.compare("b", "a") < 0);
+ }
+
+ public void testReverseComparator2() {
+ Comparator<String> cmp = (s1, s2) -> s1.length() - s2.length();
+ Comparator<String> cmpr = cmp.reverseOrder();
+
+ assertEquals(cmpr.reverseOrder(), cmp);
+ assertEquals(0, cmp.compare("abc", "def"));
+ assertEquals(0, cmpr.compare("abc", "def"));
+ assertTrue(cmp.compare("abcd", "def") > 0);
+ assertTrue(cmpr.compare("abcd", "def") < 0);
+ assertTrue(cmp.compare("abc", "defg") < 0);
+ assertTrue(cmpr.compare("abc", "defg") > 0);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void testReverseComparatorNPE() {
+ Comparator<String> cmp = Comparators.reverseOrder(null);
+ }
+
+ public void testComposeComparator() {
+ // Longer string in front
+ Comparator<String> first = (s1, s2) -> s2.length() - s1.length();
+ Comparator<String> second = Comparators.naturalOrder();
+ Comparator<String> composed = Comparators.compose(first, second);
+
+ assertTrue(composed.compare("abcdefg", "abcdef") < 0);
+ assertTrue(composed.compare("abcdef", "abcdefg") > 0);
+ assertTrue(composed.compare("abcdef", "abcdef") == 0);
+ assertTrue(composed.compare("abcdef", "ghijkl") < 0);
+ assertTrue(composed.compare("ghijkl", "abcdefg") > 0);
+ }
+
+ private <K, V> void assertPairComparison(K k1, V v1, K k2, V v2,
+ Comparator<Map.Entry<K, V>> ck,
+ Comparator<Map.Entry<K, V>> cv) {
+ final Map.Entry<K, V> p11 = new AbstractMap.SimpleImmutableEntry<>(k1, v1);
+ final Map.Entry<K, V> p12 = new AbstractMap.SimpleImmutableEntry<>(k1, v2);
+ final Map.Entry<K, V> p21 = new AbstractMap.SimpleImmutableEntry<>(k2, v1);
+ final Map.Entry<K, V> p22 = new AbstractMap.SimpleImmutableEntry<>(k2, v2);
+
+ assertTrue(ck.compare(p11, p11) == 0);
+ assertTrue(ck.compare(p12, p11) == 0);
+ assertTrue(ck.compare(p11, p12) == 0);
+ assertTrue(ck.compare(p12, p22) < 0);
+ assertTrue(ck.compare(p12, p21) < 0);
+ assertTrue(ck.compare(p21, p11) > 0);
+ assertTrue(ck.compare(p21, p12) > 0);
+
+ assertTrue(cv.compare(p11, p11) == 0);
+ assertTrue(cv.compare(p12, p11) > 0);
+ assertTrue(cv.compare(p11, p12) < 0);
+ assertTrue(cv.compare(p12, p22) == 0);
+ assertTrue(cv.compare(p12, p21) > 0);
+ assertTrue(cv.compare(p21, p11) == 0);
+ assertTrue(cv.compare(p21, p12) < 0);
+
+ Comparator<Map.Entry<K, V>> cmp = Comparators.compose(ck, cv);
+ assertTrue(cmp.compare(p11, p11) == 0);
+ assertTrue(cmp.compare(p12, p11) > 0);
+ assertTrue(cmp.compare(p11, p12) < 0);
+ assertTrue(cmp.compare(p12, p22) < 0);
+ assertTrue(cmp.compare(p12, p21) < 0);
+ assertTrue(cmp.compare(p21, p11) > 0);
+ assertTrue(cmp.compare(p21, p12) > 0);
+
+ cmp = Comparators.compose(cv, ck);
+ assertTrue(cmp.compare(p11, p11) == 0);
+ assertTrue(cmp.compare(p12, p11) > 0);
+ assertTrue(cmp.compare(p11, p12) < 0);
+ assertTrue(cmp.compare(p12, p22) < 0);
+ assertTrue(cmp.compare(p12, p21) > 0);
+ assertTrue(cmp.compare(p21, p11) > 0);
+ assertTrue(cmp.compare(p21, p12) < 0);
+ }
+
+ public void testKVComparatorable() {
+ assertPairComparison(1, "ABC", 2, "XYZ",
+ Comparators.<Integer, String>naturalOrderKeys(),
+ Comparators.<Integer, String>naturalOrderValues());
+ }
+
+ private static class People {
+ final String firstName;
+ final String lastName;
+ final int age;
+
+ People(String first, String last, int age) {
+ firstName = first;
+ lastName = last;
+ this.age = age;
+ }
+
+ String getFirstName() { return firstName; }
+ String getLastName() { return lastName; }
+ int getAge() { return age; }
+ long getAgeAsLong() { return (long) age; };
+ double getAgeAsDouble() { return (double) age; };
+ }
+
+ private final People people[] = {
+ new People("John", "Doe", 34),
+ new People("Mary", "Doe", 30),
+ new People("Maria", "Doe", 14),
+ new People("Jonah", "Doe", 10),
+ new People("John", "Cook", 54),
+ new People("Mary", "Cook", 50),
+ };
+
+ public void testKVComparators() {
+ // Comparator<People> cmp = Comparators.naturalOrder(); // Should fail to compiler as People is not comparable
+ // We can use simple comparator, but those have been tested above.
+ // Thus choose to do compose for some level of interation.
+ Comparator<People> cmp1 = Comparators.comparing((Function<People, String>) People::getFirstName);
+ Comparator<People> cmp2 = Comparators.comparing((Function<People, String>) People::getLastName);
+ Comparator<People> cmp = Comparators.compose(cmp1, cmp2);
+
+ assertPairComparison(people[0], people[0], people[1], people[1],
+ Comparators.<People, People>byKey(cmp),
+ Comparators.<People, People>byValue(cmp));
+
+ }
+
+ private <T> void assertComparison(Comparator<T> cmp, T less, T greater) {
+ assertTrue(cmp.compare(less, greater) < 0, "less");
+ assertTrue(cmp.compare(less, less) == 0, "equal");
+ assertTrue(cmp.compare(greater, less) > 0, "greater");
+ }
+
+ public void testComparatorDefaultMethods() {
+ Comparator<People> cmp = Comparators.comparing((Function<People, String>) People::getFirstName);
+ Comparator<People> cmp2 = Comparators.comparing((Function<People, String>) People::getLastName);
+ // reverseOrder
+ assertComparison(cmp.reverseOrder(), people[1], people[0]);
+ // thenComparing(Comparator)
+ assertComparison(cmp.thenComparing(cmp2), people[0], people[1]);
+ assertComparison(cmp.thenComparing(cmp2), people[4], people[0]);
+ // thenComparing(Function)
+ assertComparison(cmp.thenComparing(People::getLastName), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getLastName), people[4], people[0]);
+ // thenComparing(ToIntFunction)
+ assertComparison(cmp.thenComparing(People::getAge), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getAge), people[1], people[5]);
+ // thenComparing(ToLongFunction)
+ assertComparison(cmp.thenComparing(People::getAgeAsLong), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getAgeAsLong), people[1], people[5]);
+ // thenComparing(ToDoubleFunction)
+ assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[1], people[5]);
+ }
+
+ public void testGreaterOf() {
+ // lesser
+ assertSame(Comparators.greaterOf(Comparators.comparing(
+ (Function<People, String>) People::getFirstName))
+ .apply(people[0], people[1]),
+ people[1]);
+ // euqal
+ assertSame(Comparators.greaterOf(Comparators.comparing(
+ (Function<People, String>) People::getLastName))
+ .apply(people[0], people[1]),
+ people[0]);
+ // greater
+ assertSame(Comparators.greaterOf(Comparators.comparing(
+ (ToIntFunction<People>) People::getAge))
+ .apply(people[0], people[1]),
+ people[0]);
+ }
+
+ public void testLesserOf() {
+ // lesser
+ assertSame(Comparators.lesserOf(Comparators.comparing(
+ (Function<People, String>) People::getFirstName))
+ .apply(people[0], people[1]),
+ people[0]);
+ // euqal
+ assertSame(Comparators.lesserOf(Comparators.comparing(
+ (Function<People, String>) People::getLastName))
+ .apply(people[0], people[1]),
+ people[0]);
+ // greater
+ assertSame(Comparators.lesserOf(Comparators.comparing(
+ (ToIntFunction<People>) People::getAge))
+ .apply(people[0], people[1]),
+ people[1]);
+ }
+
+ public void testNulls() {
+ try {
+ Comparators.<String>naturalOrder().compare("abc", (String) null);
+ fail("expected NPE with naturalOrder");
+ } catch (NullPointerException npe) {}
+ try {
+ Comparators.<String>naturalOrder().compare((String) null, "abc");
+ fail("expected NPE with naturalOrder");
+ } catch (NullPointerException npe) {}
+
+ try {
+ Comparators.<String>reverseOrder().compare("abc", (String) null);
+ fail("expected NPE with naturalOrder");
+ } catch (NullPointerException npe) {}
+ try {
+ Comparators.<String>reverseOrder().compare((String) null, "abc");
+ fail("expected NPE with naturalOrder");
+ } catch (NullPointerException npe) {}
+
+ try {
+ Comparator<Map.Entry<String, String>> cmp = Comparators.byKey(null);
+ fail("byKey(null) should throw NPE");
+ } catch (NullPointerException npe) {}
+
+ try {
+ Comparator<Map.Entry<String, String>> cmp = Comparators.byValue(null);
+ fail("byValue(null) should throw NPE");
+ } catch (NullPointerException npe) {}
+
+ try {
+ Comparator<People> cmp = Comparators.comparing((Function<People, String>) null);
+ fail("comparing(null) should throw NPE");
+ } catch (NullPointerException npe) {}
+ try {
+ Comparator<People> cmp = Comparators.comparing((ToIntFunction<People>) null);
+ fail("comparing(null) should throw NPE");
+ } catch (NullPointerException npe) {}
+ try {
+ Comparator<People> cmp = Comparators.comparing((ToLongFunction<People>) null);
+ fail("comparing(null) should throw NPE");
+ } catch (NullPointerException npe) {}
+ try {
+ Comparator<People> cmp = Comparators.comparing((ToDoubleFunction<People>) null);
+ fail("comparing(null) should throw NPE");
+ } catch (NullPointerException npe) {}
+
+ try {
+ BinaryOperator<String> op = Comparators.lesserOf(null);
+ fail("lesserOf(null) should throw NPE");
+ } catch (NullPointerException npe) {}
+
+ try {
+ BinaryOperator<String> op = Comparators.greaterOf(null);
+ fail("lesserOf(null) should throw NPE");
+ } catch (NullPointerException npe) {}
+ }
+}
--- a/jdk/test/java/util/ComparatorsTest.java Fri Apr 12 10:42:50 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,353 +0,0 @@
-/*
- * Copyright (c) 2012, 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 8001667
- * @run testng ComparatorsTest
- */
-
-import java.util.Comparator;
-import java.util.Comparators;
-import java.util.AbstractMap;
-import java.util.Map;
-import org.testng.annotations.Test;
-
-import java.util.function.Function;
-import java.util.function.ToIntFunction;
-import java.util.function.ToLongFunction;
-import java.util.function.ToDoubleFunction;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.assertSame;
-
-/**
- * Unit tests for helper methods in Comparators
- */
-@Test(groups = "unit")
-public class ComparatorsTest {
- private static class Thing {
- public final int intField;
- public final long longField;
- public final double doubleField;
- public final String stringField;
-
- private Thing(int intField, long longField, double doubleField, String stringField) {
- this.intField = intField;
- this.longField = longField;
- this.doubleField = doubleField;
- this.stringField = stringField;
- }
-
- public int getIntField() {
- return intField;
- }
-
- public long getLongField() {
- return longField;
- }
-
- public double getDoubleField() {
- return doubleField;
- }
-
- public String getStringField() {
- return stringField;
- }
- }
-
- private final int[] intValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
- private final long[] longValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
- private final double[] doubleValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
- private final String[] stringValues = { "a", "a", "b", "b", "c", "c", "d", "d", "e", "e" };
- private final int[] comparisons = { 0, -1, 0, -1, 0, -1, 0, -1, 0 };
-
- private<T> void assertComparisons(T[] things, Comparator<T> comp, int[] comparisons) {
- for (int i=0; i<comparisons.length; i++) {
- assertEquals(comparisons.length + 1, things.length);
- assertEquals(comparisons[i], comp.compare(things[i], things[i+1]));
- assertEquals(-comparisons[i], comp.compare(things[i+1], things[i]));
- }
- }
-
- public void testIntComparator() {
- Thing[] things = new Thing[intValues.length];
- for (int i=0; i<intValues.length; i++)
- things[i] = new Thing(intValues[i], 0L, 0.0, null);
- Comparator<Thing> comp = Comparators.comparing(new ToIntFunction<ComparatorsTest.Thing>() {
- @Override
- public int applyAsInt(Thing thing) {
- return thing.getIntField();
- }
- });
-
- assertComparisons(things, comp, comparisons);
- }
-
- public void testLongComparator() {
- Thing[] things = new Thing[longValues.length];
- for (int i=0; i<longValues.length; i++)
- things[i] = new Thing(0, longValues[i], 0.0, null);
- Comparator<Thing> comp = Comparators.comparing(new ToLongFunction<ComparatorsTest.Thing>() {
- @Override
- public long applyAsLong(Thing thing) {
- return thing.getLongField();
- }
- });
-
- assertComparisons(things, comp, comparisons);
- }
-
- public void testDoubleComparator() {
- Thing[] things = new Thing[doubleValues.length];
- for (int i=0; i<doubleValues.length; i++)
- things[i] = new Thing(0, 0L, doubleValues[i], null);
- Comparator<Thing> comp = Comparators.comparing(new ToDoubleFunction<ComparatorsTest.Thing>() {
- @Override
- public double applyAsDouble(Thing thing) {
- return thing.getDoubleField();
- }
- });
-
- assertComparisons(things, comp, comparisons);
- }
-
- public void testComparing() {
- Thing[] things = new Thing[doubleValues.length];
- for (int i=0; i<doubleValues.length; i++)
- things[i] = new Thing(0, 0L, 0.0, stringValues[i]);
- Comparator<Thing> comp = Comparators.comparing(new Function<Thing, String>() {
- @Override
- public String apply(Thing thing) {
- return thing.getStringField();
- }
- });
-
- assertComparisons(things, comp, comparisons);
- }
-
- public void testNaturalOrderComparator() {
- Comparator<String> comp = Comparators.naturalOrder();
-
- assertComparisons(stringValues, comp, comparisons);
- }
-
- public void testReverseComparator() {
- Comparator<String> cmpr = Comparators.reverseOrder();
- Comparator<String> cmp = cmpr.reverseOrder();
-
- assertEquals(cmp.reverseOrder(), cmpr);
- assertEquals(0, cmp.compare("a", "a"));
- assertEquals(0, cmpr.compare("a", "a"));
- assertTrue(cmp.compare("a", "b") < 0);
- assertTrue(cmpr.compare("a", "b") > 0);
- assertTrue(cmp.compare("b", "a") > 0);
- assertTrue(cmpr.compare("b", "a") < 0);
- }
-
- public void testReverseComparator2() {
- Comparator<String> cmp = (s1, s2) -> s1.length() - s2.length();
- Comparator<String> cmpr = cmp.reverseOrder();
-
- assertEquals(cmpr.reverseOrder(), cmp);
- assertEquals(0, cmp.compare("abc", "def"));
- assertEquals(0, cmpr.compare("abc", "def"));
- assertTrue(cmp.compare("abcd", "def") > 0);
- assertTrue(cmpr.compare("abcd", "def") < 0);
- assertTrue(cmp.compare("abc", "defg") < 0);
- assertTrue(cmpr.compare("abc", "defg") > 0);
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void testReverseComparatorNPE() {
- Comparator<String> cmp = Comparators.reverseOrder(null);
- }
-
- public void testComposeComparator() {
- // Longer string in front
- Comparator<String> first = (s1, s2) -> s2.length() - s1.length();
- Comparator<String> second = Comparators.naturalOrder();
- Comparator<String> composed = Comparators.compose(first, second);
-
- assertTrue(composed.compare("abcdefg", "abcdef") < 0);
- assertTrue(composed.compare("abcdef", "abcdefg") > 0);
- assertTrue(composed.compare("abcdef", "abcdef") == 0);
- assertTrue(composed.compare("abcdef", "ghijkl") < 0);
- assertTrue(composed.compare("ghijkl", "abcdefg") > 0);
- }
-
- private <K, V> void assertPairComparison(K k1, V v1, K k2, V v2,
- Comparator<Map.Entry<K, V>> ck,
- Comparator<Map.Entry<K, V>> cv) {
- final Map.Entry<K, V> p11 = new AbstractMap.SimpleImmutableEntry<>(k1, v1);
- final Map.Entry<K, V> p12 = new AbstractMap.SimpleImmutableEntry<>(k1, v2);
- final Map.Entry<K, V> p21 = new AbstractMap.SimpleImmutableEntry<>(k2, v1);
- final Map.Entry<K, V> p22 = new AbstractMap.SimpleImmutableEntry<>(k2, v2);
-
- assertTrue(ck.compare(p11, p11) == 0);
- assertTrue(ck.compare(p12, p11) == 0);
- assertTrue(ck.compare(p11, p12) == 0);
- assertTrue(ck.compare(p12, p22) < 0);
- assertTrue(ck.compare(p12, p21) < 0);
- assertTrue(ck.compare(p21, p11) > 0);
- assertTrue(ck.compare(p21, p12) > 0);
-
- assertTrue(cv.compare(p11, p11) == 0);
- assertTrue(cv.compare(p12, p11) > 0);
- assertTrue(cv.compare(p11, p12) < 0);
- assertTrue(cv.compare(p12, p22) == 0);
- assertTrue(cv.compare(p12, p21) > 0);
- assertTrue(cv.compare(p21, p11) == 0);
- assertTrue(cv.compare(p21, p12) < 0);
-
- Comparator<Map.Entry<K, V>> cmp = Comparators.compose(ck, cv);
- assertTrue(cmp.compare(p11, p11) == 0);
- assertTrue(cmp.compare(p12, p11) > 0);
- assertTrue(cmp.compare(p11, p12) < 0);
- assertTrue(cmp.compare(p12, p22) < 0);
- assertTrue(cmp.compare(p12, p21) < 0);
- assertTrue(cmp.compare(p21, p11) > 0);
- assertTrue(cmp.compare(p21, p12) > 0);
-
- cmp = Comparators.compose(cv, ck);
- assertTrue(cmp.compare(p11, p11) == 0);
- assertTrue(cmp.compare(p12, p11) > 0);
- assertTrue(cmp.compare(p11, p12) < 0);
- assertTrue(cmp.compare(p12, p22) < 0);
- assertTrue(cmp.compare(p12, p21) > 0);
- assertTrue(cmp.compare(p21, p11) > 0);
- assertTrue(cmp.compare(p21, p12) < 0);
- }
-
- public void testKVComparatorable() {
- assertPairComparison(1, "ABC", 2, "XYZ",
- Comparators.<Integer, String>naturalOrderKeys(),
- Comparators.<Integer, String>naturalOrderValues());
- }
-
- private static class People {
- final String firstName;
- final String lastName;
- final int age;
-
- People(String first, String last, int age) {
- firstName = first;
- lastName = last;
- this.age = age;
- }
-
- String getFirstName() { return firstName; }
- String getLastName() { return lastName; }
- int getAge() { return age; }
- long getAgeAsLong() { return (long) age; };
- double getAgeAsDouble() { return (double) age; };
- }
-
- private final People people[] = {
- new People("John", "Doe", 34),
- new People("Mary", "Doe", 30),
- new People("Maria", "Doe", 14),
- new People("Jonah", "Doe", 10),
- new People("John", "Cook", 54),
- new People("Mary", "Cook", 50),
- };
-
- public void testKVComparators() {
- // Comparator<People> cmp = Comparators.naturalOrder(); // Should fail to compiler as People is not comparable
- // We can use simple comparator, but those have been tested above.
- // Thus choose to do compose for some level of interation.
- Comparator<People> cmp1 = Comparators.comparing((Function<People, String>) People::getFirstName);
- Comparator<People> cmp2 = Comparators.comparing((Function<People, String>) People::getLastName);
- Comparator<People> cmp = Comparators.compose(cmp1, cmp2);
-
- assertPairComparison(people[0], people[0], people[1], people[1],
- Comparators.<People, People>byKey(cmp),
- Comparators.<People, People>byValue(cmp));
-
- }
-
- private <T> void assertComparison(Comparator<T> cmp, T less, T greater) {
- assertTrue(cmp.compare(less, greater) < 0, "less");
- assertTrue(cmp.compare(less, less) == 0, "equal");
- assertTrue(cmp.compare(greater, less) > 0, "greater");
- }
-
- public void testComparatorDefaultMethods() {
- Comparator<People> cmp = Comparators.comparing((Function<People, String>) People::getFirstName);
- Comparator<People> cmp2 = Comparators.comparing((Function<People, String>) People::getLastName);
- // reverseOrder
- assertComparison(cmp.reverseOrder(), people[1], people[0]);
- // thenComparing(Comparator)
- assertComparison(cmp.thenComparing(cmp2), people[0], people[1]);
- assertComparison(cmp.thenComparing(cmp2), people[4], people[0]);
- // thenComparing(Function)
- assertComparison(cmp.thenComparing(People::getLastName), people[0], people[1]);
- assertComparison(cmp.thenComparing(People::getLastName), people[4], people[0]);
- // thenComparing(ToIntFunction)
- assertComparison(cmp.thenComparing(People::getAge), people[0], people[1]);
- assertComparison(cmp.thenComparing(People::getAge), people[1], people[5]);
- // thenComparing(ToLongFunction)
- assertComparison(cmp.thenComparing(People::getAgeAsLong), people[0], people[1]);
- assertComparison(cmp.thenComparing(People::getAgeAsLong), people[1], people[5]);
- // thenComparing(ToDoubleFunction)
- assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[0], people[1]);
- assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[1], people[5]);
- }
-
- public void testGreaterOf() {
- // lesser
- assertSame(Comparators.greaterOf(Comparators.comparing(
- (Function<People, String>) People::getFirstName))
- .apply(people[0], people[1]),
- people[1]);
- // euqal
- assertSame(Comparators.greaterOf(Comparators.comparing(
- (Function<People, String>) People::getLastName))
- .apply(people[0], people[1]),
- people[0]);
- // greater
- assertSame(Comparators.greaterOf(Comparators.comparing(
- (ToIntFunction<People>) People::getAge))
- .apply(people[0], people[1]),
- people[0]);
- }
-
- public void testLesserOf() {
- // lesser
- assertSame(Comparators.lesserOf(Comparators.comparing(
- (Function<People, String>) People::getFirstName))
- .apply(people[0], people[1]),
- people[0]);
- // euqal
- assertSame(Comparators.lesserOf(Comparators.comparing(
- (Function<People, String>) People::getLastName))
- .apply(people[0], people[1]),
- people[0]);
- // greater
- assertSame(Comparators.lesserOf(Comparators.comparing(
- (ToIntFunction<People>) People::getAge))
- .apply(people[0], people[1]),
- people[1]);
- }
-}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Map/BasicSerialization.java Tue Apr 16 01:44:58 2013 -0700
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012, 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 8011200
+ * @run testng BasicSerialization
+ * @summary Ensure Maps can be serialized and deserialized.
+ * @author Mike Duigou
+ */
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayInputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.fail;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertSame;
+
+public class BasicSerialization {
+
+ enum IntegerEnum {
+
+ e0, e1, e2, e3, e4, e5, e6, e7, e8, e9,
+ e10, e11, e12, e13, e14, e15, e16, e17, e18, e19,
+ e20, e21, e22, e23, e24, e25, e26, e27, e28, e29,
+ e30, e31, e32, e33, e34, e35, e36, e37, e38, e39,
+ e40, e41, e42, e43, e44, e45, e46, e47, e48, e49,
+ e50, e51, e52, e53, e54, e55, e56, e57, e58, e59,
+ e60, e61, e62, e63, e64, e65, e66, e67, e68, e69,
+ e70, e71, e72, e73, e74, e75, e76, e77, e78, e79,
+ e80, e81, e82, e83, e84, e85, e86, e87, e88, e89,
+ e90, e91, e92, e93, e94, e95, e96, e97, e98, e99,
+ EXTRA_KEY;
+ public static final int SIZE = values().length;
+ };
+ private static final int TEST_SIZE = IntegerEnum.SIZE - 1;
+ /**
+ * Realized keys ensure that there is always a hard ref to all test objects.
+ */
+ private static final IntegerEnum[] KEYS = new IntegerEnum[TEST_SIZE];
+ /**
+ * Realized values ensure that there is always a hard ref to all test
+ * objects.
+ */
+ private static final String[] VALUES = new String[TEST_SIZE];
+
+ static {
+ IntegerEnum[] keys = IntegerEnum.values();
+ for (int each = 0; each < TEST_SIZE; each++) {
+ KEYS[each] = keys[each];
+ VALUES[each] = keys[each].name();
+ }
+ }
+ private static final IntegerEnum EXTRA_KEY = IntegerEnum.EXTRA_KEY;
+ private static final String EXTRA_VALUE = IntegerEnum.EXTRA_KEY.name();
+
+ public static <K, V> Map<K, V> mapClone(Map<K, V> map) {
+ Method cloneMethod;
+
+ try {
+ cloneMethod = map.getClass().getMethod("clone", new Class[]{});
+ } catch (NoSuchMethodException | SecurityException all) {
+ cloneMethod = null;
+ }
+
+ if (null != cloneMethod) {
+ try {
+ Map<K, V> result = (Map<K, V>)cloneMethod.invoke(map, new Object[]{});
+ return result;
+ } catch (Exception all) {
+ fail("clone() failed " + map.getClass().getSimpleName(), all);
+ return null;
+ }
+ } else {
+ Constructor<? extends Map> copyConstructor;
+ try {
+ copyConstructor = (Constructor<? extends Map>)map.getClass().getConstructor(new Class[]{Map.class});
+
+ Map<K, V> result = (Map<K, V>)copyConstructor.newInstance(new Object[]{map});
+
+ return result;
+ } catch (Exception all) {
+ return serialClone(map);
+ }
+ }
+ }
+
+ @Test(dataProvider = "Map<IntegerEnum,String>")
+ public void testSerialization(String description, Map<IntegerEnum, String> map) {
+ Object foo = new Object();
+
+ Map<IntegerEnum, String> clone = mapClone(map);
+ Map<IntegerEnum, String> serialClone = serialClone(map);
+
+ assertEquals(map, map, description + ":should equal self");
+ assertEquals(clone, map, description + ":should equal clone");
+ assertEquals(map, clone, description + ": should equal orginal map");
+ assertEquals(serialClone, map, description + ": should equal deserialized clone");
+ assertEquals(map, serialClone, description + ": should equal original map");
+ assertEquals(serialClone, clone, description + ": deserialized clone should equal clone");
+ assertEquals(clone, serialClone, description + ": clone should equal deserialized clone");
+
+ assertFalse(map.containsKey(EXTRA_KEY), description + ":unexpected key");
+ assertFalse(clone.containsKey(EXTRA_KEY), description + ":unexpected key");
+ assertFalse(serialClone.containsKey(EXTRA_KEY), description + ":unexpected key");
+ map.put(EXTRA_KEY, EXTRA_VALUE);
+ clone.put(EXTRA_KEY, EXTRA_VALUE);
+ serialClone.put(EXTRA_KEY, EXTRA_VALUE);
+ assertTrue(map.containsKey(EXTRA_KEY), description + ":missing key");
+ assertTrue(clone.containsKey(EXTRA_KEY), description + ":missing key");
+ assertTrue(serialClone.containsKey(EXTRA_KEY), description + ":missing key");
+ assertSame(map.get(EXTRA_KEY), EXTRA_VALUE, description + ":wrong value");
+ assertSame(clone.get(EXTRA_KEY), EXTRA_VALUE, description + ":wrong value");
+ assertSame(serialClone.get(EXTRA_KEY), EXTRA_VALUE, description + ":wrong value");
+
+ assertEquals(map, map, description + ":should equal self");
+ assertEquals(clone, map, description + ":should equal clone");
+ assertEquals(map, clone, description + ": should equal orginal map");
+ assertEquals(serialClone, map, description + ": should equal deserialized clone");
+ assertEquals(map, serialClone, description + ": should equal original map");
+ assertEquals(serialClone, clone, description + ": deserialized clone should equal clone");
+ assertEquals(clone, serialClone, description + ": clone should equal deserialized clone");
+ }
+
+ static byte[] serializedForm(Object obj) {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ new ObjectOutputStream(baos).writeObject(obj);
+ return baos.toByteArray();
+ } catch (IOException e) {
+ fail("Unexpected Exception", e);
+ return null;
+ }
+ }
+
+ static Object readObject(byte[] bytes) throws IOException, ClassNotFoundException {
+ InputStream is = new ByteArrayInputStream(bytes);
+ return new ObjectInputStream(is).readObject();
+ }
+
+ @SuppressWarnings("unchecked")
+ static <T> T serialClone(T obj) {
+ try {
+ return (T)readObject(serializedForm(obj));
+ } catch (IOException | ClassNotFoundException e) {
+ fail("Unexpected Exception", e);
+ return null;
+ }
+ }
+
+ @DataProvider(name = "Map<IntegerEnum,String>", parallel = true)
+ private static Iterator<Object[]> makeMaps() {
+ return Arrays.asList(
+ // empty
+ new Object[]{"HashMap", new HashMap()},
+ new Object[]{"LinkedHashMap", new LinkedHashMap()},
+ new Object[]{"Collections.checkedMap(HashMap)", Collections.checkedMap(new HashMap(), IntegerEnum.class, String.class)},
+ new Object[]{"Collections.synchronizedMap(HashMap)", Collections.synchronizedMap(new HashMap())},
+ // null hostile
+ new Object[]{"EnumMap", new EnumMap(IntegerEnum.class)},
+ new Object[]{"Hashtable", new Hashtable()},
+ new Object[]{"TreeMap", new TreeMap()},
+ new Object[]{"ConcurrentHashMap", new ConcurrentHashMap()},
+ new Object[]{"ConcurrentSkipListMap", new ConcurrentSkipListMap()},
+ new Object[]{"Collections.checkedMap(ConcurrentHashMap)", Collections.checkedMap(new ConcurrentHashMap(), IntegerEnum.class, String.class)},
+ new Object[]{"Collections.synchronizedMap(EnumMap)", Collections.synchronizedMap(new EnumMap(IntegerEnum.class))},
+ // filled
+ new Object[]{"HashMap", fillMap(new HashMap())},
+ new Object[]{"LinkedHashMap", fillMap(new LinkedHashMap())},
+ new Object[]{"Collections.checkedMap(HashMap)", Collections.checkedMap(fillMap(new HashMap()), IntegerEnum.class, String.class)},
+ new Object[]{"Collections.synchronizedMap(HashMap)", Collections.synchronizedMap(fillMap(new HashMap()))},
+ // null hostile
+ new Object[]{"EnumMap", fillMap(new EnumMap(IntegerEnum.class))},
+ new Object[]{"Hashtable", fillMap(new Hashtable())},
+ new Object[]{"TreeMap", fillMap(new TreeMap())},
+ new Object[]{"ConcurrentHashMap", fillMap(new ConcurrentHashMap())},
+ new Object[]{"ConcurrentSkipListMap", fillMap(new ConcurrentSkipListMap())},
+ new Object[]{"Collections.checkedMap(ConcurrentHashMap)", Collections.checkedMap(fillMap(new ConcurrentHashMap()), IntegerEnum.class, String.class)},
+ new Object[]{"Collections.synchronizedMap(EnumMap)", Collections.synchronizedMap(fillMap(new EnumMap(IntegerEnum.class)))}).iterator();
+ }
+
+ private static Map<IntegerEnum, String> fillMap(Map<IntegerEnum, String> result) {
+ for (int each = 0; each < TEST_SIZE; each++) {
+ result.put(KEYS[each], VALUES[each]);
+ }
+
+ return result;
+ }
+}
--- a/jdk/test/java/util/Objects/BasicObjectsTest.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/test/java/util/Objects/BasicObjectsTest.java Tue Apr 16 01:44:58 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -23,12 +23,13 @@
/*
* @test
- * @bug 6797535 6889858 6891113
+ * @bug 6797535 6889858 6891113 8011800
* @summary Basic tests for methods in java.util.Objects
* @author Joseph D. Darcy
*/
import java.util.*;
+import java.util.function.*;
public class BasicObjectsTest {
public static void main(String... args) {
@@ -40,7 +41,7 @@
errors += testToString();
errors += testToString2();
errors += testCompare();
- errors += testNonNull();
+ errors += testRequireNonNull();
if (errors > 0 )
throw new RuntimeException();
}
@@ -158,49 +159,54 @@
return errors;
}
- private static int testNonNull() {
+ private static int testRequireNonNull() {
int errors = 0;
- String s;
+
+ final String RNN_1 = "1-arg requireNonNull";
+ final String RNN_2 = "2-arg requireNonNull";
+ final String RNN_3 = "Supplier requireNonNull";
+
+ Function<String, String> rnn1 = s -> Objects.requireNonNull(s);
+ Function<String, String> rnn2 = s -> Objects.requireNonNull(s, "trousers");
+ Function<String, String> rnn3 = s -> Objects.requireNonNull(s, () -> "trousers");
- // Test 1-arg variant
+ errors += testRNN_NonNull(rnn1, RNN_1);
+ errors += testRNN_NonNull(rnn2, RNN_2);
+ errors += testRNN_NonNull(rnn3, RNN_3);
+
+ errors += testRNN_Null(rnn1, RNN_1, null);
+ errors += testRNN_Null(rnn2, RNN_2, "trousers");
+ errors += testRNN_Null(rnn3, RNN_3, "trousers");
+ return errors;
+ }
+
+ private static int testRNN_NonNull(Function<String, String> testFunc,
+ String testFuncName) {
+ int errors = 0;
try {
- s = Objects.requireNonNull("pants");
+ String s = testFunc.apply("pants");
if (s != "pants") {
- System.err.printf("1-arg non-null failed to return its arg");
+ System.err.printf(testFuncName + " failed to return its arg");
errors++;
}
} catch (NullPointerException e) {
- System.err.printf("1-arg nonNull threw unexpected NPE");
+ System.err.printf(testFuncName + " threw unexpected NPE");
errors++;
}
+ return errors;
+ }
+ private static int testRNN_Null(Function<String, String> testFunc,
+ String testFuncName,
+ String expectedMessage) {
+ int errors = 0;
try {
- s = Objects.requireNonNull(null);
- System.err.printf("1-arg nonNull failed to throw NPE");
+ String s = testFunc.apply(null);
+ System.err.printf(testFuncName + " failed to throw NPE");
errors++;
} catch (NullPointerException e) {
- // Expected
- }
-
- // Test 2-arg variant
- try {
- s = Objects.requireNonNull("pants", "trousers");
- if (s != "pants") {
- System.err.printf("2-arg nonNull failed to return its arg");
- errors++;
- }
- } catch (NullPointerException e) {
- System.err.printf("2-arg nonNull threw unexpected NPE");
- errors++;
- }
-
- try {
- s = Objects.requireNonNull(null, "pantaloons");
- System.err.printf("2-arg nonNull failed to throw NPE");
- errors++;
- } catch (NullPointerException e) {
- if (e.getMessage() != "pantaloons") {
- System.err.printf("2-arg nonNull threw NPE w/ bad detail msg");
+ if (e.getMessage() != expectedMessage) {
+ System.err.printf(testFuncName + " threw NPE w/ bad detail msg");
errors++;
}
}
--- a/jdk/test/java/util/concurrent/CompletableFuture/Basic.java Fri Apr 12 10:42:50 2013 -0700
+++ b/jdk/test/java/util/concurrent/CompletableFuture/Basic.java Tue Apr 16 01:44:58 2013 -0700
@@ -486,40 +486,40 @@
CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
cf3 = cf1.applyToEither(cf2, (x) -> { check(x == 1 || x == 2); return x; });
+ checkCompletedNormally(cf3, new Object[] {1, 2});
check(cf1.isDone() || cf2.isDone());
- checkCompletedNormally(cf3, new Object[] {1, 2});
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> 2);
cf3 = cf1.applyToEitherAsync(cf2, (x) -> { check(x == 1 || x == 2); return x; });
+ checkCompletedNormally(cf3, new Object[] {1, 2});
check(cf1.isDone() || cf2.isDone());
- checkCompletedNormally(cf3, new Object[] {1, 2});
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> 2);
cf3 = cf1.applyToEitherAsync(cf2, (x) -> { check(x == 1 || x == 2); return x; }, executor);
+ checkCompletedNormally(cf3, new Object[] {1, 2});
check(cf1.isDone() || cf2.isDone());
- checkCompletedNormally(cf3, new Object[] {1, 2});
cf1 = supplyAsync(() -> { throw new RuntimeException(); });
cf2 = supplyAsync(() -> 2);
cf3 = cf1.applyToEither(cf2, (x) -> { check(x == 2); return x; });
- check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == 1); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
+ check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> { throw new RuntimeException(); });
cf3 = cf1.applyToEitherAsync(cf2, (x) -> { check(x == 1); return x; });
- check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == 1); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
+ check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> { throw new RuntimeException(); });
cf2 = supplyAsync(() -> { throw new RuntimeException(); });
cf3 = cf1.applyToEitherAsync(cf2, (x) -> { fail(); return x; });
+ checkCompletedExceptionally(cf3);
check(cf1.isDone() || cf2.isDone());
- checkCompletedExceptionally(cf3);
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
@@ -531,45 +531,45 @@
CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
cf3 = cf1.acceptEither(cf2, (x) -> { check(x == 1 || x == 2); atomicInt.incrementAndGet(); });
+ checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
- checkCompletedNormally(cf3, null);
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> 2);
cf3 = cf1.acceptEitherAsync(cf2, (x) -> { check(x == 1 || x == 2); atomicInt.incrementAndGet(); });
+ checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
- checkCompletedNormally(cf3, null);
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> 2);
cf3 = cf2.acceptEitherAsync(cf1, (x) -> { check(x == 1 || x == 2); atomicInt.incrementAndGet(); }, executor);
+ checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
- checkCompletedNormally(cf3, null);
check(atomicInt.get() == (before + 1));
cf1 = supplyAsync(() -> { throw new RuntimeException(); });
cf2 = supplyAsync(() -> 2);
cf3 = cf2.acceptEitherAsync(cf1, (x) -> { check(x == 2); }, executor);
- check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == null); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
+ check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> { throw new RuntimeException(); });
cf3 = cf2.acceptEitherAsync(cf1, (x) -> { check(x == 1); });
- check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == null); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
+ check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> { throw new RuntimeException(); });
cf2 = supplyAsync(() -> { throw new RuntimeException(); });
cf3 = cf2.acceptEitherAsync(cf1, (x) -> { fail(); });
+ checkCompletedExceptionally(cf3);
check(cf1.isDone() || cf2.isDone());
- checkCompletedExceptionally(cf3);
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
@@ -581,50 +581,50 @@
CompletableFuture<Void> cf1 = runAsync(() -> { });
CompletableFuture<Void> cf2 = runAsync(() -> { });
cf3 = cf1.runAfterEither(cf2, () -> { atomicInt.incrementAndGet(); });
+ checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
- checkCompletedNormally(cf3, null);
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = runAsync(() -> { });
cf2 = runAsync(() -> { });
cf3 = cf1.runAfterEitherAsync(cf2, () -> { atomicInt.incrementAndGet(); });
+ checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
- checkCompletedNormally(cf3, null);
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = runAsync(() -> { });
cf2 = runAsync(() -> { });
cf3 = cf2.runAfterEitherAsync(cf1, () -> { atomicInt.incrementAndGet(); }, executor);
+ checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
- checkCompletedNormally(cf3, null);
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = runAsync(() -> { throw new RuntimeException(); });
cf2 = runAsync(() -> { });
cf3 = cf2.runAfterEither(cf1, () -> { atomicInt.incrementAndGet(); });
- check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == null); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
+ check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = runAsync(() -> { });
cf2 = runAsync(() -> { throw new RuntimeException(); });
cf3 = cf1.runAfterEitherAsync(cf2, () -> { atomicInt.incrementAndGet(); });
- check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == null); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
+ check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = runAsync(() -> { throw new RuntimeException(); });
cf2 = runAsync(() -> { throw new RuntimeException(); });
cf3 = cf2.runAfterEitherAsync(cf1, () -> { atomicInt.incrementAndGet(); }, executor);
+ checkCompletedExceptionally(cf3);
check(cf1.isDone() || cf2.isDone());
- checkCompletedExceptionally(cf3);
check(atomicInt.get() == before);
} catch (Throwable t) { unexpected(t); }
@@ -670,16 +670,16 @@
//----------------------------------------------------------------
// anyOf tests
//----------------------------------------------------------------
- //try {
- // CompletableFuture<Object> cf3;
- // for (int k=0; k < 10; k++){
- // CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
- // CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
- // cf3 = CompletableFuture.anyOf(cf1, cf2);
- // check(cf1.isDone() || cf2.isDone());
- // checkCompletedNormally(cf3, new Object[] {1, 2});
- // }
- //} catch (Throwable t) { unexpected(t); }
+ try {
+ CompletableFuture<Object> cf3;
+ for (int k=0; k < 10; k++){
+ CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
+ CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
+ cf3 = CompletableFuture.anyOf(cf1, cf2);
+ checkCompletedNormally(cf3, new Object[] {1, 2});
+ check(cf1.isDone() || cf2.isDone());
+ }
+ } catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// allOf tests