--- a/jdk/make/tools/src/build/tools/tzdb/TzdbZoneRulesCompiler.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/make/tools/src/build/tools/tzdb/TzdbZoneRulesCompiler.java Tue Oct 22 12:33:33 2013 +0100
@@ -618,6 +618,11 @@
// remove ROC, which is not supported in j.u.tz
builtZones.remove("ROC");
links.remove("ROC");
+ // remove EST, HST and MST. They are supported via
+ // the short-id mapping
+ builtZones.remove("EST");
+ builtZones.remove("HST");
+ builtZones.remove("MST");
}
/**
--- a/jdk/makefiles/Setup.gmk Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/makefiles/Setup.gmk Tue Oct 22 12:33:33 2013 +0100
@@ -27,7 +27,7 @@
# To build with all warnings enabled, do the following:
# make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000"
-JAVAC_WARNINGS := -Xlint:-unchecked,-deprecation,-overrides,classfile,dep-ann,divzero,varargs -Werror
+JAVAC_WARNINGS := -Xlint:-unchecked,-deprecation,-overrides,auxiliaryclass,classfile,dep-ann,divzero,empty,try,varargs -Werror
# Any java code executed during a JDK build to build other parts of the JDK must be
# executed by the bootstrap JDK (probably with -Xbootclasspath/p: ) and for this
--- a/jdk/src/share/classes/java/io/Closeable.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/io/Closeable.java Tue Oct 22 12:33:33 2013 +0100
@@ -34,7 +34,6 @@
*
* @since 1.5
*/
-@FunctionalInterface
public interface Closeable extends AutoCloseable {
/**
--- a/jdk/src/share/classes/java/io/Flushable.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/io/Flushable.java Tue Oct 22 12:33:33 2013 +0100
@@ -34,7 +34,6 @@
*
* @since 1.5
*/
-@FunctionalInterface
public interface Flushable {
/**
--- a/jdk/src/share/classes/java/lang/AutoCloseable.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/lang/AutoCloseable.java Tue Oct 22 12:33:33 2013 +0100
@@ -48,7 +48,6 @@
* @author Josh Bloch
* @since 1.7
*/
-@FunctionalInterface
public interface AutoCloseable {
/**
* Closes this resource, relinquishing any underlying resources.
--- a/jdk/src/share/classes/java/lang/Class.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/lang/Class.java Tue Oct 22 12:33:33 2013 +0100
@@ -1571,6 +1571,10 @@
* <p> If this {@code Class} object represents a primitive type or void,
* then the returned array has length 0.
*
+ * <p> Static methods declared in superinterfaces of the class or interface
+ * represented by this {@code Class} object are not considered members of
+ * the class or interface.
+ *
* <p> The elements in the returned array are not sorted and are not in any
* particular order.
*
@@ -1729,6 +1733,10 @@
* <p> If this {@code Class} object represents an array type, then this
* method does not find the {@code clone()} method.
*
+ * <p> Static methods declared in superinterfaces of the class or interface
+ * represented by this {@code Class} object are not considered members of
+ * the class or interface.
+ *
* @param name the name of the method
* @param parameterTypes the list of parameters
* @return the {@code Method} object that matches the specified
@@ -1752,7 +1760,7 @@
public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
- Method method = getMethod0(name, parameterTypes);
+ Method method = getMethod0(name, parameterTypes, true);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
}
@@ -2727,6 +2735,14 @@
}
}
+ void addAllNonStatic(Method[] methods) {
+ for (Method candidate : methods) {
+ if (!Modifier.isStatic(candidate.getModifiers())) {
+ add(candidate);
+ }
+ }
+ }
+
int length() {
return length;
}
@@ -2797,7 +2813,7 @@
MethodArray inheritedMethods = new MethodArray();
Class<?>[] interfaces = getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
- inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
+ inheritedMethods.addAllNonStatic(interfaces[i].privateGetPublicMethods());
}
if (!isInterface()) {
Class<?> c = getSuperclass();
@@ -2900,7 +2916,7 @@
}
- private Method getMethod0(String name, Class<?>[] parameterTypes) {
+ private Method getMethod0(String name, Class<?>[] parameterTypes, boolean includeStaticMethods) {
// Note: the intent is that the search algorithm this routine
// uses be equivalent to the ordering imposed by
// privateGetPublicMethods(). It fetches only the declared
@@ -2913,25 +2929,23 @@
if ((res = searchMethods(privateGetDeclaredMethods(true),
name,
parameterTypes)) != null) {
- return res;
+ if (includeStaticMethods || !Modifier.isStatic(res.getModifiers()))
+ return res;
}
// Search superclass's methods
if (!isInterface()) {
Class<? super T> c = getSuperclass();
if (c != null) {
- if ((res = c.getMethod0(name, parameterTypes)) != null) {
+ if ((res = c.getMethod0(name, parameterTypes, true)) != null) {
return res;
}
}
}
// Search superinterfaces' methods
Class<?>[] interfaces = getInterfaces();
- for (int i = 0; i < interfaces.length; i++) {
- Class<?> c = interfaces[i];
- if ((res = c.getMethod0(name, parameterTypes)) != null) {
+ for (Class<?> c : interfaces)
+ if ((res = c.getMethod0(name, parameterTypes, false)) != null)
return res;
- }
- }
// Not found
return null;
}
@@ -3300,7 +3314,10 @@
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
Objects.requireNonNull(annotationClass);
- return AnnotationSupport.getMultipleAnnotations(annotationData().annotations, annotationClass);
+ AnnotationData annotationData = annotationData();
+ return AnnotationSupport.getAssociatedAnnotations(annotationData.declaredAnnotations,
+ annotationData.annotations,
+ annotationClass);
}
/**
@@ -3330,7 +3347,8 @@
public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {
Objects.requireNonNull(annotationClass);
- return AnnotationSupport.getMultipleAnnotations(annotationData().declaredAnnotations, annotationClass);
+ return AnnotationSupport.getDirectlyAndIndirectlyPresent(annotationData().declaredAnnotations,
+ annotationClass);
}
/**
--- a/jdk/src/share/classes/java/lang/Comparable.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/lang/Comparable.java Tue Oct 22 12:33:33 2013 +0100
@@ -93,7 +93,6 @@
* @see java.util.Comparator
* @since 1.2
*/
-@FunctionalInterface
public interface Comparable<T> {
/**
* Compares this object with the specified object for order. Returns a
--- a/jdk/src/share/classes/java/lang/ConditionalSpecialCasing.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/lang/ConditionalSpecialCasing.java Tue Oct 22 12:33:33 2013 +0100
@@ -74,7 +74,6 @@
new Entry(0x00CC, new char[]{0x0069, 0x0307, 0x0300}, new char[]{0x00CC}, "lt", 0), // # LATIN CAPITAL LETTER I WITH GRAVE
new Entry(0x00CD, new char[]{0x0069, 0x0307, 0x0301}, new char[]{0x00CD}, "lt", 0), // # LATIN CAPITAL LETTER I WITH ACUTE
new Entry(0x0128, new char[]{0x0069, 0x0307, 0x0303}, new char[]{0x0128}, "lt", 0), // # LATIN CAPITAL LETTER I WITH TILDE
- new Entry(0x0130, new char[]{0x0069, 0x0307}, new char[]{0x0130}, "lt", 0), // # LATIN CAPITAL LETTER I WITH DOT ABOVE
//# ================================================================================
//# Turkish and Azeri
@@ -85,10 +84,7 @@
new Entry(0x0049, new char[]{0x0131}, new char[]{0x0049}, "tr", NOT_BEFORE_DOT), // # LATIN CAPITAL LETTER I
new Entry(0x0049, new char[]{0x0131}, new char[]{0x0049}, "az", NOT_BEFORE_DOT), // # LATIN CAPITAL LETTER I
new Entry(0x0069, new char[]{0x0069}, new char[]{0x0130}, "tr", 0), // # LATIN SMALL LETTER I
- new Entry(0x0069, new char[]{0x0069}, new char[]{0x0130}, "az", 0), // # LATIN SMALL LETTER I
- //# ================================================================================
- //# Other
- new Entry(0x0130, new char[]{0x0069, 0x0307}, new char[]{0x0130}, "en", 0), // # LATIN CAPITALLETTER I WITH DOT ABOVE
+ new Entry(0x0069, new char[]{0x0069}, new char[]{0x0130}, "az", 0) // # LATIN SMALL LETTER I
};
// A hash table that contains the above entries
--- a/jdk/src/share/classes/java/lang/Iterable.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/lang/Iterable.java Tue Oct 22 12:33:33 2013 +0100
@@ -42,7 +42,6 @@
* @since 1.5
* @jls 14.14.2 The enhanced for statement
*/
-@FunctionalInterface
public interface Iterable<T> {
/**
* Returns an iterator over elements of type {@code T}.
--- a/jdk/src/share/classes/java/lang/Readable.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/lang/Readable.java Tue Oct 22 12:33:33 2013 +0100
@@ -34,7 +34,6 @@
*
* @since 1.5
*/
-@FunctionalInterface
public interface Readable {
/**
--- a/jdk/src/share/classes/java/lang/String.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/lang/String.java Tue Oct 22 12:33:33 2013 +0100
@@ -2598,21 +2598,14 @@
}
if (localeDependent || srcChar == '\u03A3') { // GREEK CAPITAL LETTER SIGMA
lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
- } else if (srcChar == '\u0130') { // LATIN CAPITAL LETTER I DOT
- lowerChar = Character.ERROR;
} else {
lowerChar = Character.toLowerCase(srcChar);
}
if ((lowerChar == Character.ERROR)
|| (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
if (lowerChar == Character.ERROR) {
- if (!localeDependent && srcChar == '\u0130') {
- lowerCharArray =
- ConditionalSpecialCasing.toLowerCaseCharArray(this, i, Locale.ENGLISH);
- } else {
- lowerCharArray =
- ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
- }
+ lowerCharArray =
+ ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
} else if (srcCount == 2) {
resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
continue;
--- a/jdk/src/share/classes/java/lang/reflect/Executable.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/lang/reflect/Executable.java Tue Oct 22 12:33:33 2013 +0100
@@ -527,7 +527,7 @@
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
- return AnnotationSupport.getMultipleAnnotations(declaredAnnotations(), annotationClass);
+ return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
}
/**
--- a/jdk/src/share/classes/java/lang/reflect/Field.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/lang/reflect/Field.java Tue Oct 22 12:33:33 2013 +0100
@@ -1123,7 +1123,7 @@
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
- return AnnotationSupport.getMultipleAnnotations(declaredAnnotations(), annotationClass);
+ return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
}
/**
--- a/jdk/src/share/classes/java/lang/reflect/Parameter.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/java/lang/reflect/Parameter.java Tue Oct 22 12:33:33 2013 +0100
@@ -295,7 +295,7 @@
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
- return AnnotationSupport.getMultipleAnnotations(declaredAnnotations(), annotationClass);
+ return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
}
/**
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java Tue Oct 22 12:33:33 2013 +0100
@@ -840,7 +840,15 @@
ti = threads.add();
if (!isOpen())
return null;
- if (size() < position + size) { // Extend file size
+
+ long filesize;
+ do {
+ filesize = nd.size(fd);
+ } while ((filesize == IOStatus.INTERRUPTED) && isOpen());
+ if (!isOpen())
+ return null;
+
+ if (filesize < position + size) { // Extend file size
if (!writable) {
throw new IOException("Channel not open for writing " +
"- cannot extend file to required size");
@@ -849,6 +857,8 @@
do {
rv = nd.truncate(fd, position + size);
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
+ if (!isOpen())
+ return null;
}
if (size == 0) {
addr = 0;
--- a/jdk/src/share/classes/sun/nio/cs/ext/DoubleByte.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/sun/nio/cs/ext/DoubleByte.java Tue Oct 22 12:33:33 2013 +0100
@@ -111,7 +111,6 @@
public static class Decoder extends CharsetDecoder
implements DelegatableDecoder, ArrayDecoder
{
-
final char[][] b2c;
final char[] b2cSB;
final int b2Min;
@@ -122,7 +121,12 @@
return CoderResult.UNDERFLOW;
}
- protected CoderResult crMalformedOrUnmappable(int b) {
+ protected CoderResult crMalformedOrUnmappable(int b1, int b2) {
+ if (b2c[b1] == B2C_UNMAPPABLE || // isNotLeadingByte(b1)
+ b2c[b2] != B2C_UNMAPPABLE || // isLeadingByte(b2)
+ decodeSingle(b2) != UNMAPPABLE_DECODING) { // isSingle(b2)
+ return CoderResult.malformedForLength(1);
+ }
return CoderResult.unmappableForLength(2);
}
@@ -161,7 +165,7 @@
int b2 = sa[sp + 1] & 0xff;
if (b2 < b2Min || b2 > b2Max ||
(c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING) {
- return crMalformedOrUnmappable(b1);
+ return crMalformedOrUnmappable(b1, b2);
}
inSize++;
}
@@ -190,7 +194,7 @@
int b2 = src.get() & 0xff;
if (b2 < b2Min || b2 > b2Max ||
(c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING)
- return crMalformedOrUnmappable(b1);
+ return crMalformedOrUnmappable(b1, b2);
inSize++;
}
dst.put(c);
@@ -221,8 +225,13 @@
if (c == UNMAPPABLE_DECODING) {
if (sp < sl) {
int b2 = src[sp++] & 0xff;
- if (b2 >= b2Min && b2 <= b2Max) {
- c = b2c[b1][b2 - b2Min];
+ if (b2 < b2Min || b2 > b2Max ||
+ (c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING) {
+ if (b2c[b1] == B2C_UNMAPPABLE || // isNotLeadingByte
+ b2c[b2] != B2C_UNMAPPABLE || // isLeadingByte
+ decodeSingle(b2) != UNMAPPABLE_DECODING) {
+ sp--;
+ }
}
}
if (c == UNMAPPABLE_DECODING) {
@@ -466,8 +475,8 @@
return CoderResult.UNDERFLOW;
}
- protected CoderResult crMalformedOrUnmappable(int b) {
- if (b == SS2 || b == SS3 )
+ protected CoderResult crMalformedOrUnmappable(int b1, int b2) {
+ if (b1 == SS2 || b1 == SS3 )
return CoderResult.malformedForLength(1);
return CoderResult.unmappableForLength(2);
}
--- a/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java Tue Oct 22 12:33:33 2013 +0100
@@ -166,7 +166,7 @@
@Override
public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotation) {
- return AnnotationSupport.getMultipleAnnotations(annotations, annotation);
+ return AnnotationSupport.getDirectlyAndIndirectlyPresent(annotations, annotation);
}
// AnnotatedType
--- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationSupport.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationSupport.java Tue Oct 22 12:33:33 2013 +0100
@@ -28,109 +28,224 @@
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public final class AnnotationSupport {
+
/**
- * Finds and returns all annotation of the type indicated by
- * {@code annotationClass} from the {@code Map} {@code
- * annotationMap}. Looks into containers of the {@code
- * annotationClass} (as specified by an the {@code
- * annotationClass} type being meta-annotated with an {@code
- * Repeatable} annotation).
+ * Finds and returns all annotations in {@code annotations} matching
+ * the given {@code annoClass}.
+ *
+ * Apart from annotations directly present in {@code annotations} this
+ * method searches for annotations inside containers i.e. indirectly
+ * present annotations.
+ *
+ * The order of the elements in the array returned depends on the iteration
+ * order of the provided map. Specifically, the directly present annotations
+ * come before the indirectly present annotations if and only if the
+ * directly present annotations come before the indirectly present
+ * annotations in the map.
*
- * @param annotationMap the {@code Map} used to store annotations indexed by their type
- * @param annotationClass the type of annotation to search for
+ * @param annotations the {@code Map} in which to search for annotations
+ * @param annoClass the type of annotation to search for
+ * @param includeNonInheritedContainees if false, the annoClass must be
+ * inheritable for the containers to be searched
*
- * @return an array of instances of {@code annotationClass} or an empty array if none were found
+ * @return an array of instances of {@code annoClass} or an empty
+ * array if none were found
*/
- public static <A extends Annotation> A[] getMultipleAnnotations(
- final Map<Class<? extends Annotation>, Annotation> annotationMap,
- final Class<A> annotationClass) {
- final List<A> res = new ArrayList<A>();
+ private static <A extends Annotation> A[] getDirectlyAndIndirectlyPresent(
+ Map<Class<? extends Annotation>, Annotation> annotations,
+ Class<A> annoClass,
+ boolean includeNonInheritedContainees) {
+
+ List<A> result = new ArrayList<A>();
@SuppressWarnings("unchecked")
- final A candidate = (A)annotationMap.get(annotationClass);
- if (candidate != null) {
- res.add(candidate);
+ A direct = (A) annotations.get(annoClass);
+ if (direct != null)
+ result.add(direct);
+
+ if (includeNonInheritedContainees ||
+ AnnotationType.getInstance(annoClass).isInherited()) {
+ A[] indirect = getIndirectlyPresent(annotations, annoClass);
+
+ if (indirect != null) {
+
+ boolean indirectFirst = direct == null ||
+ containerBeforeContainee(annotations, annoClass);
+
+ result.addAll((indirectFirst ? 0 : 1), Arrays.asList(indirect));
+ }
}
- final Class<? extends Annotation> containerClass = getContainer(annotationClass);
- if (containerClass != null) {
- res.addAll(unpackAll(annotationMap.get(containerClass), annotationClass));
- }
+ @SuppressWarnings("unchecked")
+ A[] arr = (A[]) Array.newInstance(annoClass, result.size());
+ return result.toArray(arr);
+ }
+
+
+ /**
+ * Equivalent to calling {@code getDirectlyAndIndirectlyPresentAnnotations(
+ * annotations, annoClass, true)}.
+ */
+ public static <A extends Annotation> A[] getDirectlyAndIndirectlyPresent(
+ Map<Class<? extends Annotation>, Annotation> annotations,
+ Class<A> annoClass) {
+
+ return getDirectlyAndIndirectlyPresent(annotations, annoClass, true);
+ }
+
- @SuppressWarnings("unchecked") // should be safe annotationClass is a token for A
- final A[] emptyTemplateArray = (A[])Array.newInstance(annotationClass, 0);
- return res.isEmpty() ? emptyTemplateArray : res.toArray(emptyTemplateArray);
+ /**
+ * Finds and returns all annotations matching the given {@code annoClass}
+ * indirectly present in {@code annotations}.
+ *
+ * @param annotations annotations to search indexed by their types
+ * @param annoClass the type of annotation to search for
+ *
+ * @return an array of instances of {@code annoClass} or an empty array if no
+ * indirectly present annotations were found
+ */
+ private static <A extends Annotation> A[] getIndirectlyPresent(
+ Map<Class<? extends Annotation>, Annotation> annotations,
+ Class<A> annoClass) {
+
+ Repeatable repeatable = annoClass.getDeclaredAnnotation(Repeatable.class);
+ if (repeatable == null)
+ return null; // Not repeatable -> no indirectly present annotations
+
+ Class<? extends Annotation> containerClass = repeatable.value();
+
+ Annotation container = annotations.get(containerClass);
+ if (container == null)
+ return null;
+
+ // Unpack container
+ A[] valueArray = getValueArray(container);
+ checkTypes(valueArray, container, annoClass);
+
+ return valueArray;
}
- /** Helper to get the container, or null if none, of an annotation. */
- private static <A extends Annotation> Class<? extends Annotation> getContainer(Class<A> annotationClass) {
- Repeatable containingAnnotation = annotationClass.getDeclaredAnnotation(Repeatable.class);
- return (containingAnnotation == null) ? null : containingAnnotation.value();
+
+ /**
+ * Figures out if conatiner class comes before containee class among the
+ * keys of the given map.
+ *
+ * @return true if container class is found before containee class when
+ * iterating over annotations.keySet().
+ */
+ private static <A extends Annotation> boolean containerBeforeContainee(
+ Map<Class<? extends Annotation>, Annotation> annotations,
+ Class<A> annoClass) {
+
+ Class<? extends Annotation> containerClass =
+ annoClass.getDeclaredAnnotation(Repeatable.class).value();
+
+ for (Class<? extends Annotation> c : annotations.keySet()) {
+ if (c == containerClass) return true;
+ if (c == annoClass) return false;
+ }
+
+ // Neither containee nor container present
+ return false;
}
- /** Reflectively look up and get the returned array from the the
- * invocation of the value() element on an instance of an
- * Annotation.
+
+ /**
+ * Finds and returns all associated annotations matching the given class.
+ *
+ * The order of the elements in the array returned depends on the iteration
+ * order of the provided maps. Specifically, the directly present annotations
+ * come before the indirectly present annotations if and only if the
+ * directly present annotations come before the indirectly present
+ * annotations in the relevant map.
+ *
+ * @param declaredAnnotations the declared annotations indexed by their types
+ * @param allAnnotations declared and inherited annotations indexed by their types
+ * @param annoClass the type of annotation to search for
+ *
+ * @return an array of instances of {@code annoClass} or an empty array if none were found.
*/
- private static <A extends Annotation> A[] getValueArray(Annotation containerInstance) {
+ public static <A extends Annotation> A[] getAssociatedAnnotations(
+ Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
+ Map<Class<? extends Annotation>, Annotation> allAnnotations,
+ Class<A> annoClass) {
+
+ // Search declared
+ A[] result = getDirectlyAndIndirectlyPresent(declaredAnnotations, annoClass);
+
+ // Search inherited
+ if (result.length == 0)
+ result = getDirectlyAndIndirectlyPresent(allAnnotations, annoClass, false);
+
+ return result;
+ }
+
+
+ /* Reflectively invoke the values-method of the given annotation
+ * (container), cast it to an array of annotations and return the result.
+ */
+ private static <A extends Annotation> A[] getValueArray(Annotation container) {
try {
- // the spec tells us the container must have an array-valued
- // value element. Get the AnnotationType, get the "value" element
- // and invoke it to get the contents.
+ // According to JLS the container must have an array-valued value
+ // method. Get the AnnotationType, get the "value" method and invoke
+ // it to get the content.
- Class<? extends Annotation> containerClass = containerInstance.annotationType();
+ Class<? extends Annotation> containerClass = container.annotationType();
AnnotationType annoType = AnnotationType.getInstance(containerClass);
if (annoType == null)
- throw new AnnotationFormatError(containerInstance + " is an invalid container for repeating annotations");
+ throw invalidContainerException(container, null);
Method m = annoType.members().get("value");
if (m == null)
- throw new AnnotationFormatError(containerInstance +
- " is an invalid container for repeating annotations");
+ throw invalidContainerException(container, null);
+
m.setAccessible(true);
- @SuppressWarnings("unchecked") // not provably safe, but we catch the ClassCastException
- A[] a = (A[])m.invoke(containerInstance); // this will erase to (Annotation[]) but we
- // do a runtime cast on the return-value
- // in the methods that call this method
- return a;
- } catch (IllegalAccessException | // couldnt loosen security
- IllegalArgumentException | // parameters doesn't match
+ // This will erase to (Annotation[]) but we do a runtime cast on the
+ // return-value in the method that call this method.
+ @SuppressWarnings("unchecked")
+ A[] values = (A[]) m.invoke(container);
+
+ return values;
+
+ } catch (IllegalAccessException | // couldn't loosen security
+ IllegalArgumentException | // parameters doesn't match
InvocationTargetException | // the value method threw an exception
- ClassCastException e) { // well, a cast failed ...
- throw new AnnotationFormatError(
- containerInstance + " is an invalid container for repeating annotations",
- e);
+ ClassCastException e) {
+
+ throw invalidContainerException(container, e);
+
}
}
- /* Sanity check type of and return a list of all the annotation
- * instances of type {@code annotationClass} from {@code
- * containerInstance}.
- */
- private static <A extends Annotation> List<A> unpackAll(Annotation containerInstance,
- Class<A> annotationClass) {
- if (containerInstance == null) {
- return Collections.emptyList(); // container not present
- }
+
+ private static AnnotationFormatError invalidContainerException(Annotation anno,
+ Throwable cause) {
+ return new AnnotationFormatError(
+ anno + " is an invalid container for repeating annotations",
+ cause);
+ }
+
- try {
- A[] a = getValueArray(containerInstance);
- List<A> l = new ArrayList<>(a.length);
- for (int i = 0; i < a.length; i++)
- l.add(annotationClass.cast(a[i]));
- return l;
- } catch (ClassCastException |
- NullPointerException e) {
- throw new AnnotationFormatError(
- String.format("%s is an invalid container for repeating annotations of type: %s",
- containerInstance, annotationClass),
- e);
+ /* Sanity check type of all the annotation instances of type {@code annoClass}
+ * from {@code container}.
+ */
+ private static <A extends Annotation> void checkTypes(A[] annotations,
+ Annotation container,
+ Class<A> annoClass) {
+ for (A a : annotations) {
+ if (!annoClass.isInstance(a)) {
+ throw new AnnotationFormatError(
+ String.format("%s is an invalid container for " +
+ "repeating annotations of type: %s",
+ container, annoClass));
+ }
}
}
}
--- a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java Tue Oct 22 12:33:33 2013 +0100
@@ -217,7 +217,7 @@
@Override
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
- return AnnotationSupport.getMultipleAnnotations(mapAnnotations(getAnnotations()), annotationClass);
+ return AnnotationSupport.getDirectlyAndIndirectlyPresent(mapAnnotations(getAnnotations()), annotationClass);
}
@Override
--- a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java Tue Oct 22 12:33:33 2013 +0100
@@ -66,8 +66,17 @@
* @return a set of time zone IDs.
*/
public static String[] getZoneIds() {
- String[] ids = Arrays.copyOf(regions, regions.length + oldMappings.length);
+ int len = regions.length + oldMappings.length;
+ if (!USE_OLDMAPPING) {
+ len += 3; // EST/HST/MST not in tzdb.dat
+ }
+ String[] ids = Arrays.copyOf(regions, len);
int i = regions.length;
+ if (!USE_OLDMAPPING) {
+ ids[i++] = "EST";
+ ids[i++] = "HST";
+ ids[i++] = "MST";
+ }
for (int j = 0; j < oldMappings.length; j++) {
ids[i++] = oldMappings[j][0];
}
@@ -264,6 +273,10 @@
aliases.put("EST", "America/New_York");
aliases.put("MST", "America/Denver");
aliases.put("HST", "Pacific/Honolulu");
+ } else {
+ zones.put("EST", new ZoneInfo("EST", -18000000));
+ zones.put("MST", new ZoneInfo("MST", -25200000));
+ zones.put("HST", new ZoneInfo("HST", -36000000));
}
}
--- a/jdk/src/share/lib/security/java.security-linux Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/lib/security/java.security-linux Tue Oct 22 12:33:33 2013 +0100
@@ -184,6 +184,7 @@
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
+ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
@@ -230,6 +231,7 @@
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
+ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
--- a/jdk/src/share/lib/security/java.security-macosx Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/lib/security/java.security-macosx Tue Oct 22 12:33:33 2013 +0100
@@ -185,6 +185,7 @@
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
+ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
@@ -231,6 +232,7 @@
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
+ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
--- a/jdk/src/share/lib/security/java.security-solaris Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/lib/security/java.security-solaris Tue Oct 22 12:33:33 2013 +0100
@@ -186,6 +186,7 @@
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
+ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
@@ -231,6 +232,7 @@
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
+ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
--- a/jdk/src/share/lib/security/java.security-windows Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/src/share/lib/security/java.security-windows Tue Oct 22 12:33:33 2013 +0100
@@ -185,6 +185,7 @@
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
+ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
@@ -231,6 +232,7 @@
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
+ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
--- a/jdk/test/ProblemList.txt Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/test/ProblemList.txt Tue Oct 22 12:33:33 2013 +0100
@@ -325,6 +325,9 @@
# 8007410
tools/launcher/FXLauncherTest.java linux-all
+# 7144200
+java/lang/management/ClassLoadingMXBean/LoadCounts.java generic-all
+
############################################################################
# jdk_jdi
--- a/jdk/test/java/lang/SecurityManager/CheckPackageAccess.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/test/java/lang/SecurityManager/CheckPackageAccess.java Tue Oct 22 12:33:33 2013 +0100
@@ -58,6 +58,7 @@
"com.sun.media.sound.",
"com.sun.naming.internal.",
"com.sun.proxy.",
+ "com.sun.corba.se.",
"com.sun.org.apache.bcel.internal.",
"com.sun.org.apache.regexp.internal.",
"com.sun.org.apache.xerces.internal.",
--- a/jdk/test/java/lang/String/ToLowerCase.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/test/java/lang/String/ToLowerCase.java Tue Oct 22 12:33:33 2013 +0100
@@ -23,7 +23,7 @@
/*
@test
- @bug 4217441 4533872 4900935
+ @bug 4217441 4533872 4900935 8020037
@summary toLowerCase should lower-case Greek Sigma correctly depending
on the context (final/non-final). Also it should handle
Locale specific (lt, tr, and az) lowercasings and supplementary
@@ -69,10 +69,11 @@
test("\u00CD", Locale.US, "\u00ED");
test("\u0128", Locale.US, "\u0129");
- // I-dot tests (Turkish and Azeri)
+ // I-dot tests
test("\u0130", turkish, "i");
test("\u0130", az, "i");
- test("\u0130", Locale.US, "i\u0307");
+ test("\u0130", lt, "i");
+ test("\u0130", Locale.US, "i");
// Remove dot_above in the sequence I + dot_above (Turkish and Azeri)
test("I\u0307", turkish, "i");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/repeatingAnnotations/NonInheritableContainee.java Tue Oct 22 12:33:33 2013 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8019420
+ * @summary Repeatable non-inheritable annotation types are mishandled by Core Reflection
+ */
+
+import java.util.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+public class NonInheritableContainee {
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Repeatable(InheritedAnnotationContainer.class)
+ @interface NonInheritedAnnotationRepeated {
+ String name();
+ }
+
+ @Inherited
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface InheritedAnnotationContainer {
+ NonInheritedAnnotationRepeated[] value();
+ }
+
+ @NonInheritedAnnotationRepeated(name="A")
+ @NonInheritedAnnotationRepeated(name="B")
+ class Parent {}
+ class Sample extends Parent {}
+
+
+ public static void main(String[] args) {
+
+ Annotation[] anns = Sample.class.getAnnotationsByType(
+ NonInheritedAnnotationRepeated.class);
+
+ if (anns.length != 0)
+ throw new RuntimeException("Non-@Inherited containees should not " +
+ "be inherited even though its container is @Inherited.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/repeatingAnnotations/OrderUnitTest.java Tue Oct 22 12:33:33 2013 +0100
@@ -0,0 +1,74 @@
+/*
+ * 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 8004912
+ * @summary Unit test for order of annotations returned by get[Declared]AnnotationsByType.
+ *
+ * @run main OrderUnitTest
+ */
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+public class OrderUnitTest {
+
+ public static void main(String[] args) {
+ testOrder(Case1.class);
+ testOrder(Case2.class);
+ }
+
+ private static void testOrder(AnnotatedElement e) {
+ Annotation[] decl = e.getDeclaredAnnotations();
+ Foo[] declByType = e.getDeclaredAnnotationsByType(Foo.class);
+
+ if (decl[0] instanceof Foo != declByType[0].isDirect() ||
+ decl[1] instanceof Foo != declByType[1].isDirect()) {
+ throw new RuntimeException("Order of directly / indirectly present " +
+ "annotations from getDeclaredAnnotationsByType does not " +
+ "match order from getDeclaredAnnotations.");
+ }
+ }
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface FooContainer {
+ Foo[] value();
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(FooContainer.class)
+@interface Foo {
+ boolean isDirect();
+}
+
+
+@Foo(isDirect = true) @FooContainer({@Foo(isDirect = false)})
+class Case1 {
+}
+
+
+@FooContainer({@Foo(isDirect = false)}) @Foo(isDirect = true)
+class Case2 {
+}
--- a/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java Tue Oct 22 12:33:33 2013 +0100
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 7154390 8005712 8007278
+ * @bug 7154390 8005712 8007278 8004912
* @summary Unit test for repeated annotation reflection
*
* @compile RepeatedUnitTest.java subpackage/package-info.java subpackage/Container.java subpackage/Containee.java subpackage/NonRepeated.java subpackage/InheritedContainee.java subpackage/InheritedContainer.java subpackage/InheritedNonRepeated.java
@@ -51,6 +51,12 @@
inheritedMe3();
inheritedMe4();
+ inheritedMe5(); // ContainerOnSuperSingleOnSub
+ inheritedMe6(); // RepeatableOnSuperSingleOnSub
+ inheritedMe7(); // SingleAnnoOnSuperContainerOnSub
+ inheritedMe8(); // SingleOnSuperRepeatableOnSub
+
+
// CONSTRUCTOR
checkMultiplier(Me1.class.getConstructor(new Class[0]), 10);
@@ -159,6 +165,30 @@
check(e.getAnnotationsByType(NonRepeated.class)[0].value() == 1000);
}
+ static void inheritedMe5() {
+ AnnotatedElement e = Me5.class;
+ check(2 == e.getAnnotations().length);
+ check(1 == countAnnotation(e, InheritedContainee.class));
+ }
+
+ static void inheritedMe6() {
+ AnnotatedElement e = Me6.class;
+ check(2 == e.getAnnotations().length);
+ check(1 == countAnnotation(e, InheritedContainee.class));
+ }
+
+ static void inheritedMe7() {
+ AnnotatedElement e = Me7.class;
+ check(2 == e.getAnnotations().length);
+ check(2 == countAnnotation(e, InheritedContainee.class));
+ }
+
+ static void inheritedMe8() {
+ AnnotatedElement e = Me8.class;
+ check(2 == e.getAnnotations().length);
+ check(2 == countAnnotation(e, InheritedContainee.class));
+ }
+
static void checkMultiplier(AnnotatedElement e, int m) {
// Basic sanity of non-repeating getAnnotation(Class)
check(e.getAnnotation(NonRepeated.class).value() == 5 * m);
@@ -252,3 +282,31 @@
@InheritedContainee(1000) @InheritedContainee(2000) @InheritedContainee(3000) @InheritedContainee(4000)
@Containee(1000) @Containee(2000) @Containee(3000) @Containee(4000)
class Me4 extends Father {}
+
+
+@InheritedContainer({@InheritedContainee(1), @InheritedContainee(2)})
+class SuperOf5 {}
+
+@InheritedContainee(3)
+class Me5 extends SuperOf5{}
+
+
+@InheritedContainee(1) @InheritedContainee(2)
+class SuperOf6 {}
+
+@InheritedContainee(3)
+class Me6 extends SuperOf6 {}
+
+
+@InheritedContainee(1)
+class SuperOf7 {}
+
+@InheritedContainer({@InheritedContainee(2), @InheritedContainee(3)})
+class Me7 extends SuperOf7 {}
+
+
+@InheritedContainee(1)
+class SuperOf8 {}
+
+@InheritedContainee(2) @InheritedContainee(3)
+class Me8 extends SuperOf8 {}
--- a/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh Tue Oct 22 12:33:33 2013 +0100
@@ -62,6 +62,10 @@
RedefineMethodInBacktraceTarget.java
"${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . RedefineMethodInBacktraceTarget.java
+cp "${TESTSRC}"/RedefineMethodInBacktraceTargetB_2.java \
+ RedefineMethodInBacktraceTargetB.java
+"${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . RedefineMethodInBacktraceTargetB.java
+
"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodInBacktraceAgent.jar \
-classpath "${TESTCLASSES}" RedefineMethodInBacktraceApp > output.log 2>&1
RUN_RESULT=$?
--- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java Tue Oct 22 12:33:33 2013 +0100
@@ -21,12 +21,17 @@
* questions.
*/
+import com.sun.management.DiagnosticCommandMBean;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.instrument.ClassDefinition;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.concurrent.CountDownLatch;
+import sun.management.ManagementFactoryHelper;
/**
* When an exception is thrown, the JVM collects just enough information
@@ -49,8 +54,12 @@
System.exit(0);
}
+ public static CountDownLatch stop = new CountDownLatch(1);
+ public static CountDownLatch called = new CountDownLatch(1);
+
private void doTest() throws Exception {
doMethodInBacktraceTest();
+ doMethodInBacktraceTestB();
}
private void doMethodInBacktraceTest() throws Exception {
@@ -63,6 +72,36 @@
touchRedefinedMethodInBacktrace(t);
}
+ private void doMethodInBacktraceTestB() throws Exception {
+ // Start a thread which blocks in method
+ Thread t = new Thread(RedefineMethodInBacktraceTargetB::methodToRedefine);
+ t.setDaemon(true);
+ t.start();
+
+ // Wait here until the new thread is in the method we want to redefine
+ called.await();
+
+ // Now redefine the class while the method is still on the stack of the new thread
+ doRedefine(RedefineMethodInBacktraceTargetB.class);
+
+ // Do thread dumps in two different ways (to exercise different code paths)
+ // while the old class is still on the stack
+
+ ThreadInfo[] tis = ManagementFactory.getThreadMXBean().dumpAllThreads(false, false);
+ for(ThreadInfo ti : tis) {
+ System.out.println(ti);
+ }
+
+ String[] threadPrintArgs = {};
+ Object[] dcmdArgs = {threadPrintArgs};
+ String[] signature = {String[].class.getName()};
+ DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean();
+ System.out.println(dcmd.invoke("threadPrint", dcmdArgs, signature));
+
+ // release the thread
+ stop.countDown();
+ }
+
private static Throwable getThrowableFromMethodToRedefine() throws Exception {
Class<RedefineMethodInBacktraceTarget> c =
RedefineMethodInBacktraceTarget.class;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java Tue Oct 22 12:33:33 2013 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/**
+ * The first version of this class. The second version is in
+ * RedefineMethodInBacktraceTargetB_2.java.
+ */
+public class RedefineMethodInBacktraceTargetB {
+ public static void methodToRedefine() {
+ try {
+ // signal that we are here
+ RedefineMethodInBacktraceApp.called.countDown();
+
+ // wait until test is done
+ RedefineMethodInBacktraceApp.stop.await();
+ } catch (InterruptedException ex) {
+ // ignore, test will fail
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java Tue Oct 22 12:33:33 2013 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * This is the second version of this class. The first version is in
+ * RedefineMethodInBacktraceTargetB.java.
+ */
+public class RedefineMethodInBacktraceTargetB {
+ public static void methodToRedefine() {
+ }
+}
--- a/jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java Tue Oct 22 12:33:33 2013 +0100
@@ -44,30 +44,86 @@
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
import org.testng.annotations.Test;
import static helper.Mod.*;
import static helper.Declared.*;
import helper.Mod;
+
public class DefaultStaticInvokeTest {
+ // getMethods(): Make sure getMethods returns the expected methods.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
public void testGetMethods(String testTarget, Object param)
throws Exception {
- // test the methods retrieved by getMethods()
testMethods(ALL_METHODS, testTarget, param);
}
+
+ // getDeclaredMethods(): Make sure getDeclaredMethods returns the expected methods.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
public void testGetDeclaredMethods(String testTarget, Object param)
throws Exception {
- // test the methods retrieved by getDeclaredMethods()
testMethods(DECLARED_ONLY, testTarget, param);
}
+
+ // getMethod(): Make sure that getMethod finds all methods it should find.
+ @Test(dataProvider = "testCasesAll",
+ dataProviderClass = DefaultStaticTestData.class)
+ public void testGetMethod(String testTarget, Object param)
+ throws Exception {
+
+ Class<?> typeUnderTest = Class.forName(testTarget);
+
+ MethodDesc[] descs = typeUnderTest.getAnnotationsByType(MethodDesc.class);
+
+ for (MethodDesc desc : descs) {
+ assertTrue(isFoundByGetMethod(typeUnderTest,
+ desc.name(),
+ argTypes(param)));
+ }
+ }
+
+
+ // getMethod(): Make sure that getMethod does *not* find certain methods.
+ @Test(dataProvider = "testCasesAll",
+ dataProviderClass = DefaultStaticTestData.class)
+ public void testGetMethodSuperInterfaces(String testTarget, Object param)
+ throws Exception {
+
+ // Make sure static methods in superinterfaces are not found (unless the type under
+ // test declares a static method with the same signature).
+
+ Class<?> typeUnderTest = Class.forName(testTarget);
+
+ for (Class<?> interfaze : typeUnderTest.getInterfaces()) {
+
+ for (MethodDesc desc : interfaze.getAnnotationsByType(MethodDesc.class)) {
+
+ boolean isStatic = desc.mod() == STATIC;
+
+ boolean declaredInThisType = isMethodDeclared(typeUnderTest,
+ desc.name());
+
+ boolean expectedToBeFound = !isStatic || declaredInThisType;
+
+ if (expectedToBeFound)
+ continue; // already tested in testGetMethod()
+
+ assertFalse(isFoundByGetMethod(typeUnderTest,
+ desc.name(),
+ argTypes(param)));
+ }
+ }
+ }
+
+
+ // Method.invoke(): Make sure Method.invoke returns the expected value.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
public void testMethodInvoke(String testTarget, Object param)
@@ -78,11 +134,13 @@
// test the method retrieved by Class.getMethod(String, Object[])
for (MethodDesc toTest : expectedMethods) {
String name = toTest.name();
- Method m = getTestMethod(typeUnderTest, name, param);
+ Method m = typeUnderTest.getMethod(name, argTypes(param));
testThisMethod(toTest, m, typeUnderTest, param);
}
}
+
+ // MethodHandle.invoke(): Make sure MethodHandle.invoke returns the expected value.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
public void testMethodHandleInvoke(String testTarget, Object param)
@@ -116,6 +174,7 @@
}
+ // Lookup.findStatic / .findVirtual: Make sure IllegalAccessException is thrown as expected.
@Test(dataProvider = "testClasses",
dataProviderClass = DefaultStaticTestData.class)
public void testIAE(String testTarget, Object param)
@@ -128,7 +187,7 @@
String mName = toTest.name();
Mod mod = toTest.mod();
if (mod != STATIC && typeUnderTest.isInterface()) {
- return;
+ continue;
}
Exception caught = null;
try {
@@ -136,10 +195,12 @@
} catch (Exception e) {
caught = e;
}
- assertTrue(caught != null);
+ assertNotNull(caught);
assertEquals(caught.getClass(), IllegalAccessException.class);
}
}
+
+
private static final String[] OBJECT_METHOD_NAMES = {
"equals",
"hashCode",
@@ -192,15 +253,15 @@
myMethods.put(mName, m);
}
}
- assertEquals(expectedMethods.length, myMethods.size());
+
+ assertEquals(myMethods.size(), expectedMethods.length);
for (MethodDesc toTest : expectedMethods) {
String name = toTest.name();
- Method candidate = myMethods.get(name);
+ Method candidate = myMethods.remove(name);
assertNotNull(candidate);
- myMethods.remove(name);
testThisMethod(toTest, candidate, typeUnderTest, param);
@@ -210,6 +271,7 @@
assertTrue(myMethods.isEmpty());
}
+
private void testThisMethod(MethodDesc toTest, Method method,
Class<?> typeUnderTest, Object param) throws Exception {
// Test modifiers, and invoke
@@ -256,37 +318,52 @@
assertFalse(method.isDefault());
break;
default:
- assertFalse(true); //this should never happen
+ fail(); //this should never happen
break;
}
}
+
+ private boolean isMethodDeclared(Class<?> type, String name) {
+ MethodDesc[] methDescs = type.getAnnotationsByType(MethodDesc.class);
+ for (MethodDesc desc : methDescs) {
+ if (desc.declared() == YES && desc.name().equals(name))
+ return true;
+ }
+ return false;
+ }
+
+
+ private boolean isFoundByGetMethod(Class<?> c, String method, Class<?>... argTypes) {
+ try {
+ c.getMethod(method, argTypes);
+ return true;
+ } catch (NoSuchMethodException notFound) {
+ return false;
+ }
+ }
+
+
+ private Class<?>[] argTypes(Object param) {
+ return param == null ? new Class[0] : new Class[] { Object.class };
+ }
+
+
private Object tryInvoke(Method m, Class<?> receiverType, Object param)
throws Exception {
Object receiver = receiverType == null ? null : receiverType.newInstance();
- Object result = null;
- if (param == null) {
- result = m.invoke(receiver);
- } else {
- result = m.invoke(receiver, param);
- }
- return result;
+ Object[] args = param == null ? new Object[0] : new Object[] { param };
+ return m.invoke(receiver, args);
}
- private Method getTestMethod(Class clazz, String methodName, Object param)
- throws NoSuchMethodException {
- Class[] paramsType = (param != null)
- ? new Class[]{Object.class}
- : new Class[]{};
- return clazz.getMethod(methodName, paramsType);
- }
private MethodHandle getTestMH(Class clazz, String methodName, Object param)
throws Exception {
return getTestMH(clazz, methodName, param, false);
}
+
private MethodHandle getTestMH(Class clazz, String methodName,
Object param, boolean isNegativeTest)
throws Exception {
--- a/jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/test/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java Tue Oct 22 12:33:33 2013 +0100
@@ -172,7 +172,7 @@
@MethodDesc(name = "defaultMethod", retval = "TestIF8.TestClass8", mod = DEFAULT, declared = NO)
class TestClass8<T> implements TestIF8<T> {
-};
+}
@MethodDesc(name = "defaultMethod", retval = "TestIF9.defaultMethod", mod = DEFAULT, declared = YES)
interface TestIF9 extends TestIF1 {
@@ -218,7 +218,6 @@
}
@MethodDesc(name = "defaultMethod", retval = "TestIF12.defaultMethod", mod = DEFAULT, declared = YES)
-@MethodDesc(name = "staticMethod", retval = "TestIF2.staticMethod", mod = STATIC, declared = NO)
interface TestIF12 extends TestIF2 {
default String defaultMethod() {
@@ -299,7 +298,7 @@
@MethodDesc(name = "defaultMethod", retval = "TestIF16.defaultMethod", mod = DEFAULT, declared = NO)
class TestClass16 implements TestIF16 {
-};
+}
@MethodDesc(name = "defaultMethod", retval = "TestIF17.defaultMethod", mod = DEFAULT, declared = YES)
@MethodDesc(name = "staticMethod", retval = "TestIF17.staticMethod", mod = STATIC, declared = YES)
@@ -318,6 +317,12 @@
class TestClass17 implements TestIF17 {
}
+
+@MethodDesc(name = "defaultMethod", retval = "TestIF17.defaultMethod", mod = DEFAULT, declared = NO)
+class TestClass18 extends TestClass17 {
+}
+
+
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MethodDescs.class)
@interface MethodDesc {
@@ -332,6 +337,41 @@
MethodDesc[] value();
}
+//Diamond Case for static method
+@MethodDesc(name = "staticMethod", retval = "TestIF2A.staticMethod", mod = STATIC, declared = YES)
+interface TestIF2A extends TestIF2 {
+ static String staticMethod() {
+ return "TestIF2A.staticMethod";
+ }
+}
+
+@MethodDesc(name = "method", retval = "", mod = ABSTRACT, declared = YES)
+interface TestIF2B extends TestIF2 {
+ String method();
+}
+
+@MethodDesc(name = "method", retval = "", mod = ABSTRACT, declared = YES)
+interface TestIF18 extends TestIF10, TestIF2A {
+ String method();
+}
+
+@MethodDesc(name = "method", retval = "", mod = ABSTRACT, declared = NO)
+@MethodDesc(name = "defaultMethod", retval = "TestIF12.defaultMethod", mod = DEFAULT, declared = NO)
+interface TestIF19 extends TestIF12, TestIF2B {
+}
+
+@MethodDesc(name = "staticMethod", retval = "TestIF20.staticMethod", mod = STATIC, declared = YES)
+@MethodDesc(name = "defaultMethod", retval = "TestIF12.defaultMethod", mod = DEFAULT, declared = NO)
+interface TestIF20 extends TestIF12, TestIF2A {
+ static String staticMethod() {
+ return "TestIF20.staticMethod";
+ }
+}
+
+@MethodDesc(name = "method", retval = "", mod = ABSTRACT, declared = NO)
+interface TestIF21 extends TestIF2A, TestIF2B {
+}
+
public class DefaultStaticTestData {
/**
@@ -343,22 +383,23 @@
static Object[][] testClasses() {
return new Object[][]{
{"TestClass1", null},
- //{"TestClass2", null}, @ignore due to JDK-8009411
+ {"TestClass2", null},
{"TestClass3", null},
- //{"TestClass4", null}, @ignore due to JDK-8009411
- //{"TestClass5", null}, @ignore due to JDK-8009411
- //{"TestClass6", null}, @ignore due to JDK-8009411
+ {"TestClass4", null},
+ {"TestClass5", null},
+ {"TestClass6", null},
{"TestClass7", "TestIF7.TestClass7"},
{"TestClass8", "TestIF8.TestClass8"},
{"TestClass9", null},
{"TestClass91", null},
- //{"TestClass11", null}, @ignore due to JDK-8009411
- //{"TestClass12", null}, @ignore due to JDK-8009411
+ {"TestClass11", null},
+ {"TestClass12", null},
{"TestClass13", null},
{"TestClass14", null},
{"TestClass15", null},
- {"TestClass16", null}
- //{"TestClass17", null} @ignore due to JDK-8009411
+ {"TestClass16", null},
+ {"TestClass17", null},
+ {"TestClass18", null},
};
}
@@ -372,6 +413,8 @@
return new Object[][]{
{"TestIF1", null},
{"TestIF2", null},
+ {"TestIF2A", null},
+ {"TestIF2B", null},
{"TestIF3", null},
{"TestIF4", null},
{"TestIF5", null},
@@ -388,7 +431,12 @@
{"TestIF1D", null},
{"TestIF15", null},
{"TestIF16", null},
- {"TestIF17", null},};
+ {"TestIF17", null},
+ {"TestIF18", null},
+ {"TestIF19", null},
+ {"TestIF20", null},
+ {"TestIF21", null},
+ };
}
@DataProvider
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java Tue Oct 22 12:33:33 2013 +0100
@@ -0,0 +1,183 @@
+/*
+ * 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 8009411
+ * @summary Test that a static method on an interface doesn't hide a default
+ * method with the same name and signature in a separate compilation
+ * scenario.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
+
+import sun.misc.IOUtils;
+
+public class StaticInterfaceMethodInWayOfDefault {
+ public interface A_v1 {
+ }
+
+ public interface A_v2 {
+ default void m() {
+ System.err.println("A.m() called");
+ }
+ }
+
+ public interface B extends A_v1 {
+ static void m() {
+ System.err.println("B.m() called");
+ }
+ }
+
+ public interface C_v1 extends B {
+ default void m() {
+ System.err.println("C.m() called");
+ }
+ }
+
+ public interface C_v2 extends B {
+ }
+
+ public static class TestTask implements Callable<String> {
+ @Override
+ public String call() {
+ try {
+ Method m = C_v1.class.getMethod("m", (Class<?>[])null);
+ return m.getDeclaringClass().getSimpleName();
+ } catch (NoSuchMethodException e) {
+ System.err.println("Couldn't find method");
+ return "ERROR";
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ int errors = 0;
+ Callable<String> v1Task = new TestTask();
+
+ ClassLoader v2Loader = new V2ClassLoader(
+ StaticInterfaceMethodInWayOfDefault.class.getClassLoader());
+ Callable<String> v2Task = (Callable<String>) Class.forName(
+ TestTask.class.getName(),
+ true,
+ v2Loader).newInstance();
+
+ System.err.println("Running using _v1 classes:");
+ String res = v1Task.call();
+ if(!res.equals("C_v1")) {
+ System.err.println("Got wrong method, expecting C_v1, got: " + res);
+ errors++;
+ }
+
+ System.err.println("Running using _v2 classes:");
+ res = v2Task.call();
+ if(!res.equals("A_v1")) {
+ System.err.println("Got wrong method, expecting A_v1, got: " + res);
+ errors++;
+ }
+
+ if (errors != 0)
+ throw new RuntimeException("Errors found, check log for details");
+ }
+
+ /**
+ * A ClassLoader implementation that loads alternative implementations of
+ * classes. If class name ends with "_v1" it locates instead a class with
+ * name ending with "_v2" and loads that class instead.
+ */
+ static class V2ClassLoader extends ClassLoader {
+ V2ClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+
+ @Override
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ if (name.indexOf('.') < 0) { // root package is our class
+ synchronized (getClassLoadingLock(name)) {
+ // First, check if the class has already been loaded
+ Class<?> c = findLoadedClass(name);
+ if (c == null) {
+ c = findClass(name);
+ }
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+ }
+ }
+ else { // not our class
+ return super.loadClass(name, resolve);
+ }
+ }
+
+ @Override
+ protected Class<?> findClass(String name)
+ throws ClassNotFoundException {
+ // special class name -> replace it with alternative name
+ if (name.endsWith("_v1")) {
+ String altName = name.substring(0, name.length() - 3) + "_v2";
+ String altPath = altName.replace('.', '/').concat(".class");
+ try (InputStream is = getResourceAsStream(altPath)) {
+ if (is != null) {
+ byte[] bytes = IOUtils.readFully(is, -1, true);
+ // patch class bytes to contain original name
+ for (int i = 0; i < bytes.length - 2; i++) {
+ if (bytes[i] == '_' &&
+ bytes[i + 1] == 'v' &&
+ bytes[i + 2] == '2') {
+ bytes[i + 2] = '1';
+ }
+ }
+ return defineClass(name, bytes, 0, bytes.length);
+ }
+ else {
+ throw new ClassNotFoundException(name);
+ }
+ }
+ catch (IOException e) {
+ throw new ClassNotFoundException(name, e);
+ }
+ }
+ else { // not special class name -> just load the class
+ String path = name.replace('.', '/').concat(".class");
+ try (InputStream is = getResourceAsStream(path)) {
+ if (is != null) {
+ byte[] bytes = IOUtils.readFully(is, -1, true);
+ return defineClass(name, bytes, 0, bytes.length);
+ }
+ else {
+ throw new ClassNotFoundException(name);
+ }
+ }
+ catch (IOException e) {
+ throw new ClassNotFoundException(name, e);
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/FileChannel/InterruptMapDeadlock.java Tue Oct 22 12:33:33 2013 +0100
@@ -0,0 +1,155 @@
+/*
+ * 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 8024833
+ * @summary Tests interruption of threads mapping sections of a file channel in
+ * an attempt to deadlock due to nesting of begin calls.
+ */
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.nio.channels.FileChannel.MapMode;
+import java.nio.file.*;
+import java.util.concurrent.Semaphore;
+import static java.nio.file.StandardOpenOption.*;
+
+public class InterruptMapDeadlock {
+
+ static class Mapper extends Thread {
+ final FileChannel fc;
+ final Semaphore gate;
+ volatile Exception exception;
+
+ Mapper(FileChannel fc, Semaphore gate) {
+ this.fc = fc;
+ this.gate = gate;
+ }
+
+ @Override
+ public void run() {
+ try {
+ gate.acquireUninterruptibly();
+ fc.map(MapMode.READ_ONLY, 0, 1);
+ throw new Exception("Map succeeded");
+ } catch (IOException x) {
+ System.out.println(x.getClass() + " (expected)");
+ } catch (Exception unexpected) {
+ this.exception = unexpected;
+ }
+ }
+
+ Exception exception() {
+ return exception;
+ }
+
+ static Mapper startMapper(FileChannel fc, Semaphore gate) {
+ Mapper r = new Mapper(fc, gate);
+ r.setDaemon(true);
+ r.start();
+ return r;
+ }
+ }
+
+ static class Interruptor extends Thread {
+
+ final Mapper[] mappers;
+ final Semaphore gate;
+
+ Interruptor(Mapper[] mappers, Semaphore gate) {
+ this.mappers = mappers;
+ this.gate = gate;
+ }
+
+ public void run() {
+ gate.release(mappers.length);
+ for (Mapper m : mappers) {
+ m.interrupt();
+ }
+ }
+ }
+ // the number of mapper threads to start
+ private static final int MAPPER_COUNT = 4;
+
+ public static void main(String[] args) throws Exception {
+ Path file = Paths.get("data.txt");
+ FileChannel.open(file, CREATE, TRUNCATE_EXISTING, WRITE).close();
+
+ Mapper[] mappers = new Mapper[MAPPER_COUNT];
+
+ for (int i=1; i<=20; i++) {
+ System.out.format("Iteration: %s%n", i);
+
+ FileChannel fc = FileChannel.open(file);
+ boolean failed = false;
+
+ Semaphore gate = new Semaphore(0);
+ // start mapper threads
+ for (int j=0; j<MAPPER_COUNT; j++) {
+ mappers[j] = Mapper.startMapper(fc, gate);
+ }
+
+ // interrupt and wait for the mappers to terminate
+ Interruptor interruptor = new Interruptor(mappers, gate);
+ interruptor.start();
+ try {
+ interruptor.join(10000);
+ if (interruptor.isAlive()) {
+ System.err.println("Interruptor thread did not terminate:");
+ Throwable t = new Exception("Stack trace");
+ t.setStackTrace(interruptor.getStackTrace());
+ t.printStackTrace();
+ failed = true;
+ }
+ } catch (InterruptedException x) {
+ System.err.println("Main thread was interrupted");
+ failed = true;
+ }
+
+ for (Mapper m: mappers) {
+ try {
+ m.join(10000);
+ Exception e = m.exception();
+ if (e != null) {
+ System.err.println("Mapper thread failed with: " + e);
+ failed = true;
+ } else if (m.isAlive()) {
+ System.err.println("Mapper thread did not terminate:");
+ Throwable t = new Exception("Stack trace");
+ t.setStackTrace(m.getStackTrace());
+ t.printStackTrace();
+ failed = true;
+ }
+ } catch (InterruptedException x) {
+ System.err.println("Main thread was interrupted");
+ failed = true;
+ }
+ }
+
+ if (failed)
+ throw new RuntimeException("Test failed - see log for details");
+ else
+ fc.close();
+ }
+ }
+}
--- a/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java Tue Oct 22 12:33:33 2013 +0100
@@ -112,13 +112,13 @@
}
private static Set<ZoneId> preferred = new HashSet<>(Arrays.asList(new ZoneId[] {
- ZoneId.of("EST"),
+ ZoneId.of("EST", ZoneId.SHORT_IDS),
ZoneId.of("Asia/Taipei"),
ZoneId.of("CET"),
}));
private static Set<ZoneId> preferred_s = new HashSet<>(Arrays.asList(new ZoneId[] {
- ZoneId.of("EST"),
+ ZoneId.of("EST", ZoneId.SHORT_IDS),
ZoneId.of("CET"),
ZoneId.of("Australia/South"),
ZoneId.of("Australia/West"),
@@ -131,7 +131,7 @@
Object[][] data_preferredZones() {
return new Object[][] {
{"America/New_York", "Eastern Standard Time", none, Locale.ENGLISH, TextStyle.FULL},
- {"EST", "Eastern Standard Time", preferred, Locale.ENGLISH, TextStyle.FULL},
+// {"EST", "Eastern Standard Time", preferred, Locale.ENGLISH, TextStyle.FULL},
{"Europe/Paris", "Central European Time", none, Locale.ENGLISH, TextStyle.FULL},
{"CET", "Central European Time", preferred, Locale.ENGLISH, TextStyle.FULL},
{"Asia/Shanghai", "China Standard Time", none, Locale.ENGLISH, TextStyle.FULL},
--- a/jdk/test/sun/nio/cs/TestIBMBugs.java Mon Oct 21 15:00:56 2013 +0100
+++ b/jdk/test/sun/nio/cs/TestIBMBugs.java Tue Oct 22 12:33:33 2013 +0100
@@ -147,16 +147,17 @@
}
private static void bug6569191 () throws Exception {
- byte[] bs = new byte[] { (byte)0x81, (byte)0xad,
- (byte)0x81, (byte)0xae,
- (byte)0x81, (byte)0xaf,
- (byte)0x81, (byte)0xb0,
- (byte)0x85, (byte)0x81,
- (byte)0x85, (byte)0x87,
- (byte)0x85, (byte)0xe0,
- (byte)0x85, (byte)0xf0 };
+ byte[] bs = new byte[] { (byte)0x81, (byte)0xad, // fffd ff6d
+ (byte)0x81, (byte)0xae, // fffd ff6e
+ (byte)0x81, (byte)0xaf, // fffd ff6f
+ (byte)0x81, (byte)0xb0, // fffd ff70
+ (byte)0x85, (byte)0x81, // fffd ->
+ (byte)0x85, (byte)0x87, // 2266 ->
+ (byte)0x85, (byte)0xe0, // 32a4 ->
+ (byte)0x85, (byte)0xf0 };// 7165 fffd
String s = new String(bs, "Cp943");
- if (!"\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"
+ // see DoubleByte for how the unmappables are handled
+ if (!"\ufffd\uff6d\ufffd\uff6e\ufffd\uff6f\ufffd\uff70\ufffd\u2266\u32a4\u7165\ufffd"
.equals(s))
throw new Exception("Cp943 failed");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/nio/cs/TestUnmappable.java Tue Oct 22 12:33:33 2013 +0100
@@ -0,0 +1,87 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008386
+ * @summary (cs) Unmappable leading should be decoded to replacement.
+ * Tests for Shift_JIS and MS932 decoding
+ * @run main TestUnmappable
+ */
+
+import java.nio.*;
+import java.nio.charset.*;
+
+public class TestUnmappable {
+ public static void main(String args[]) throws Exception {
+
+ // illegal leading character test
+ byte[][] inputBytes = {
+ // Shift_JIS
+ {(byte)0xce, (byte)0xa0, (byte)0xce, (byte)0x7a},
+ // MS932
+ {(byte)0x3c, (byte)0x21, (byte)0x2d, (byte)0x2d,
+ (byte)0xe5, (byte)0xaf, (byte)0xbe, (byte)0xe5,
+ (byte)0xbf, (byte)0x9c, (byte)0x2d, (byte)0x2d,
+ (byte)0x3e, (byte)0xd, (byte)0xa },
+ {(byte)0x81, (byte)0xad},
+ // PCK
+ {(byte)0xef, (byte)0x90},
+ {(byte)0x91, (byte)0xfd}
+ };
+
+ String[] charsets = { "Shift_JIS", "MS932", "PCK" };
+ String[] expectedStrings = {
+ // Shift_JIS
+ "0xce 0x3f 0xce 0x7a ",
+ // MS932
+ "0x3c 0x21 0x2d 0x2d 0xe5 0xaf 0xbe 0xe5 0xbf " +
+ "0x3f 0x2d 0x2d 0x3e 0xd 0xa ",
+ "0x3f 0xad ",
+ // PCK
+ "0x3f 0x3f ",
+ "0x3f "};
+
+ for (int i = 0; i < charsets.length; i++) {
+ String ret = new String(inputBytes[i], charsets[i]);
+ String bString = getByteString(ret.getBytes(Charset.forName(charsets[i])));
+ if (expectedStrings[i].length() != bString.length()
+ || ! expectedStrings[i].equals(bString)){
+ throw new Exception("ByteToChar for " + charsets[i]
+ + " does not work correctly.\n" +
+ "Expected: " + expectedStrings[i] + "\n" +
+ "Received: " + bString);
+ }
+ }
+ }
+
+ private static String getByteString(byte[] bytes) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < bytes.length; i++) {
+ sb.append("0x" + Integer.toHexString((int)(bytes[i] & 0xFF)) + " ");
+ }
+ return sb.toString();
+ }
+}