提交 2bab3577 编写于 作者: L lana

Merge

...@@ -129,9 +129,9 @@ LIBJAVA_SRC_DIRS := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/l ...@@ -129,9 +129,9 @@ LIBJAVA_SRC_DIRS := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/l
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/common \ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/common \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/util $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/util
ifneq ($(OPENJDK_TARGET_OS), macosx) ifeq ($(OPENJDK_TARGET_OS), windows)
LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/util/locale/provider LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/util/locale/provider
else else ifeq ($(OPENJDK_TARGET_OS), macosx)
LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/util/locale/provider LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/util/locale/provider
endif endif
......
...@@ -287,8 +287,6 @@ SUNWprivate_1.1 { ...@@ -287,8 +287,6 @@ SUNWprivate_1.1 {
# Java_sun_misc_VM_unsuspendSomeThreads; threads.c # Java_sun_misc_VM_unsuspendSomeThreads; threads.c
# Java_sun_misc_VM_unsuspendThreads; threads.c # Java_sun_misc_VM_unsuspendThreads; threads.c
Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPattern;
# Outcalls from libjvm done using dlsym(). # Outcalls from libjvm done using dlsym().
VerifyClassCodes; VerifyClassCodes;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
#include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h" #include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h"
#include "jni_util.h"
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
#include <stdio.h> #include <stdio.h>
...@@ -63,6 +64,10 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -63,6 +64,10 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
localeString = getMacOSXLocale(posixCat); localeString = getMacOSXLocale(posixCat);
if (localeString == NULL) { if (localeString == NULL) {
localeString = getPosixLocale(posixCat); localeString = getPosixLocale(posixCat);
if (localeString == NULL) {
JNU_ThrowOutOfMemoryError(env, NULL);
return NULL;
}
} }
ret = (*env)->NewStringUTF(env, localeString); ret = (*env)->NewStringUTF(env, localeString);
free(localeString); free(localeString);
...@@ -127,6 +132,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -127,6 +132,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getAmPmStrings JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getAmPmStrings
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) { (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) {
CFLocaleRef cflocale = CFLocaleCopyCurrent(); CFLocaleRef cflocale = CFLocaleCopyCurrent();
jstring tmp_string;
if (cflocale != NULL) { if (cflocale != NULL) {
CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault, CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,
cflocale, cflocale,
...@@ -138,13 +144,21 @@ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderA ...@@ -138,13 +144,21 @@ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderA
if (amStr != NULL) { if (amStr != NULL) {
CFStringGetCString(amStr, buf, BUFLEN, kCFStringEncodingUTF8); CFStringGetCString(amStr, buf, BUFLEN, kCFStringEncodingUTF8);
CFRelease(amStr); CFRelease(amStr);
(*env)->SetObjectArrayElement(env, ampms, 0, (*env)->NewStringUTF(env, buf)); tmp_string = (*env)->NewStringUTF(env, buf);
if (tmp_string != NULL) {
(*env)->SetObjectArrayElement(env, ampms, 0, tmp_string);
}
} }
CFStringRef pmStr = CFDateFormatterCopyProperty(df, kCFDateFormatterPMSymbol); if (!(*env)->ExceptionCheck(env)){
if (pmStr != NULL) { CFStringRef pmStr = CFDateFormatterCopyProperty(df, kCFDateFormatterPMSymbol);
CFStringGetCString(pmStr, buf, BUFLEN, kCFStringEncodingUTF8); if (pmStr != NULL) {
CFRelease(pmStr); CFStringGetCString(pmStr, buf, BUFLEN, kCFStringEncodingUTF8);
(*env)->SetObjectArrayElement(env, ampms, 1, (*env)->NewStringUTF(env, buf)); CFRelease(pmStr);
tmp_string = (*env)->NewStringUTF(env, buf);
if (tmp_string != NULL) {
(*env)->SetObjectArrayElement(env, ampms, 1, tmp_string);
}
}
} }
CFRelease(df); CFRelease(df);
} }
...@@ -647,10 +661,16 @@ static CFNumberFormatterStyle convertNumberFormatterStyle(jint javaStyle) { ...@@ -647,10 +661,16 @@ static CFNumberFormatterStyle convertNumberFormatterStyle(jint javaStyle) {
static void copyArrayElements(JNIEnv *env, CFArrayRef cfarray, jobjectArray jarray, CFIndex sindex, int dindex, int count) { static void copyArrayElements(JNIEnv *env, CFArrayRef cfarray, jobjectArray jarray, CFIndex sindex, int dindex, int count) {
char buf[BUFLEN]; char buf[BUFLEN];
jstring tmp_string;
for (; count > 0; sindex++, dindex++, count--) { for (; count > 0; sindex++, dindex++, count--) {
CFStringGetCString(CFArrayGetValueAtIndex(cfarray, sindex), buf, BUFLEN, kCFStringEncodingUTF8); CFStringGetCString(CFArrayGetValueAtIndex(cfarray, sindex), buf, BUFLEN, kCFStringEncodingUTF8);
(*env)->SetObjectArrayElement(env, jarray, dindex, (*env)->NewStringUTF(env, buf)); tmp_string = (*env)->NewStringUTF(env, buf);
if (tmp_string != NULL) {
(*env)->SetObjectArrayElement(env, jarray, dindex, tmp_string);
} else {
break;
}
} }
} }
......
...@@ -93,6 +93,14 @@ public class ByteArrayOutputStream extends OutputStream { ...@@ -93,6 +93,14 @@ public class ByteArrayOutputStream extends OutputStream {
grow(minCapacity); grow(minCapacity);
} }
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/** /**
* Increases the capacity to ensure that it can hold at least the * Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument. * number of elements specified by the minimum capacity argument.
...@@ -105,14 +113,19 @@ public class ByteArrayOutputStream extends OutputStream { ...@@ -105,14 +113,19 @@ public class ByteArrayOutputStream extends OutputStream {
int newCapacity = oldCapacity << 1; int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0) if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; newCapacity = minCapacity;
if (newCapacity < 0) { if (newCapacity - MAX_ARRAY_SIZE > 0)
if (minCapacity < 0) // overflow newCapacity = hugeCapacity(minCapacity);
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
buf = Arrays.copyOf(buf, newCapacity); buf = Arrays.copyOf(buf, newCapacity);
} }
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/** /**
* Writes the specified byte to this byte array output stream. * Writes the specified byte to this byte array output stream.
* *
......
...@@ -188,7 +188,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; ...@@ -188,7 +188,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static MethodHandle makePairwiseConvert(MethodHandle target, MethodType srcType, static MethodHandle makePairwiseConvert(MethodHandle target, MethodType srcType,
boolean strict, boolean monobox) { boolean strict, boolean monobox) {
MethodType dstType = target.type(); MethodType dstType = target.type();
assert(dstType.parameterCount() == target.type().parameterCount());
if (srcType == dstType) if (srcType == dstType)
return target; return target;
if (USE_LAMBDA_FORM_EDITOR) { if (USE_LAMBDA_FORM_EDITOR) {
...@@ -265,6 +264,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; ...@@ -265,6 +264,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static MethodHandle makePairwiseConvertIndirect(MethodHandle target, MethodType srcType, static MethodHandle makePairwiseConvertIndirect(MethodHandle target, MethodType srcType,
boolean strict, boolean monobox) { boolean strict, boolean monobox) {
assert(target.type().parameterCount() == srcType.parameterCount());
// Calculate extra arguments (temporaries) required in the names array. // Calculate extra arguments (temporaries) required in the names array.
Object[] convSpecs = computeValueConversions(srcType, target.type(), strict, monobox); Object[] convSpecs = computeValueConversions(srcType, target.type(), strict, monobox);
final int INARG_COUNT = srcType.parameterCount(); final int INARG_COUNT = srcType.parameterCount();
......
...@@ -2024,12 +2024,22 @@ return invoker; ...@@ -2024,12 +2024,22 @@ return invoker;
*/ */
public static public static
MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) { MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
if (!target.type().isCastableTo(newType)) { explicitCastArgumentsChecks(target, newType);
throw new WrongMethodTypeException("cannot explicitly cast "+target+" to "+newType); // use the asTypeCache when possible:
MethodType oldType = target.type();
if (oldType == newType) return target;
if (oldType.explicitCastEquivalentToAsType(newType)) {
return target.asType(newType);
} }
return MethodHandleImpl.makePairwiseConvert(target, newType, false); return MethodHandleImpl.makePairwiseConvert(target, newType, false);
} }
private static void explicitCastArgumentsChecks(MethodHandle target, MethodType newType) {
if (target.type().parameterCount() != newType.parameterCount()) {
throw new WrongMethodTypeException("cannot explicitly cast " + target + " to " + newType);
}
}
/** /**
* Produces a method handle which adapts the calling sequence of the * Produces a method handle which adapts the calling sequence of the
* given method handle to a new type, by reordering the arguments. * given method handle to a new type, by reordering the arguments.
...@@ -2162,7 +2172,7 @@ assert((int)twice.invokeExact(21) == 42); ...@@ -2162,7 +2172,7 @@ assert((int)twice.invokeExact(21) == 42);
// dropIdx is missing from reorder; add it in at the end // dropIdx is missing from reorder; add it in at the end
int oldArity = reorder.length; int oldArity = reorder.length;
target = dropArguments(target, oldArity, newType.parameterType(dropIdx)); target = dropArguments(target, oldArity, newType.parameterType(dropIdx));
reorder = Arrays.copyOf(reorder, oldArity+1); reorder = Arrays.copyOf(reorder, oldArity + 1);
reorder[oldArity] = dropIdx; reorder[oldArity] = dropIdx;
} }
assert(target == originalTarget || permuteArgumentChecks(reorder, newType, target.type())); assert(target == originalTarget || permuteArgumentChecks(reorder, newType, target.type()));
...@@ -2180,9 +2190,9 @@ assert((int)twice.invokeExact(21) == 42); ...@@ -2180,9 +2190,9 @@ assert((int)twice.invokeExact(21) == 42);
long mask = 0; long mask = 0;
for (int arg : reorder) { for (int arg : reorder) {
assert(arg < newArity); assert(arg < newArity);
mask |= (1 << arg); mask |= (1L << arg);
} }
if (mask == (1 << newArity) - 1) { if (mask == (1L << newArity) - 1) {
assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity); assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity);
return -1; return -1;
} }
...@@ -2191,16 +2201,18 @@ assert((int)twice.invokeExact(21) == 42); ...@@ -2191,16 +2201,18 @@ assert((int)twice.invokeExact(21) == 42);
int zeroPos = Long.numberOfTrailingZeros(zeroBit); int zeroPos = Long.numberOfTrailingZeros(zeroBit);
assert(zeroPos < newArity); assert(zeroPos < newArity);
return zeroPos; return zeroPos;
} else {
BitSet mask = new BitSet(newArity);
for (int arg : reorder) {
assert (arg < newArity);
mask.set(arg);
}
int zeroPos = mask.nextClearBit(0);
assert(zeroPos <= newArity);
if (zeroPos == newArity)
return -1;
return zeroPos;
} }
BitSet mask = new BitSet(newArity);
for (int arg : reorder) {
assert(arg < newArity);
mask.set(arg);
}
int zeroPos = mask.nextClearBit(0);
if (zeroPos == newArity)
return -1;
return zeroPos;
} }
/** /**
...@@ -2216,32 +2228,42 @@ assert((int)twice.invokeExact(21) == 42); ...@@ -2216,32 +2228,42 @@ assert((int)twice.invokeExact(21) == 42);
long mask = 0; long mask = 0;
for (int i = 0; i < reorder.length; i++) { for (int i = 0; i < reorder.length; i++) {
int arg = reorder[i]; int arg = reorder[i];
if (arg >= newArity) return reorder.length; if (arg >= newArity) {
int bit = 1 << arg; return reorder.length;
if ((mask & bit) != 0) }
long bit = 1L << arg;
if ((mask & bit) != 0) {
return i; // >0 indicates a dup return i; // >0 indicates a dup
}
mask |= bit; mask |= bit;
} }
if (mask == (1 << newArity) - 1) { if (mask == (1L << newArity) - 1) {
assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity); assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity);
return 0; return 0;
} }
// find first zero // find first zero
long zeroBit = Long.lowestOneBit(~mask); long zeroBit = Long.lowestOneBit(~mask);
int zeroPos = Long.numberOfTrailingZeros(zeroBit); int zeroPos = Long.numberOfTrailingZeros(zeroBit);
assert(zeroPos < newArity); assert(zeroPos <= newArity);
if (zeroPos == newArity) {
return 0;
}
return ~zeroPos; return ~zeroPos;
} else { } else {
// same algorithm, different bit set // same algorithm, different bit set
BitSet mask = new BitSet(newArity); BitSet mask = new BitSet(newArity);
for (int i = 0; i < reorder.length; i++) { for (int i = 0; i < reorder.length; i++) {
int arg = reorder[i]; int arg = reorder[i];
if (arg >= newArity) return reorder.length; if (arg >= newArity) {
if (mask.get(arg)) return reorder.length;
}
if (mask.get(arg)) {
return i; // >0 indicates a dup return i; // >0 indicates a dup
}
mask.set(arg); mask.set(arg);
} }
int zeroPos = mask.nextClearBit(0); int zeroPos = mask.nextClearBit(0);
assert(zeroPos <= newArity);
if (zeroPos == newArity) { if (zeroPos == newArity) {
return 0; return 0;
} }
...@@ -2477,6 +2499,7 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z")); ...@@ -2477,6 +2499,7 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) { MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
MethodType oldType = target.type(); // get NPE MethodType oldType = target.type(); // get NPE
int dropped = dropArgumentChecks(oldType, pos, valueTypes); int dropped = dropArgumentChecks(oldType, pos, valueTypes);
MethodType newType = oldType.insertParameterTypes(pos, valueTypes);
if (dropped == 0) return target; if (dropped == 0) return target;
BoundMethodHandle result = target.rebind(); BoundMethodHandle result = target.rebind();
LambdaForm lform = result.form; LambdaForm lform = result.form;
...@@ -2488,7 +2511,6 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z")); ...@@ -2488,7 +2511,6 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
} else { } else {
lform = lform.addArguments(pos, valueTypes); lform = lform.addArguments(pos, valueTypes);
} }
MethodType newType = oldType.insertParameterTypes(pos, valueTypes);
result = result.copyWith(newType, lform); result = result.copyWith(newType, lform);
return result; return result;
} }
......
...@@ -827,26 +827,6 @@ class MethodType implements java.io.Serializable { ...@@ -827,26 +827,6 @@ class MethodType implements java.io.Serializable {
return true; return true;
} }
/*non-public*/ /*non-public*/
boolean isCastableTo(MethodType newType) {
MethodTypeForm oldForm = this.form();
MethodTypeForm newForm = newType.form();
if (oldForm == newForm)
// same parameter count, same primitive/object mix
return true;
int argc = parameterCount();
if (argc != newType.parameterCount())
return false;
// Corner case: boxing (primitive-to-reference) must have a plausible target type
// Therefore, we may have to return false for a boxing operation.
if (!canCast(returnType(), newType.returnType()))
return false;
if (newForm.primitiveParameterCount() == 0)
return true; // no primitive sources to mess things up
if (oldForm.erasedType == this)
return true; // no funny target references to mess things up
return canCastParameters(newType.ptypes, ptypes);
}
/*non-public*/
boolean isConvertibleTo(MethodType newType) { boolean isConvertibleTo(MethodType newType) {
MethodTypeForm oldForm = this.form(); MethodTypeForm oldForm = this.form();
MethodTypeForm newForm = newType.form(); MethodTypeForm newForm = newType.form();
...@@ -877,15 +857,66 @@ class MethodType implements java.io.Serializable { ...@@ -877,15 +857,66 @@ class MethodType implements java.io.Serializable {
return canConvertParameters(srcTypes, dstTypes); return canConvertParameters(srcTypes, dstTypes);
} }
private boolean canCastParameters(Class<?>[] srcTypes, Class<?>[] dstTypes) { /** Returns true if MHs.explicitCastArguments produces the same result as MH.asType.
for (int i = 0; i < srcTypes.length; i++) { * If the type conversion is impossible for either, the result should be false.
if (!canCast(srcTypes[i], dstTypes[i])) { */
/*non-public*/
boolean explicitCastEquivalentToAsType(MethodType newType) {
if (this == newType) return true;
if (!explicitCastEquivalentToAsType(rtype, newType.rtype)) {
return false;
}
Class<?>[] srcTypes = newType.ptypes;
Class<?>[] dstTypes = ptypes;
if (dstTypes == srcTypes) {
return true;
}
assert(dstTypes.length == srcTypes.length);
for (int i = 0; i < dstTypes.length; i++) {
if (!explicitCastEquivalentToAsType(srcTypes[i], dstTypes[i])) {
return false; return false;
} }
} }
return true; return true;
} }
/** Reports true if the src can be converted to the dst, by both asType and MHs.eCE,
* and with the same effect.
* MHs.eCA has the following "upgrades" to MH.asType:
* 1. interfaces are unchecked (that is, treated as if aliased to Object)
* Therefore, {@code Object->CharSequence} is possible in both cases but has different semantics
* 2. the full matrix of primitive-to-primitive conversions is supported
* Narrowing like {@code long->byte} and basic-typing like {@code boolean->int}
* are not supported by asType, but anything supported by asType is equivalent
* with MHs.eCE.
* 3a. unboxing conversions can be followed by the full matrix of primitive conversions
* 3b. unboxing of null is permitted (creates a zero primitive value)
* Most unboxing conversions, like {@code Object->int}, has potentially
* different behaviors for asType vs. MHs.eCE, because the dynamic value
* might be a wrapper of a type that requires narrowing, like {@code (Object)1L->byte}.
* The equivalence is only certain if the static src type is a wrapper,
* and the conversion will be a widening one.
* Other than interfaces, reference-to-reference conversions are the same.
* Boxing primitives to references is the same for both operators.
*/
private static boolean explicitCastEquivalentToAsType(Class<?> src, Class<?> dst) {
if (src == dst || dst == Object.class || dst == void.class) return true;
if (src.isPrimitive()) {
// Could be a prim/prim conversion, where casting is a strict superset.
// Or a boxing conversion, which is always to an exact wrapper class.
return canConvert(src, dst);
} else if (dst.isPrimitive()) {
Wrapper dw = Wrapper.forPrimitiveType(dst);
// Watch out: If src is Number or Object, we could get dynamic narrowing conversion.
// The conversion is known to be widening only if the wrapper type is statically visible.
return (Wrapper.isWrapperType(src) &&
dw.isConvertibleFrom(Wrapper.forWrapperType(src)));
} else {
// R->R always works, but we have to avoid a check-cast to an interface.
return !dst.isInterface() || dst.isAssignableFrom(src);
}
}
private boolean canConvertParameters(Class<?>[] srcTypes, Class<?>[] dstTypes) { private boolean canConvertParameters(Class<?>[] srcTypes, Class<?>[] dstTypes) {
for (int i = 0; i < srcTypes.length; i++) { for (int i = 0; i < srcTypes.length; i++) {
if (!canConvert(srcTypes[i], dstTypes[i])) { if (!canConvert(srcTypes[i], dstTypes[i])) {
...@@ -895,16 +926,6 @@ class MethodType implements java.io.Serializable { ...@@ -895,16 +926,6 @@ class MethodType implements java.io.Serializable {
return true; return true;
} }
private static boolean canCast(Class<?> src, Class<?> dst) {
if (src.isPrimitive() && !dst.isPrimitive()) {
if (dst == Object.class || dst.isInterface()) return true;
// Here is the corner case that is not castable. Example: int -> String
Wrapper sw = Wrapper.forPrimitiveType(src);
return dst.isAssignableFrom(sw.wrapperType());
}
return true;
}
/*non-public*/ /*non-public*/
static boolean canConvert(Class<?> src, Class<?> dst) { static boolean canConvert(Class<?> src, Class<?> dst) {
// short-circuit a few cases: // short-circuit a few cases:
......
...@@ -557,33 +557,15 @@ public final class Constructor<T> extends Executable { ...@@ -557,33 +557,15 @@ public final class Constructor<T> extends Executable {
*/ */
@Override @Override
public AnnotatedType getAnnotatedReceiverType() { public AnnotatedType getAnnotatedReceiverType() {
Class<?> thisDeclClass = getDeclaringClass(); if (getDeclaringClass().getEnclosingClass() == null)
Class<?> enclosingClass = thisDeclClass.getEnclosingClass(); return super.getAnnotatedReceiverType();
if (enclosingClass == null) {
// A Constructor for a top-level class
return null;
}
Class<?> outerDeclaringClass = thisDeclClass.getDeclaringClass();
if (outerDeclaringClass == null) {
// A constructor for a local or anonymous class
return null;
}
// Either static nested or inner class
if (Modifier.isStatic(thisDeclClass.getModifiers())) {
// static nested
return null;
}
// A Constructor for an inner class
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(), return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess(). sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(thisDeclClass), getConstantPool(getDeclaringClass()),
this, this,
thisDeclClass, getDeclaringClass(),
enclosingClass, getDeclaringClass().getEnclosingClass(),
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER); TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
} }
} }
...@@ -602,24 +602,21 @@ public abstract class Executable extends AccessibleObject ...@@ -602,24 +602,21 @@ public abstract class Executable extends AccessibleObject
/** /**
* Returns an {@code AnnotatedType} object that represents the use of a * Returns an {@code AnnotatedType} object that represents the use of a
* type to specify the receiver type of the method/constructor represented * type to specify the receiver type of the method/constructor represented
* by this {@code Executable} object. * by this Executable object. The receiver type of a method/constructor is
* available only if the method/constructor has a <em>receiver
* parameter</em> (JLS 8.4.1).
* *
* The receiver type of a method/constructor is available only if the * If this {@code Executable} object represents a constructor or instance
* method/constructor has a receiver parameter (JLS 8.4.1). If this {@code * method that does not have a receiver parameter, or has a receiver
* Executable} object <em>represents an instance method or represents a * parameter with no annotations on its type, then the return value is an
* constructor of an inner member class</em>, and the * {@code AnnotatedType} object representing an element with no
* method/constructor <em>either</em> has no receiver parameter or has a
* receiver parameter with no annotations on its type, then the return
* value is an {@code AnnotatedType} object representing an element with no
* annotations. * annotations.
* *
* If this {@code Executable} object represents a static method or * If this {@code Executable} object represents a static method, then the
* represents a constructor of a top level, static member, local, or * return value is null.
* anoymous class, then the return value is null.
* *
* @return an object representing the receiver type of the method or * @return an object representing the receiver type of the method or
* constructor represented by this {@code Executable} or {@code null} if * constructor represented by this {@code Executable}
* this {@code Executable} can not have a receiver parameter
* *
* @since 1.8 * @since 1.8
*/ */
......
...@@ -1261,19 +1261,20 @@ class MutableBigInteger { ...@@ -1261,19 +1261,20 @@ class MutableBigInteger {
int sigma = (int) Math.max(0, n32 - b.bitLength()); // step 3: sigma = max{T | (2^T)*B < beta^n} int sigma = (int) Math.max(0, n32 - b.bitLength()); // step 3: sigma = max{T | (2^T)*B < beta^n}
MutableBigInteger bShifted = new MutableBigInteger(b); MutableBigInteger bShifted = new MutableBigInteger(b);
bShifted.safeLeftShift(sigma); // step 4a: shift b so its length is a multiple of n bShifted.safeLeftShift(sigma); // step 4a: shift b so its length is a multiple of n
safeLeftShift(sigma); // step 4b: shift this by the same amount MutableBigInteger aShifted = new MutableBigInteger (this);
aShifted.safeLeftShift(sigma); // step 4b: shift a by the same amount
// step 5: t is the number of blocks needed to accommodate this plus one additional bit // step 5: t is the number of blocks needed to accommodate a plus one additional bit
int t = (int) ((bitLength()+n32) / n32); int t = (int) ((aShifted.bitLength()+n32) / n32);
if (t < 2) { if (t < 2) {
t = 2; t = 2;
} }
// step 6: conceptually split this into blocks a[t-1], ..., a[0] // step 6: conceptually split a into blocks a[t-1], ..., a[0]
MutableBigInteger a1 = getBlock(t-1, t, n); // the most significant block of this MutableBigInteger a1 = aShifted.getBlock(t-1, t, n); // the most significant block of a
// step 7: z[t-2] = [a[t-1], a[t-2]] // step 7: z[t-2] = [a[t-1], a[t-2]]
MutableBigInteger z = getBlock(t-2, t, n); // the second to most significant block MutableBigInteger z = aShifted.getBlock(t-2, t, n); // the second to most significant block
z.addDisjoint(a1, n); // z[t-2] z.addDisjoint(a1, n); // z[t-2]
// do schoolbook division on blocks, dividing 2-block numbers by 1-block numbers // do schoolbook division on blocks, dividing 2-block numbers by 1-block numbers
...@@ -1284,7 +1285,7 @@ class MutableBigInteger { ...@@ -1284,7 +1285,7 @@ class MutableBigInteger {
ri = z.divide2n1n(bShifted, qi); ri = z.divide2n1n(bShifted, qi);
// step 8b: z = [ri, a[i-1]] // step 8b: z = [ri, a[i-1]]
z = getBlock(i-1, t, n); // a[i-1] z = aShifted.getBlock(i-1, t, n); // a[i-1]
z.addDisjoint(ri, n); z.addDisjoint(ri, n);
quotient.addShifted(qi, i*n); // update q (part of step 9) quotient.addShifted(qi, i*n); // update q (part of step 9)
} }
...@@ -1292,7 +1293,7 @@ class MutableBigInteger { ...@@ -1292,7 +1293,7 @@ class MutableBigInteger {
ri = z.divide2n1n(bShifted, qi); ri = z.divide2n1n(bShifted, qi);
quotient.add(qi); quotient.add(qi);
ri.rightShift(sigma); // step 9: this and b were shifted, so shift back ri.rightShift(sigma); // step 9: a and b were shifted, so shift back
return ri; return ri;
} }
} }
......
...@@ -1335,66 +1335,94 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable ...@@ -1335,66 +1335,94 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable
int maxNotifications, int maxNotifications,
long timeout) long timeout)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
IOException org;
boolean retried = false;
while (true) { // used for a successful re-connection while (true) { // used for a successful re-connection
// or a transient network problem
try { try {
return connection.fetchNotifications(clientSequenceNumber, return connection.fetchNotifications(clientSequenceNumber,
maxNotifications, maxNotifications,
timeout); timeout); // return normally
} catch (IOException ioe) { } catch (IOException ioe) {
org = ioe; // Examine the chain of exceptions to determine whether this
// is a deserialization issue. If so - we propagate the
// appropriate exception to the caller, who will then
// proceed with fetching notifications one by one
rethrowDeserializationException(ioe);
// inform of IOException
try { try {
communicatorAdmin.gotIOException(ioe); communicatorAdmin.gotIOException(ioe);
// reconnection OK, back to "while" to do again
// The connection should be re-established.
continue;
} catch (IOException ee) { } catch (IOException ee) {
// No more fetch, the Exception will be re-thrown. boolean toClose = false;
break;
} // never reached synchronized (this) {
} // never reached if (terminated) {
// the connection is closed.
throw ioe;
} else if (retried) {
toClose = true;
}
}
if (toClose) {
// JDK-8049303
// We received an IOException - but the communicatorAdmin
// did not close the connection - possibly because
// the original exception was raised by a transient network
// problem?
// We already know that this exception is not due to a deserialization
// issue as we already took care of that before involving the
// communicatorAdmin. Moreover - we already made one retry attempt
// at fetching the same batch of notifications - and the
// problem persisted.
// Since trying again doesn't seem to solve the issue, we will now
// close the connection. Doing otherwise might cause the
// NotifFetcher thread to die silently.
final Notification failedNotif =
new JMXConnectionNotification(
JMXConnectionNotification.FAILED,
this,
connectionId,
clientNotifSeqNo++,
"Failed to communicate with the server: " + ioe.toString(),
ioe);
sendNotification(failedNotif);
try {
close(true);
} catch (Exception e) {
// OK.
// We are closing
}
throw ioe; // the connection is closed here.
} else {
// JDK-8049303 possible transient network problem,
// let's try one more time
retried = true;
}
}
}
} }
}
private void rethrowDeserializationException(IOException ioe)
throws ClassNotFoundException, IOException {
// specially treating for an UnmarshalException // specially treating for an UnmarshalException
if (org instanceof UnmarshalException) { if (ioe instanceof UnmarshalException) {
UnmarshalException ume = (UnmarshalException)org; throw ioe; // the fix of 6937053 made ClientNotifForwarder.fetchNotifs
// fetch one by one with UnmarshalException
if (ume.detail instanceof ClassNotFoundException) } else if (ioe instanceof MarshalException) {
throw (ClassNotFoundException) ume.detail;
/* In Sun's RMI implementation, if a method return
contains an unserializable object, then we get
UnmarshalException wrapping WriteAbortedException
wrapping NotSerializableException. In that case we
extract the NotSerializableException so that our
caller can realize it should try to skip past the
notification that presumably caused it. It's not
certain that every other RMI implementation will
generate this exact exception sequence. If not, we
will not detect that the problem is due to an
unserializable object, and we will stop trying to
receive notifications from the server. It's not
clear we can do much better. */
if (ume.detail instanceof WriteAbortedException) {
WriteAbortedException wae =
(WriteAbortedException) ume.detail;
if (wae.detail instanceof IOException)
throw (IOException) wae.detail;
}
} else if (org instanceof MarshalException) {
// IIOP will throw MarshalException wrapping a NotSerializableException // IIOP will throw MarshalException wrapping a NotSerializableException
// when a server fails to serialize a response. // when a server fails to serialize a response.
MarshalException me = (MarshalException)org; MarshalException me = (MarshalException)ioe;
if (me.detail instanceof NotSerializableException) { if (me.detail instanceof NotSerializableException) {
throw (NotSerializableException)me.detail; throw (NotSerializableException)me.detail;
} }
} }
// Not serialization problem, simply re-throw the orginal exception // Not serialization problem, return.
throw org;
} }
protected Integer addListenerForMBeanRemovedNotif() protected Integer addListenerForMBeanRemovedNotif()
......
...@@ -800,14 +800,22 @@ public abstract class FlowView extends BoxView { ...@@ -800,14 +800,22 @@ public abstract class FlowView extends BoxView {
@Override @Override
protected void forwardUpdate(DocumentEvent.ElementChange ec, protected void forwardUpdate(DocumentEvent.ElementChange ec,
DocumentEvent e, Shape a, ViewFactory f) { DocumentEvent e, Shape a, ViewFactory f) {
calculateUpdateIndexes(e); // Update the view responsible for the changed element by invocation of
// Send update event to all views followed by the changed place. // super method.
lastUpdateIndex = Math.max((getViewCount() - 1), 0); super.forwardUpdate(ec, e, a, f);
for (int i = firstUpdateIndex; i <= lastUpdateIndex; i++) { // Re-calculate the update indexes and update the views followed by
View v = getView(i); // the changed place. Note: we update the views only when insertion or
if (v != null) { // removal takes place.
Shape childAlloc = getChildAllocation(i, a); DocumentEvent.EventType type = e.getType();
forwardUpdateToView(v, e, childAlloc, f); if (type == DocumentEvent.EventType.INSERT ||
type == DocumentEvent.EventType.REMOVE) {
firstUpdateIndex = Math.min((lastUpdateIndex + 1), (getViewCount() - 1));
lastUpdateIndex = Math.max((getViewCount() - 1), 0);
for (int i = firstUpdateIndex; i <= lastUpdateIndex; i++) {
View v = getView(i);
if (v != null) {
v.updateAfterChange();
}
} }
} }
} }
......
...@@ -971,6 +971,14 @@ public class GlyphView extends View implements TabableView, Cloneable { ...@@ -971,6 +971,14 @@ public class GlyphView extends View implements TabableView, Cloneable {
} }
} }
/** {@inheritDoc} */
@Override
void updateAfterChange() {
// Drop the break spots. They will be re-calculated during
// layout. It is necessary for proper line break calculation.
breakSpots = null;
}
/** /**
* Class to hold data needed to justify this GlyphView in a PargraphView.Row * Class to hold data needed to justify this GlyphView in a PargraphView.Row
*/ */
......
...@@ -1198,6 +1198,13 @@ public abstract class View implements SwingConstants { ...@@ -1198,6 +1198,13 @@ public abstract class View implements SwingConstants {
firstUpdateIndex = Math.max(firstUpdateIndex, 0); firstUpdateIndex = Math.max(firstUpdateIndex, 0);
} }
/**
* Updates the view to reflect the changes.
*/
void updateAfterChange() {
// Do nothing by default. Should be overridden in subclasses, if any.
}
/** /**
* Forwards the <code>DocumentEvent</code> to the give child view. This * Forwards the <code>DocumentEvent</code> to the give child view. This
* simply messages the view with a call to <code>insertUpdate</code>, * simply messages the view with a call to <code>insertUpdate</code>,
......
...@@ -386,7 +386,7 @@ public abstract class SunToolkit extends Toolkit ...@@ -386,7 +386,7 @@ public abstract class SunToolkit extends Toolkit
* null or the target can't be found, a null with be returned. * null or the target can't be found, a null with be returned.
*/ */
public static AppContext targetToAppContext(Object target) { public static AppContext targetToAppContext(Object target) {
if (target == null || GraphicsEnvironment.isHeadless()) { if (target == null) {
return null; return null;
} }
AppContext context = getAppContext(target); AppContext context = getAppContext(target);
...@@ -460,12 +460,10 @@ public abstract class SunToolkit extends Toolkit ...@@ -460,12 +460,10 @@ public abstract class SunToolkit extends Toolkit
* via targetToAppContext() above. * via targetToAppContext() above.
*/ */
public static void insertTargetMapping(Object target, AppContext appContext) { public static void insertTargetMapping(Object target, AppContext appContext) {
if (!GraphicsEnvironment.isHeadless()) { if (!setAppContext(target, appContext)) {
if (!setAppContext(target, appContext)) { // Target is not a Component/MenuComponent, use the private Map
// Target is not a Component/MenuComponent, use the private Map // instead.
// instead. appContextMap.put(target, appContext);
appContextMap.put(target, appContext);
}
} }
} }
......
...@@ -656,8 +656,15 @@ abstract class Handshaker { ...@@ -656,8 +656,15 @@ abstract class Handshaker {
*/ */
ProtocolList getActiveProtocols() { ProtocolList getActiveProtocols() {
if (activeProtocols == null) { if (activeProtocols == null) {
boolean enabledSSL20Hello = false;
ArrayList<ProtocolVersion> protocols = new ArrayList<>(4); ArrayList<ProtocolVersion> protocols = new ArrayList<>(4);
for (ProtocolVersion protocol : enabledProtocols.collection()) { for (ProtocolVersion protocol : enabledProtocols.collection()) {
// Need not to check the SSL20Hello protocol.
if (protocol.v == ProtocolVersion.SSL20Hello.v) {
enabledSSL20Hello = true;
continue;
}
boolean found = false; boolean found = false;
for (CipherSuite suite : enabledCipherSuites.collection()) { for (CipherSuite suite : enabledCipherSuites.collection()) {
if (suite.isAvailable() && suite.obsoleted > protocol.v && if (suite.isAvailable() && suite.obsoleted > protocol.v &&
...@@ -684,6 +691,11 @@ abstract class Handshaker { ...@@ -684,6 +691,11 @@ abstract class Handshaker {
"No available cipher suite for " + protocol); "No available cipher suite for " + protocol);
} }
} }
if (!protocols.isEmpty() && enabledSSL20Hello) {
protocols.add(ProtocolVersion.SSL20Hello);
}
activeProtocols = new ProtocolList(protocols); activeProtocols = new ProtocolList(protocols);
} }
......
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
...@@ -31,12 +31,14 @@ public class XRSolidSrcPict { ...@@ -31,12 +31,14 @@ public class XRSolidSrcPict {
XRSurfaceData srcPict; XRSurfaceData srcPict;
XRColor xrCol; XRColor xrCol;
int curPixVal = -1; int curPixVal;
public XRSolidSrcPict(XRBackend con, int parentXid) { public XRSolidSrcPict(XRBackend con, int parentXid) {
this.con = con; this.con = con;
xrCol = new XRColor(); xrCol = new XRColor();
curPixVal = 0xFF000000;
int solidPixmap = con.createPixmap(parentXid, 32, 1, 1); int solidPixmap = con.createPixmap(parentXid, 32, 1, 1);
int solidSrcPictXID = con.createPicture(solidPixmap, XRUtils.PictStandardARGB32); int solidSrcPictXID = con.createPicture(solidPixmap, XRUtils.PictStandardARGB32);
con.setPictureRepeat(solidSrcPictXID, XRUtils.RepeatNormal); con.setPictureRepeat(solidSrcPictXID, XRUtils.RepeatNormal);
......
/* /*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,100 +25,10 @@ ...@@ -25,100 +25,10 @@
package sun.util.locale.provider; package sun.util.locale.provider;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.spi.DateFormatProvider;
import java.util.Locale;
/** /**
* LocaleProviderAdapter implementation for the Unix locale data * LocaleProviderAdapter implementation for the Unix locale data
* *
* @author Naoto Sato * @author Naoto Sato
*/ */
public class HostLocaleProviderAdapterImpl { public class HostLocaleProviderAdapterImpl {
static Locale[] supported = {Locale.getDefault(Locale.Category.FORMAT)};
public static DateFormatProvider getDateFormatProvider() {
return new DateFormatProvider() {
String posixPattern;
@Override
public Locale[] getAvailableLocales() {
// not implemented yet
return new Locale[0];
}
@Override
public DateFormat getDateInstance(int style, Locale locale) {
posixPattern = getPattern(style, -1, locale.toLanguageTag());
return new SimpleDateFormat(convertPosixToJava(posixPattern), locale);
}
@Override
public DateFormat getTimeInstance(int style, Locale locale) {
posixPattern = getPattern(-1, style, locale.toLanguageTag());
return new SimpleDateFormat(convertPosixToJava(posixPattern), locale);
} }
@Override
public DateFormat getDateTimeInstance(int dateStyle,
int timeStyle, Locale locale) {
posixPattern = getPattern(dateStyle, timeStyle, locale.toLanguageTag());
return new SimpleDateFormat(convertPosixToJava(posixPattern), locale);
}
};
}
private static String convertPosixToJava(String posixPattern) {
StringBuilder sb = new StringBuilder();
boolean conversion = false;
for (int index = 0; index < posixPattern.length(); index++) {
char c = posixPattern.charAt(index);
if (conversion) {
switch (c) {
case 'a':
sb.append("EEE");
break;
case 'b':
sb.append("MMM");
break;
case 'e':
sb.append("dd");
break;
case 'H':
sb.append("kk");
break;
case 'M':
sb.append("mm");
break;
case 'S':
sb.append("ss");
break;
case 'Y':
sb.append("yyyy");
break;
case 'm':
sb.append("MM");
break;
case 'd':
sb.append("dd");
break;
case 'r':
sb.append("hh:mm:ss aa");
break;
case 'Z':
sb.append("zzz");
break;
}
conversion = false;
} else {
if (c == '%') {
conversion = true;
} else {
sb.append(c);
}
}
}
return sb.toString();
}
private static native String getPattern(int dateStyle, int timeStyle, String langtag);
}
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
#define _WIN32_WINNT 0x0601 #define _WIN32_WINNT 0x0601
#endif #endif
#include "jni.h"
#include "jni_util.h"
#include <windows.h> #include <windows.h>
#include <shlobj.h> #include <shlobj.h>
#include <objidl.h> #include <objidl.h>
...@@ -51,7 +54,7 @@ ...@@ -51,7 +54,7 @@
#endif #endif
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
static void SetupI18nProps(LCID lcid, char** language, char** script, char** country, static boolean SetupI18nProps(LCID lcid, char** language, char** script, char** country,
char** variant, char** encoding); char** variant, char** encoding);
#define PROPSIZE 9 // eight-letter + null terminator #define PROPSIZE 9 // eight-letter + null terminator
...@@ -60,8 +63,11 @@ static void SetupI18nProps(LCID lcid, char** language, char** script, char** cou ...@@ -60,8 +63,11 @@ static void SetupI18nProps(LCID lcid, char** language, char** script, char** cou
static char * static char *
getEncodingInternal(LCID lcid) getEncodingInternal(LCID lcid)
{ {
char * ret = malloc(16);
int codepage; int codepage;
char * ret = malloc(16);
if (ret == NULL) {
return NULL;
}
if (GetLocaleInfo(lcid, if (GetLocaleInfo(lcid,
LOCALE_IDEFAULTANSICODEPAGE, LOCALE_IDEFAULTANSICODEPAGE,
...@@ -132,7 +138,11 @@ getEncodingInternal(LCID lcid) ...@@ -132,7 +138,11 @@ getEncodingInternal(LCID lcid)
static char* getConsoleEncoding() static char* getConsoleEncoding()
{ {
char* buf = malloc(16); char* buf = malloc(16);
int cp = GetConsoleCP(); int cp;
if (buf == NULL) {
return NULL;
}
cp = GetConsoleCP();
if (cp >= 874 && cp <= 950) if (cp >= 874 && cp <= 950)
sprintf(buf, "ms%d", cp); sprintf(buf, "ms%d", cp);
else else
...@@ -152,11 +162,16 @@ DllExport const char * ...@@ -152,11 +162,16 @@ DllExport const char *
getJavaIDFromLangID(LANGID langID) getJavaIDFromLangID(LANGID langID)
{ {
char * elems[5]; // lang, script, ctry, variant, encoding char * elems[5]; // lang, script, ctry, variant, encoding
char * ret = malloc(SNAMESIZE); char * ret;
int index; int index;
SetupI18nProps(MAKELCID(langID, SORT_DEFAULT), ret = malloc(SNAMESIZE);
&(elems[0]), &(elems[1]), &(elems[2]), &(elems[3]), &(elems[4])); if (ret == NULL) {
return NULL;
}
if (SetupI18nProps(MAKELCID(langID, SORT_DEFAULT),
&(elems[0]), &(elems[1]), &(elems[2]), &(elems[3]), &(elems[4]))) {
// there always is the "language" tag // there always is the "language" tag
strcpy(ret, elems[0]); strcpy(ret, elems[0]);
...@@ -172,6 +187,9 @@ getJavaIDFromLangID(LANGID langID) ...@@ -172,6 +187,9 @@ getJavaIDFromLangID(LANGID langID)
for (index = 0; index < 5; index++) { for (index = 0; index < 5; index++) {
free(elems[index]); free(elems[index]);
} }
} else {
ret = NULL;
}
return ret; return ret;
} }
...@@ -259,12 +277,15 @@ cpu_isalist(void) ...@@ -259,12 +277,15 @@ cpu_isalist(void)
return NULL; return NULL;
} }
static void static boolean
SetupI18nProps(LCID lcid, char** language, char** script, char** country, SetupI18nProps(LCID lcid, char** language, char** script, char** country,
char** variant, char** encoding) { char** variant, char** encoding) {
/* script */ /* script */
char tmp[SNAMESIZE]; char tmp[SNAMESIZE];
*script = malloc(PROPSIZE); *script = malloc(PROPSIZE);
if (*script == NULL) {
return FALSE;
}
if (GetLocaleInfo(lcid, if (GetLocaleInfo(lcid,
LOCALE_SNAME, tmp, SNAMESIZE) == 0 || LOCALE_SNAME, tmp, SNAMESIZE) == 0 ||
sscanf(tmp, "%*[a-z\\-]%1[A-Z]%[a-z]", *script, &((*script)[1])) == 0 || sscanf(tmp, "%*[a-z\\-]%1[A-Z]%[a-z]", *script, &((*script)[1])) == 0 ||
...@@ -274,6 +295,9 @@ SetupI18nProps(LCID lcid, char** language, char** script, char** country, ...@@ -274,6 +295,9 @@ SetupI18nProps(LCID lcid, char** language, char** script, char** country,
/* country */ /* country */
*country = malloc(PROPSIZE); *country = malloc(PROPSIZE);
if (*country == NULL) {
return FALSE;
}
if (GetLocaleInfo(lcid, if (GetLocaleInfo(lcid,
LOCALE_SISO3166CTRYNAME, *country, PROPSIZE) == 0 && LOCALE_SISO3166CTRYNAME, *country, PROPSIZE) == 0 &&
GetLocaleInfo(lcid, GetLocaleInfo(lcid,
...@@ -283,6 +307,9 @@ SetupI18nProps(LCID lcid, char** language, char** script, char** country, ...@@ -283,6 +307,9 @@ SetupI18nProps(LCID lcid, char** language, char** script, char** country,
/* language */ /* language */
*language = malloc(PROPSIZE); *language = malloc(PROPSIZE);
if (*language == NULL) {
return FALSE;
}
if (GetLocaleInfo(lcid, if (GetLocaleInfo(lcid,
LOCALE_SISO639LANGNAME, *language, PROPSIZE) == 0 && LOCALE_SISO639LANGNAME, *language, PROPSIZE) == 0 &&
GetLocaleInfo(lcid, GetLocaleInfo(lcid,
...@@ -294,6 +321,9 @@ SetupI18nProps(LCID lcid, char** language, char** script, char** country, ...@@ -294,6 +321,9 @@ SetupI18nProps(LCID lcid, char** language, char** script, char** country,
/* variant */ /* variant */
*variant = malloc(PROPSIZE); *variant = malloc(PROPSIZE);
if (*variant == NULL) {
return FALSE;
}
(*variant)[0] = '\0'; (*variant)[0] = '\0';
/* handling for Norwegian */ /* handling for Norwegian */
...@@ -308,6 +338,10 @@ SetupI18nProps(LCID lcid, char** language, char** script, char** country, ...@@ -308,6 +338,10 @@ SetupI18nProps(LCID lcid, char** language, char** script, char** country,
/* encoding */ /* encoding */
*encoding = getEncodingInternal(lcid); *encoding = getEncodingInternal(lcid);
if (*encoding == NULL) {
return FALSE;
}
return TRUE;
} }
java_props_t * java_props_t *
......
...@@ -1014,9 +1014,11 @@ JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0 ...@@ -1014,9 +1014,11 @@ JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0
case MIB_IF_TYPE_FDDI: case MIB_IF_TYPE_FDDI:
case IF_TYPE_IEEE80211: case IF_TYPE_IEEE80211:
len = ifRowP->dwPhysAddrLen; len = ifRowP->dwPhysAddrLen;
ret = (*env)->NewByteArray(env, len); if (len > 0) {
if (!IS_NULL(ret)) { ret = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) ifRowP->bPhysAddr); if (!IS_NULL(ret)) {
(*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) ifRowP->bPhysAddr);
}
} }
break; break;
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
#include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h" #include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h"
#include "jni_util.h"
#include <windows.h> #include <windows.h>
#include <gdefs.h> #include <gdefs.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -197,8 +198,13 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -197,8 +198,13 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
} }
localeString = (char *)getJavaIDFromLangID(langid); localeString = (char *)getJavaIDFromLangID(langid);
if (localeString != NULL) {
ret = (*env)->NewStringUTF(env, localeString); ret = (*env)->NewStringUTF(env, localeString);
free(localeString); free(localeString);
} else {
JNU_ThrowOutOfMemoryError(env, "memory allocation error");
ret = NULL;
}
return ret; return ret;
} }
...@@ -211,6 +217,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -211,6 +217,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
(JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) { (JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) {
WCHAR pattern[BUFLEN]; WCHAR pattern[BUFLEN];
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
CHECK_NULL_RETURN(langtag, NULL);
pattern[0] = L'\0'; pattern[0] = L'\0';
...@@ -228,7 +235,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -228,7 +235,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
return (*env)->NewString(env, pattern, wcslen(pattern)); return (*env)->NewString(env, pattern, (jsize)wcslen(pattern));
} }
/* /*
...@@ -238,8 +245,11 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -238,8 +245,11 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
*/ */
JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarID JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarID
(JNIEnv *env, jclass cls, jstring jlangtag) { (JNIEnv *env, jclass cls, jstring jlangtag) {
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag;
jint ret = getCalendarID(langtag); jint ret;
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
CHECK_NULL_RETURN(langtag, 0);
ret = getCalendarID(langtag);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
return ret; return ret;
} }
...@@ -252,18 +262,30 @@ JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterIm ...@@ -252,18 +262,30 @@ JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterIm
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getAmPmStrings JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getAmPmStrings
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) { (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag;
jstring tmp_string;
// AM // AM
int got = getLocaleInfoWrapper(langtag, LOCALE_S1159, buf, BUFLEN); int got;
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
CHECK_NULL_RETURN(langtag, NULL);
got = getLocaleInfoWrapper(langtag, LOCALE_S1159, buf, BUFLEN);
if (got) { if (got) {
(*env)->SetObjectArrayElement(env, ampms, 0, (*env)->NewString(env, buf, wcslen(buf))); tmp_string = (*env)->NewString(env, buf, (jsize)wcslen(buf));
if (tmp_string != NULL) {
(*env)->SetObjectArrayElement(env, ampms, 0, tmp_string);
}
} }
if (!(*env)->ExceptionCheck(env)){
// PM // PM
got = getLocaleInfoWrapper(langtag, LOCALE_S2359, buf, BUFLEN); got = getLocaleInfoWrapper(langtag, LOCALE_S2359, buf, BUFLEN);
if (got) { if (got) {
(*env)->SetObjectArrayElement(env, ampms, 1, (*env)->NewString(env, buf, wcslen(buf))); tmp_string = (*env)->NewString(env, buf, (jsize)wcslen(buf));
if (tmp_string != NULL) {
(*env)->SetObjectArrayElement(env, ampms, 1, tmp_string);
}
}
} }
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
...@@ -280,12 +302,17 @@ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderA ...@@ -280,12 +302,17 @@ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderA
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray eras) { (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray eras) {
WCHAR ad[BUFLEN]; WCHAR ad[BUFLEN];
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
jstring tmp_string;
CHECK_NULL_RETURN(langtag, eras);
getCalendarInfoWrapper(langtag, getCalendarID(langtag), NULL, getCalendarInfoWrapper(langtag, getCalendarID(langtag), NULL,
CAL_SERASTRING, ad, BUFLEN, NULL); CAL_SERASTRING, ad, BUFLEN, NULL);
// Windows does not provide B.C. era. // Windows does not provide B.C. era.
(*env)->SetObjectArrayElement(env, eras, 1, (*env)->NewString(env, ad, wcslen(ad))); tmp_string = (*env)->NewString(env, ad, (jsize)wcslen(ad));
if (tmp_string != NULL) {
(*env)->SetObjectArrayElement(env, eras, 1, tmp_string);
}
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
...@@ -347,13 +374,17 @@ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderA ...@@ -347,13 +374,17 @@ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderA
*/ */
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNumberPattern JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNumberPattern
(JNIEnv *env, jclass cls, jint numberStyle, jstring jlangtag) { (JNIEnv *env, jclass cls, jint numberStyle, jstring jlangtag) {
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag;
jstring ret; jstring ret;
WCHAR * pattern;
WCHAR * pattern = getNumberPattern(langtag, numberStyle); langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
CHECK_NULL_RETURN(langtag, NULL);
pattern = getNumberPattern(langtag, numberStyle);
CHECK_NULL_RETURN(pattern, NULL);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
ret = (*env)->NewString(env, pattern, wcslen(pattern)); ret = (*env)->NewString(env, pattern, (jsize)wcslen(pattern));
free(pattern); free(pattern);
return ret; return ret;
...@@ -367,8 +398,10 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -367,8 +398,10 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_isNativeDigit JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_isNativeDigit
(JNIEnv *env, jclass cls, jstring jlangtag) { (JNIEnv *env, jclass cls, jstring jlangtag) {
DWORD num; DWORD num;
int got;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int got = getLocaleInfoWrapper(langtag, CHECK_NULL_RETURN(langtag, JNI_FALSE);
got = getLocaleInfoWrapper(langtag,
LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER, LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER,
(LPWSTR)&num, sizeof(num)); (LPWSTR)&num, sizeof(num));
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
...@@ -384,12 +417,14 @@ JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapt ...@@ -384,12 +417,14 @@ JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapt
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCurrencySymbol JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCurrencySymbol
(JNIEnv *env, jclass cls, jstring jlangtag, jstring currencySymbol) { (JNIEnv *env, jclass cls, jstring jlangtag, jstring currencySymbol) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
int got;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int got = getLocaleInfoWrapper(langtag, LOCALE_SCURRENCY, buf, BUFLEN); CHECK_NULL_RETURN(langtag, currencySymbol);
got = getLocaleInfoWrapper(langtag, LOCALE_SCURRENCY, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
return (*env)->NewString(env, buf, wcslen(buf)); return (*env)->NewString(env, buf, (jsize)wcslen(buf));
} else { } else {
return currencySymbol; return currencySymbol;
} }
...@@ -403,8 +438,10 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -403,8 +438,10 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDecimalSeparator JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDecimalSeparator
(JNIEnv *env, jclass cls, jstring jlangtag, jchar decimalSeparator) { (JNIEnv *env, jclass cls, jstring jlangtag, jchar decimalSeparator) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
int got;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int got = getLocaleInfoWrapper(langtag, LOCALE_SDECIMAL, buf, BUFLEN); CHECK_NULL_RETURN(langtag, decimalSeparator);
got = getLocaleInfoWrapper(langtag, LOCALE_SDECIMAL, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
...@@ -422,8 +459,10 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI ...@@ -422,8 +459,10 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getGroupingSeparator JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getGroupingSeparator
(JNIEnv *env, jclass cls, jstring jlangtag, jchar groupingSeparator) { (JNIEnv *env, jclass cls, jstring jlangtag, jchar groupingSeparator) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
int got;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int got = getLocaleInfoWrapper(langtag, LOCALE_STHOUSAND, buf, BUFLEN); CHECK_NULL_RETURN(langtag, groupingSeparator);
got = getLocaleInfoWrapper(langtag, LOCALE_STHOUSAND, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
...@@ -441,12 +480,14 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI ...@@ -441,12 +480,14 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInfinity JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInfinity
(JNIEnv *env, jclass cls, jstring jlangtag, jstring infinity) { (JNIEnv *env, jclass cls, jstring jlangtag, jstring infinity) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
int got;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int got = getLocaleInfoWrapper(langtag, LOCALE_SPOSINFINITY, buf, BUFLEN); CHECK_NULL_RETURN(langtag, infinity);
got = getLocaleInfoWrapper(langtag, LOCALE_SPOSINFINITY, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
return (*env)->NewString(env, buf, wcslen(buf)); return (*env)->NewString(env, buf, (jsize)wcslen(buf));
} else { } else {
return infinity; return infinity;
} }
...@@ -460,12 +501,14 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -460,12 +501,14 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInternationalCurrencySymbol JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInternationalCurrencySymbol
(JNIEnv *env, jclass cls, jstring jlangtag, jstring internationalCurrencySymbol) { (JNIEnv *env, jclass cls, jstring jlangtag, jstring internationalCurrencySymbol) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
int got;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int got = getLocaleInfoWrapper(langtag, LOCALE_SINTLSYMBOL, buf, BUFLEN); CHECK_NULL_RETURN(langtag, internationalCurrencySymbol);
got = getLocaleInfoWrapper(langtag, LOCALE_SINTLSYMBOL, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
return (*env)->NewString(env, buf, wcslen(buf)); return (*env)->NewString(env, buf, (jsize)wcslen(buf));
} else { } else {
return internationalCurrencySymbol; return internationalCurrencySymbol;
} }
...@@ -479,8 +522,10 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -479,8 +522,10 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMinusSign JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMinusSign
(JNIEnv *env, jclass cls, jstring jlangtag, jchar minusSign) { (JNIEnv *env, jclass cls, jstring jlangtag, jchar minusSign) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
int got;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int got = getLocaleInfoWrapper(langtag, LOCALE_SNEGATIVESIGN, buf, BUFLEN); CHECK_NULL_RETURN(langtag, minusSign);
got = getLocaleInfoWrapper(langtag, LOCALE_SNEGATIVESIGN, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
...@@ -498,8 +543,10 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI ...@@ -498,8 +543,10 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonetaryDecimalSeparator JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonetaryDecimalSeparator
(JNIEnv *env, jclass cls, jstring jlangtag, jchar monetaryDecimalSeparator) { (JNIEnv *env, jclass cls, jstring jlangtag, jchar monetaryDecimalSeparator) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
int got;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int got = getLocaleInfoWrapper(langtag, LOCALE_SMONDECIMALSEP, buf, BUFLEN); CHECK_NULL_RETURN(langtag, monetaryDecimalSeparator);
got = getLocaleInfoWrapper(langtag, LOCALE_SMONDECIMALSEP, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
...@@ -517,12 +564,14 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI ...@@ -517,12 +564,14 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNaN JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNaN
(JNIEnv *env, jclass cls, jstring jlangtag, jstring nan) { (JNIEnv *env, jclass cls, jstring jlangtag, jstring nan) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
int got;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int got = getLocaleInfoWrapper(langtag, LOCALE_SNAN, buf, BUFLEN); CHECK_NULL_RETURN(langtag, nan);
got = getLocaleInfoWrapper(langtag, LOCALE_SNAN, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
return (*env)->NewString(env, buf, wcslen(buf)); return (*env)->NewString(env, buf, (jsize)wcslen(buf));
} else { } else {
return nan; return nan;
} }
...@@ -536,8 +585,10 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -536,8 +585,10 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPercent JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPercent
(JNIEnv *env, jclass cls, jstring jlangtag, jchar percent) { (JNIEnv *env, jclass cls, jstring jlangtag, jchar percent) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
int got;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int got = getLocaleInfoWrapper(langtag, LOCALE_SPERCENT, buf, BUFLEN); CHECK_NULL_RETURN(langtag, percent);
got = getLocaleInfoWrapper(langtag, LOCALE_SPERCENT, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
...@@ -555,8 +606,12 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI ...@@ -555,8 +606,12 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPerMill JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPerMill
(JNIEnv *env, jclass cls, jstring jlangtag, jchar perMill) { (JNIEnv *env, jclass cls, jstring jlangtag, jchar perMill) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag;
int got = getLocaleInfoWrapper(langtag, LOCALE_SPERMILLE, buf, BUFLEN); int got;
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
CHECK_NULL_RETURN(langtag, perMill);
got = getLocaleInfoWrapper(langtag, LOCALE_SPERMILLE, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
...@@ -574,8 +629,12 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI ...@@ -574,8 +629,12 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getZeroDigit JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getZeroDigit
(JNIEnv *env, jclass cls, jstring jlangtag, jchar zeroDigit) { (JNIEnv *env, jclass cls, jstring jlangtag, jchar zeroDigit) {
WCHAR buf[BUFLEN]; WCHAR buf[BUFLEN];
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag;
int got = getLocaleInfoWrapper(langtag, LOCALE_SNATIVEDIGITS, buf, BUFLEN); int got;
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
CHECK_NULL_RETURN(langtag, zeroDigit);
got = getLocaleInfoWrapper(langtag, LOCALE_SNATIVEDIGITS, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jlangtag, langtag); (*env)->ReleaseStringChars(env, jlangtag, langtag);
if (got) { if (got) {
...@@ -593,9 +652,11 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI ...@@ -593,9 +652,11 @@ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterI
JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDataValue JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDataValue
(JNIEnv *env, jclass cls, jstring jlangtag, jint type) { (JNIEnv *env, jclass cls, jstring jlangtag, jint type) {
DWORD num; DWORD num;
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag;
int got = 0; int got = 0;
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
CHECK_NULL_RETURN(langtag, -1);
switch (type) { switch (type) {
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTDAYOFWEEK: case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTDAYOFWEEK:
got = getLocaleInfoWrapper(langtag, got = getLocaleInfoWrapper(langtag,
...@@ -648,11 +709,12 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte ...@@ -648,11 +709,12 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte
} }
pjChar = (*env)->GetStringChars(env, jStr, JNI_FALSE); pjChar = (*env)->GetStringChars(env, jStr, JNI_FALSE);
CHECK_NULL_RETURN(pjChar, NULL);
got = getLocaleInfoWrapper(pjChar, lcType, buf, BUFLEN); got = getLocaleInfoWrapper(pjChar, lcType, buf, BUFLEN);
(*env)->ReleaseStringChars(env, jStr, pjChar); (*env)->ReleaseStringChars(env, jStr, pjChar);
if (got) { if (got) {
return (*env)->NewString(env, buf, wcslen(buf)); return (*env)->NewString(env, buf, (jsize)wcslen(buf));
} else { } else {
return NULL; return NULL;
} }
...@@ -706,15 +768,21 @@ jint getCalendarID(const jchar *langtag) { ...@@ -706,15 +768,21 @@ jint getCalendarID(const jchar *langtag) {
void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jobjectArray jarray, CALTYPE* pCalTypes, int offset, int length) { void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jobjectArray jarray, CALTYPE* pCalTypes, int offset, int length) {
WCHAR name[BUFLEN]; WCHAR name[BUFLEN];
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
int calid = getCalendarID(langtag); int calid;
jstring tmp_string;
CHECK_NULL(langtag);
calid = getCalendarID(langtag);
if (calid != -1) { if (calid != -1) {
int i; int i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
getCalendarInfoWrapper(langtag, calid, NULL, getCalendarInfoWrapper(langtag, calid, NULL,
pCalTypes[i], name, BUFLEN, NULL); pCalTypes[i], name, BUFLEN, NULL);
(*env)->SetObjectArrayElement(env, jarray, i + offset, tmp_string = (*env)->NewString(env, name, (jsize)wcslen(name));
(*env)->NewString(env, name, wcslen(name))); if (tmp_string != NULL) {
(*env)->SetObjectArrayElement(env, jarray, i + offset, tmp_string);
}
} }
} }
......
...@@ -124,15 +124,27 @@ jdk_security2 = \ ...@@ -124,15 +124,27 @@ jdk_security2 = \
jdk_security3 = \ jdk_security3 = \
javax/security \ javax/security \
-javax/security/auth/kerberos \
com/sun/security \ com/sun/security \
-com/sun/security/jgss \
com/sun/org/apache/xml/internal/security \ com/sun/org/apache/xml/internal/security \
sun/security \ sun/security \
-sun/security/krb5 \
-sun/security/jgss \
javax/net \
lib/security lib/security
jdk_security4 = \
com/sun/security/jgss \
javax/security/auth/kerberos \
sun/security/krb5 \
sun/security/jgss
jdk_security = \ jdk_security = \
:jdk_security1 \ :jdk_security1 \
:jdk_security2 \ :jdk_security2 \
:jdk_security3 :jdk_security3 \
:jdk_security4
jdk_text = \ jdk_text = \
java/text \ java/text \
......
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
/**
* @test
* @bug 8056009
* @summary tests whether Graphics.setColor-calls with Color.white are ignored directly
* after pipeline initialization for a certain set of operations.
* @author ceisserer
*/
public class WhiteTextColorTest extends Frame {
public static volatile boolean success = false;
public WhiteTextColorTest() {
Image dstImg = getGraphicsConfiguration()
.createCompatibleVolatileImage(30, 20);
Graphics g = dstImg.getGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, dstImg.getWidth(null), dstImg.getHeight(null));
g.setColor(Color.WHITE);
g.drawString("Test", 0, 15);
BufferedImage readBackImg = new BufferedImage(dstImg.getWidth(null),
dstImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
readBackImg.getGraphics().drawImage(dstImg, 0, 0, null);
for (int x = 0; x < readBackImg.getWidth(); x++) {
for (int y = 0; y < readBackImg.getHeight(); y++) {
int pixel = readBackImg.getRGB(x, y);
// In case a single white pixel is found, the
// setColor(Color.WHITE)
// call before was not ignored and the bug is not present
if (pixel == 0xFFFFFFFF) {
return;
}
}
}
throw new RuntimeException("Test Failed");
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new WhiteTextColorTest();
}
});
}
}
/* /*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014 Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this * published by the Free Software Foundation.
* 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 * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
...@@ -23,55 +21,45 @@ ...@@ -23,55 +21,45 @@
* questions. * questions.
*/ */
#include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h"
#include <gdefs.h>
#include <string.h>
#include <langinfo.h>
#include <locale.h>
#define BUFLEN 64
/* /*
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl * @test
* Method: getPattern * @ignore This test has huge memory requirements
* Signature: (IILjava/lang/String;)Ljava/lang/String; * @run main/timeout=1800/othervm -Xmx8g MaxCapacity
* @bug 8055949
* @summary Check that we can write (almost) Integer.MAX_VALUE bytes
* to a ByteArrayOutputStream.
* @author Martin Buchholz
*/ */
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPattern import java.io.ByteArrayOutputStream;
(JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) {
// TEMPORARY! public class MaxCapacity {
char locale[BUFLEN]; public static void main(String[] args) {
char * pch; long maxHeap = Runtime.getRuntime().maxMemory();
char * old; if (maxHeap < 3L * Integer.MAX_VALUE) {
char * ret; System.out.printf("Skipping test; max memory %sM too small%n",
const char *langtag = (*env)->GetStringUTFChars(env, jlangtag, JNI_FALSE); maxHeap/(1024*1024));
return;
strcpy(locale, langtag); }
pch = strchr(locale, '-'); ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (pch != NULL) { for (long n = 0; ; n++) {
*pch = '_'; try {
} baos.write((byte)'x');
pch = strchr(locale, '-'); } catch (Throwable t) {
if (pch != NULL) { // check data integrity while we're here
*pch = '\0'; byte[] bytes = baos.toByteArray();
} if (bytes.length != n)
strcat(locale, ".UTF-8"); throw new AssertionError("wrong length");
old = setlocale(LC_TIME, ""); if (bytes[0] != 'x' ||
setlocale(LC_TIME, locale); bytes[bytes.length - 1] != 'x')
throw new AssertionError("wrong contents");
if (dateStyle != (-1) && timeStyle != (-1)) { long gap = Integer.MAX_VALUE - n;
ret = nl_langinfo(D_T_FMT); System.out.printf("gap=%dM %d%n", gap/(1024*1024), gap);
} else if (dateStyle != (-1)) { if (gap > 1024)
ret = nl_langinfo(D_FMT); throw t;
} else if (timeStyle != (-1)) { // t.printStackTrace();
ret = nl_langinfo(T_FMT); break;
} else { }
ret = "yyyy/MM/dd"; }
} }
setlocale(LC_TIME, old);
(*env)->ReleaseStringUTFChars(env, jlangtag, langtag);
return (*env)->NewStringUTF(env, ret);
} }
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8023651 8044629 * @bug 8023651
* @summary Test that the receiver annotations and the return annotations of * @summary Test that the receiver annotations and the return annotations of
* constructors behave correctly. * constructors behave correctly.
* @run testng ConstructorReceiverTest * @run testng ConstructorReceiverTest
...@@ -38,16 +38,11 @@ import org.testng.annotations.Test; ...@@ -38,16 +38,11 @@ import org.testng.annotations.Test;
import static org.testng.Assert.*; import static org.testng.Assert.*;
public class ConstructorReceiverTest { public class ConstructorReceiverTest {
public static final Integer EMPTY_ANNOTATED_TYPE = Integer.valueOf(-1);
// Format is { // Format is {
// { Class to get ctor for, // { Class to get ctor for,
// ctor param class, // ctor param class,
// value of anno of return type, // value of anno of return type,
// value of anno for receiver, // value of anno for receiver or null if there should be no receiver anno
// or null if there should be no receiver,
// or EMPTY_ANNOTATED_TYPE of there should be a receiver but
// no annotation
// }, // },
// ... // ...
// } // }
...@@ -56,15 +51,13 @@ public class ConstructorReceiverTest { ...@@ -56,15 +51,13 @@ public class ConstructorReceiverTest {
{ ConstructorReceiverTest.Middle.class, ConstructorReceiverTest.class, Integer.valueOf(10), Integer.valueOf(15) }, { ConstructorReceiverTest.Middle.class, ConstructorReceiverTest.class, Integer.valueOf(10), Integer.valueOf(15) },
{ ConstructorReceiverTest.Middle.Inner.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(100), Integer.valueOf(150) }, { ConstructorReceiverTest.Middle.Inner.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(100), Integer.valueOf(150) },
{ ConstructorReceiverTest.Middle.Inner.Innermost.class, ConstructorReceiverTest.Middle.Inner.class, Integer.valueOf(1000), Integer.valueOf(1500) }, { ConstructorReceiverTest.Middle.Inner.Innermost.class, ConstructorReceiverTest.Middle.Inner.class, Integer.valueOf(1000), Integer.valueOf(1500) },
{ ConstructorReceiverTest.Middle.InnerNoReceiver.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(300), EMPTY_ANNOTATED_TYPE }, { ConstructorReceiverTest.Middle.InnerNoReceiver.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(300), null },
{ ConstructorReceiverTest.Nested.class, null, Integer.valueOf(20), null }, { ConstructorReceiverTest.Nested.class, null, Integer.valueOf(20), null },
{ ConstructorReceiverTest.Nested.NestedMiddle.class, ConstructorReceiverTest.Nested.class, Integer.valueOf(200), Integer.valueOf(250)}, { ConstructorReceiverTest.Nested.NestedMiddle.class, ConstructorReceiverTest.Nested.class, Integer.valueOf(200), Integer.valueOf(250)},
{ ConstructorReceiverTest.Nested.NestedMiddle.NestedInner.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(2000), Integer.valueOf(2500)}, { ConstructorReceiverTest.Nested.NestedMiddle.NestedInner.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(2000), Integer.valueOf(2500)},
{ ConstructorReceiverTest.Nested.NestedMiddle.NestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(4000), EMPTY_ANNOTATED_TYPE}, { ConstructorReceiverTest.Nested.NestedMiddle.NestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(4000), null},
{ ConstructorReceiverTest.Nested.NestedMiddle.SecondNestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(5000), EMPTY_ANNOTATED_TYPE},
}; };
@DataProvider @DataProvider
public Object[][] data() { return TESTS; } public Object[][] data() { return TESTS; }
...@@ -78,27 +71,14 @@ public class ConstructorReceiverTest { ...@@ -78,27 +71,14 @@ public class ConstructorReceiverTest {
c = toTest.getDeclaredConstructor(ctorParamType); c = toTest.getDeclaredConstructor(ctorParamType);
AnnotatedType annotatedReceiverType = c.getAnnotatedReceiverType(); AnnotatedType annotatedReceiverType = c.getAnnotatedReceiverType();
// Some Constructors doesn't conceptually have a receiver, they should return null
if (receiverVal == null) {
assertNull(annotatedReceiverType, "getAnnotatedReciverType should return null for Constructor: " + c);
return;
}
// check that getType() matches the receiver
assertEquals(annotatedReceiverType.getType(),
ctorParamType,
"getType() doesn't match receiver type: " + ctorParamType);
Annotation[] receiverAnnotations = annotatedReceiverType.getAnnotations(); Annotation[] receiverAnnotations = annotatedReceiverType.getAnnotations();
// Some Constructors have no annotations on but in theory can have a receiver if (receiverVal == null) {
if (receiverVal.equals(EMPTY_ANNOTATED_TYPE)) { assertEquals(receiverAnnotations.length, 0, Arrays.asList(receiverAnnotations).toString() +
assertEquals(receiverAnnotations.length, 0, "expecting an empty annotated type for: " + c); " should be empty. Looking at 'length': ");
return; return;
} }
// The rest should have annotations
assertEquals(receiverAnnotations.length, 1, "expecting a 1 element array. Looking at 'length': "); assertEquals(receiverAnnotations.length, 1, "expecting a 1 element array. Looking at 'length': ");
assertEquals(((Annot)receiverAnnotations[0]).value(), receiverVal.intValue(), " wrong annotation found. Found " + assertEquals(((Annot)receiverAnnotations[0]).value(), receiverVal.intValue(), " wrong annotation found. Found " +
receiverAnnotations[0] + receiverAnnotations[0] +
...@@ -156,10 +136,6 @@ public class ConstructorReceiverTest { ...@@ -156,10 +136,6 @@ public class ConstructorReceiverTest {
class NestedInnerNoReceiver { class NestedInnerNoReceiver {
@Annot(4000) public NestedInnerNoReceiver() {} @Annot(4000) public NestedInnerNoReceiver() {}
} }
class SecondNestedInnerNoReceiver {
@Annot(5000) public SecondNestedInnerNoReceiver(NestedMiddle NestedMiddle.this) {}
}
} }
} }
......
/* /*
* Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,11 +23,10 @@ ...@@ -23,11 +23,10 @@
/* /*
* @test * @test
* @bug 8024915 8044629 * @bug 8024915
*/ */
import java.lang.reflect.AnnotatedType; import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Executable;
import java.util.Arrays; import java.util.Arrays;
public class GetAnnotatedReceiverType { public class GetAnnotatedReceiverType {
...@@ -43,115 +42,41 @@ public class GetAnnotatedReceiverType { ...@@ -43,115 +42,41 @@ public class GetAnnotatedReceiverType {
public Inner1(GetAnnotatedReceiverType GetAnnotatedReceiverType.this) {} public Inner1(GetAnnotatedReceiverType GetAnnotatedReceiverType.this) {}
} }
public static class Nested {
public Nested() {}
public class NestedInner {
public NestedInner() { }
public Class<?> getLocalClass () {
class NestedInnerLocal { public NestedInnerLocal() {} }
return NestedInnerLocal.class;
}
public Class<?> getAnonymousClass() {
return new Object() {}.getClass();
}
}
}
public class Inner2 {
public Inner2() { }
public class Inner3 {
public Inner3() { }
public Class<?> getLocalClass () {
class InnerLocal { public InnerLocal() {} }
return InnerLocal.class;
}
public Class<?> getAnonymousClass() {
return new Object() {}.getClass();
}
}
public Class<?> getLocalClass () {
class InnerLocal { public InnerLocal() {} }
return InnerLocal.class;
}
public Class<?> getAnonymousClass() {
return new Object() {}.getClass();
}
}
private static int failures = 0; private static int failures = 0;
private static int tests = 0; private static int tests = 0;
public static void main(String[] args) throws NoSuchMethodException { public static void main(String[] args) throws NoSuchMethodException {
checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method"), checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method").getAnnotatedReceiverType(),
"getAnnotatedReceiverType for \"method\" should return an empty AnnotatedType"); "getAnnotatedReceiverType for \"method\" should return an empty AnnotatedType");
checkEmptyAT(Inner0.class.getConstructor(GetAnnotatedReceiverType.class), checkEmptyAT(Inner0.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(),
"getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType"); "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType");
checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method0"), checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method0").getAnnotatedReceiverType(),
"getAnnotatedReceiverType for \"method0\" should return an empty AnnotatedType"); "getAnnotatedReceiverType for \"method0\" should return an empty AnnotatedType");
checkEmptyAT(Inner1.class.getConstructor(GetAnnotatedReceiverType.class), checkEmptyAT(Inner1.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(),
"getAnnotatedReceiverType for a ctor with a \"this\" should return an empty AnnotatedType"); "getAnnotatedReceiverType for a ctor with a \"this\" should return an empty AnnotatedType");
checkNull(GetAnnotatedReceiverType.class.getMethod("method4"), checkNull(GetAnnotatedReceiverType.class.getMethod("method4").getAnnotatedReceiverType(),
"getAnnotatedReceiverType() on a static method should return null"); "getAnnotatedReceiverType() on a static method should return null");
// More nested, inner, local and anonymous classes
Nested nested = new Nested();
Nested.NestedInner instance = nested.new NestedInner();
checkNull(nested.getClass().getConstructors()[0],
"getAnnotatedReceiverType() on a constructor for a static class should return null");
checkEmptyAT(instance.getClass().getConstructors()[0],
"getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType");
checkNull(instance.getLocalClass().getConstructors()[0],
"getAnnotatedReceiverType() on a constructor for a local class should return null");
checkNull(instance.getAnonymousClass().getDeclaredConstructors()[0],
"getAnnotatedReceiverType() on a constructor for an anonymous class should return null");
GetAnnotatedReceiverType outer = new GetAnnotatedReceiverType();
Inner2 instance2 = outer.new Inner2();
checkEmptyAT(instance2.getClass().getConstructors()[0],
"getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType");
checkNull(instance2.getLocalClass().getConstructors()[0],
"getAnnotatedReceiverType() on a constructor for a local class should return null");
checkNull(instance2.getAnonymousClass().getDeclaredConstructors()[0],
"getAnnotatedReceiverType() on a constructor for an anonymous class should return null");
Inner2.Inner3 instance3 = instance2.new Inner3();
checkEmptyAT(instance3.getClass().getConstructors()[0],
"getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType");
checkNull(instance3.getLocalClass().getConstructors()[0],
"getAnnotatedReceiverType() on a constructor for a local class should return null");
checkNull(instance3.getAnonymousClass().getDeclaredConstructors()[0],
"getAnnotatedReceiverType() on a constructor for an anonymous class should return null");
if (failures != 0) if (failures != 0)
throw new RuntimeException("Test failed, see log for details"); throw new RuntimeException("Test failed, see log for details");
else if (tests != 15) else if (tests != 5)
throw new RuntimeException("Not all cases ran, failing"); throw new RuntimeException("Not all cases ran, failing");
} }
private static void checkNull(Executable e, String msg) { private static void checkNull(Object o, String msg) {
AnnotatedType a = e.getAnnotatedReceiverType(); if (o != null) {
if (a != null) {
failures++; failures++;
System.err.println(msg + ": " + e); System.err.println(msg);
} }
tests++; tests++;
} }
private static void checkEmptyAT(Executable e, String msg) { private static void checkEmptyAT(AnnotatedType a, String msg) {
AnnotatedType a = e.getAnnotatedReceiverType();
if (a.getAnnotations().length != 0) { if (a.getAnnotations().length != 0) {
failures++; failures++;
System.err.print(msg + ": " + e); System.err.print(msg);
} }
tests++; tests++;
} }
......
...@@ -73,11 +73,13 @@ public class TestExecutableGetAnnotatedType { ...@@ -73,11 +73,13 @@ public class TestExecutableGetAnnotatedType {
testParameters(e.getParameters()); testParameters(e.getParameters());
} }
// should test constructors as well, see JDK-8044629
@Test(dataProvider = "genericMethodData") @Test(dataProvider = "genericMethodData")
public void testGenericReceiverType(Executable e) throws Exception { public void testGenericReceiverType(Executable e) throws Exception {
testReceiverType0(e); testReceiverType0(e);
} }
// should test constructors as well, see JDK-8044629
@Test(dataProvider = "methodData") @Test(dataProvider = "methodData")
public void testReceiverType(Executable e) throws Exception { public void testReceiverType(Executable e) throws Exception {
testReceiverType0(e); testReceiverType0(e);
......
...@@ -21,8 +21,12 @@ ...@@ -21,8 +21,12 @@
* questions. * questions.
*/ */
import java.io.File;
import java.io.FileWriter;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.Arrays;
import java.util.stream.Collectors;
import sun.management.ManagementFactoryHelper; import sun.management.ManagementFactoryHelper;
import com.sun.management.DiagnosticCommandMBean; import com.sun.management.DiagnosticCommandMBean;
...@@ -32,8 +36,8 @@ public class NMTHelper ...@@ -32,8 +36,8 @@ public class NMTHelper
executeDcmd("vmNativeMemory", "baseline"); executeDcmd("vmNativeMemory", "baseline");
} }
// Total: reserved=3484685KB +293KB, committed=266629KB +293KB // Total: reserved=3484685KB +293KB, committed=266629KB +293KB
private static Pattern totalLine = Pattern.compile("^Total: reserved=\\d+KB .*KB, committed=\\d+KB (.*)KB$"); private static Pattern totalLine = Pattern.compile("^Total: reserved=\\d+KB .*KB, committed=\\d+KB (.*)KB$");
public static long committedDiff() throws Exception { public static long committedDiff() throws Exception {
String res = (String) executeDcmd("vmNativeMemory", "detail.diff"); String res = (String) executeDcmd("vmNativeMemory", "detail.diff");
...@@ -53,14 +57,14 @@ public class NMTHelper ...@@ -53,14 +57,14 @@ public class NMTHelper
Object[] dcmdArgs = {args}; Object[] dcmdArgs = {args};
String[] signature = {String[].class.getName()}; String[] signature = {String[].class.getName()};
try { String cmdString = cmd + " " +
System.out.print("> " + cmd + " "); Arrays.stream(args).collect(Collectors.joining(" "));
for (String s : args) { File f = new File("dcmdoutput-" + cmd + "-" + System.currentTimeMillis() + ".txt");
System.out.print(s + " "); System.out.println("Output from Dcmd '" + cmdString + "' is being written to file " + f);
} try (FileWriter fw = new FileWriter(f)) {
System.out.println(":"); fw.write("> " + cmdString + ":");
String result = (String) dcmd.invoke(cmd, dcmdArgs, signature); String result = (String) dcmd.invoke(cmd, dcmdArgs, signature);
System.out.println(result); fw.write(result);
return result; return result;
} catch(Exception ex) { } catch(Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
# @author Daniel D. Daugherty # @author Daniel D. Daugherty
# #
# @run shell MakeJAR3.sh RedefineBigClassAgent 'Can-Redefine-Classes: true' # @run shell MakeJAR3.sh RedefineBigClassAgent 'Can-Redefine-Classes: true'
# @run build BigClass RedefineBigClassApp # @run build BigClass RedefineBigClassApp NMTHelper
# @run shell/timeout=600 RedefineBigClass.sh # @run shell/timeout=600 RedefineBigClass.sh
# #
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
# @author Daniel D. Daugherty # @author Daniel D. Daugherty
# #
# @run shell MakeJAR4.sh RetransformBigClassAgent SimpleIdentityTransformer 'Can-Retransform-Classes: true' # @run shell MakeJAR4.sh RetransformBigClassAgent SimpleIdentityTransformer 'Can-Retransform-Classes: true'
# @run build BigClass RetransformBigClassApp # @run build BigClass RetransformBigClassApp NMTHelper
# @run shell/timeout=600 RetransformBigClass.sh # @run shell/timeout=600 RetransformBigClass.sh
# #
......
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.invoke.MethodHandle;
import java.lang.reflect.InvocationTargetException;
/**
* Abstract class for lambda forms caching testing.
*
* @author kshefov
*/
public abstract class LFCachingTestCase extends LambdaFormTestCase {
/**
* Constructor for lambda forms caching test case.
*
* @param testMethod A method from {@code j.l.i.MethodHandles} class that
* returns a {@code j.l.i.MethodHandle} instance.
*/
protected LFCachingTestCase(TestMethods testMethod) {
super(testMethod);
}
/**
* Checks that the lambda forms of the two adapter method handles adapter1
* and adapter2 are the same.
*
* @param adapter1 First method handle.
* @param adapter2 Second method handle.
*/
public void checkLFCaching(MethodHandle adapter1, MethodHandle adapter2) {
try {
if (!adapter1.type().equals(adapter2.type())) {
throw new Error("TESTBUG: Types of the two method handles are not the same");
}
Object lambdaForm0 = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter1);
Object lambdaForm1 = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter2);
if (lambdaForm0 == null || lambdaForm1 == null) {
throw new Error("Unexpected error: One or both lambda forms of the method handles are null");
}
if (lambdaForm0 != lambdaForm1) {
System.err.println("Lambda form 0 toString is:");
System.err.println(lambdaForm0);
System.err.println("Lambda form 1 toString is:");
System.err.println(lambdaForm1);
throw new AssertionError("Error: Lambda forms of the two method handles"
+ " are not the same. LF cahing does not work");
}
} catch (IllegalAccessException | IllegalArgumentException |
SecurityException | InvocationTargetException ex) {
throw new Error("Unexpected exception: ", ex);
}
}
}
/*
* Copyright (c) 2014, 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 LFGarbageCollectedTest
* @bug 8046703
* @summary Test verifies that lambda forms are garbage collected
* @author kshefov
* @ignore 8057020
* @library /lib/testlibrary/jsr292 /lib/testlibrary
* @build TestMethods
* @build LambdaFormTestCase
* @build LFGarbageCollectedTest
* @run main/othervm/timeout=600 -Djava.lang.invoke.MethodHandle.USE_LF_EDITOR=true -DtestLimit=150 LFGarbageCollectedTest
*/
import java.lang.invoke.MethodHandle;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.InvocationTargetException;
import java.util.EnumSet;
import java.util.Map;
/**
* Lambda forms garbage collection test class.
*/
public final class LFGarbageCollectedTest extends LambdaFormTestCase {
/**
* Constructor for a lambda forms garbage collection test case.
*
* @param testMethod A method from {@code j.l.i.MethodHandles} class that
* returns a {@code j.l.i.MethodHandle} instance.
*/
public LFGarbageCollectedTest(TestMethods testMethod) {
super(testMethod);
}
@Override
public void doTest() {
try {
Map<String, Object> data = getTestMethod().getTestCaseData();
MethodHandle adapter;
try {
adapter = getTestMethod().getTestCaseMH(data, TestMethods.Kind.ONE);
} catch (NoSuchMethodException ex) {
throw new Error("Unexpected exception: ", ex);
}
Object lambdaForm = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter);
if (lambdaForm == null) {
throw new Error("Unexpected error: Lambda form of the method handle is null");
}
ReferenceQueue rq = new ReferenceQueue();
PhantomReference ph = new PhantomReference(lambdaForm, rq);
lambdaForm = null;
data = null;
adapter = null;
for (int i = 0; i < 1000 && !ph.isEnqueued(); i++) {
System.gc();
}
if (!ph.isEnqueued()) {
throw new AssertionError("Error: Lambda form is not garbage collected");
}
} catch (IllegalAccessException | IllegalArgumentException |
InvocationTargetException ex) {
throw new Error("Unexpected exception: ", ex);
}
}
/**
* Main routine for lambda forms garbage collection test.
*
* @param args Accepts no arguments.
*/
public static void main(String[] args) {
// The "identity", "constant", "arrayElementGetter" and "arrayElementSetter"
// methods should be removed from this test,
// because their lambda forms are stored in a static field and are not GC'ed.
// There can be only a finite number of such LFs for each method,
// so no memory leak happens.
EnumSet<TestMethods> testMethods = EnumSet.complementOf(EnumSet.of(
TestMethods.IDENTITY,
TestMethods.CONSTANT,
TestMethods.ARRAY_ELEMENT_GETTER,
TestMethods.ARRAY_ELEMENT_SETTER));
LambdaFormTestCase.runTests(LFGarbageCollectedTest::new, testMethods);
}
}
/*
* Copyright (c) 2014, 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 LFMultiThreadCachingTest
* @bug 8046703
* @summary Test verifies that lambda forms are cached when run with multiple threads
* @author kshefov
* @library /lib/testlibrary/jsr292 /lib/testlibrary
* @build TestMethods
* @build LambdaFormTestCase
* @build LFCachingTestCase
* @build LFMultiThreadCachingTest
* @run main/othervm/timeout=300 -Djava.lang.invoke.MethodHandle.USE_LF_EDITOR=true LFMultiThreadCachingTest
*/
import java.lang.invoke.MethodHandle;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
/**
* Multiple threaded lambda forms caching test class.
*/
public final class LFMultiThreadCachingTest extends LFCachingTestCase {
private static final TestMethods.Kind[] KINDS;
static {
EnumSet<TestMethods.Kind> set = EnumSet.complementOf(EnumSet.of(TestMethods.Kind.EXCEPT));
KINDS = set.toArray(new TestMethods.Kind[set.size()]);
if (KINDS.length < 2) {
throw new Error("TESTBUG: KINDS.length[" + KINDS.length + "] should be at least 2");
}
}
private static final int CORES = Math.max(KINDS.length, Runtime.getRuntime().availableProcessors());
/**
* Constructor a for multiple threaded lambda forms caching test case.
*
* @param testMethod A method from {@code j.l.i.MethodHandles} class that
* returns a {@code j.l.i.MethodHandle} instance.
*/
public LFMultiThreadCachingTest(TestMethods testMethod) {
super(testMethod);
}
@Override
public void doTest() {
Map<String, Object> data = getTestMethod().getTestCaseData();
ConcurrentLinkedQueue<MethodHandle> adapters = new ConcurrentLinkedQueue<>();
CyclicBarrier begin = new CyclicBarrier(CORES);
CountDownLatch end = new CountDownLatch(CORES);
for (int i = 0; i < CORES; ++i) {
TestMethods.Kind kind = KINDS[i % KINDS.length];
new Thread(() -> {
try {
begin.await();
adapters.add(getTestMethod().getTestCaseMH(data, kind));
} catch (InterruptedException | BrokenBarrierException | IllegalAccessException | NoSuchMethodException ex) {
throw new Error("Unexpected exception: ", ex);
} finally {
end.countDown();
}
}).start();
}
try {
end.await();
} catch (InterruptedException ex) {
throw new Error("Unexpected exception: ", ex);
}
if (adapters.size() < CORES) {
throw new Error("adapters size[" + adapters.size() + "] is less than " + CORES);
}
MethodHandle prev = adapters.poll();
for (MethodHandle current : adapters) {
checkLFCaching(prev, current);
prev = current;
}
}
/**
* Main routine for multiple threaded lambda forms caching test.
*
* @param args Accepts no arguments.
*/
public static void main(String[] args) {
LambdaFormTestCase.runTests(LFMultiThreadCachingTest::new, EnumSet.allOf(TestMethods.class));
}
}
/*
* Copyright (c) 2014, 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 LFSingleThreadCachingTest
* @bug 8046703
* @summary Test verifies that lambda forms are cached when run with single thread
* @author kshefov
* @library /lib/testlibrary/jsr292 /lib/testlibrary
* @build TestMethods
* @build LambdaFormTestCase
* @build LFCachingTestCase
* @build LFSingleThreadCachingTest
* @run main/othervm/timeout=300 -Djava.lang.invoke.MethodHandle.USE_LF_EDITOR=true LFSingleThreadCachingTest
*/
import java.lang.invoke.MethodHandle;
import java.util.EnumSet;
import java.util.Map;
/**
* Single threaded lambda forms caching test class.
*/
public final class LFSingleThreadCachingTest extends LFCachingTestCase {
/**
* Constructor for a single threaded lambda forms caching test case.
*
* @param testMethod A method from {@code j.l.i.MethodHandles} class that
* returns a {@code j.l.i.MethodHandle} instance.
*/
public LFSingleThreadCachingTest(TestMethods testMethod) {
super(testMethod);
}
@Override
public void doTest() {
MethodHandle adapter1;
MethodHandle adapter2;
Map<String, Object> data = getTestMethod().getTestCaseData();
try {
adapter1 = getTestMethod().getTestCaseMH(data, TestMethods.Kind.ONE);
adapter2 = getTestMethod().getTestCaseMH(data, TestMethods.Kind.TWO);
} catch (NoSuchMethodException | IllegalAccessException ex) {
throw new Error("Unexpected exception: ", ex);
}
checkLFCaching(adapter1, adapter2);
}
/**
* Main routine for single threaded lambda forms caching test.
*
* @param args Accepts no arguments.
*/
public static void main(String[] args) {
LambdaFormTestCase.runTests(LFSingleThreadCachingTest::new, EnumSet.allOf(TestMethods.class));
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.oracle.testlibrary.jsr292.Helper;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.function.Function;
/**
* Lambda forms caching test case class. Contains all necessary test routines to
* test lambda forms caching in method handles returned by methods of
* MethodHandles class.
*
* @author kshefov
*/
public abstract class LambdaFormTestCase {
private final static String METHOD_HANDLE_CLASS_NAME = "java.lang.invoke.MethodHandle";
private final static String INTERNAL_FORM_METHOD_NAME = "internalForm";
/**
* Reflection link to {@code j.l.i.MethodHandle.internalForm} method. It is
* used to get a lambda form from a method handle.
*/
protected final static Method INTERNAL_FORM;
static {
try {
Class mhClass = Class.forName(METHOD_HANDLE_CLASS_NAME);
INTERNAL_FORM = mhClass.getDeclaredMethod(INTERNAL_FORM_METHOD_NAME);
INTERNAL_FORM.setAccessible(true);
} catch (Exception ex) {
throw new Error("Unexpected exception: ", ex);
}
}
private final TestMethods testMethod;
/**
* Test case constructor. Generates test cases with random method types for
* given methods form {@code j.l.i.MethodHandles} class.
*
* @param testMethod A method from {@code j.l.i.MethodHandles} class which
* returns a {@code j.l.i.MethodHandle}.
*/
protected LambdaFormTestCase(TestMethods testMethod) {
this.testMethod = testMethod;
}
public TestMethods getTestMethod() {
return testMethod;
}
/**
* Routine that executes a test case.
*/
public abstract void doTest();
/**
* Runs a number of test cases defined by the size of testCases list.
*
* @param ctor constructor of LambdaFormCachingTest or its child classes
* object.
* @param testMethods list of test methods
*/
public static void runTests(Function<TestMethods, LambdaFormTestCase> ctor, Collection<TestMethods> testMethods) {
boolean passed = true;
int testCounter = 0;
int failCounter = 0;
long iterations = Math.max(1, Helper.TEST_LIMIT / testMethods.size());
for (long i = 0; i < iterations; i++) {
System.err.println(String.format("Iteration %d:", i));
for (TestMethods testMethod : testMethods) {
LambdaFormTestCase testCase = ctor.apply(testMethod);
try {
System.err.printf("Tested LF caching feature with MethodHandles.%s method.%n",
testCase.getTestMethod().name);
testCase.doTest();
System.err.println("PASSED");
} catch (Throwable t) {
t.printStackTrace();
System.err.println("FAILED");
passed = false;
failCounter++;
}
testCounter++;
}
}
if (!passed) {
throw new Error(String.format("%d of %d test cases FAILED! %n"
+ "Rerun the test with the same \"-Dseed=\" option as in the log file!",
failCounter, testCounter));
} else {
System.err.println(String.format("All %d test cases PASSED!", testCounter));
}
}
}
此差异已折叠。
...@@ -43,6 +43,7 @@ import java.util.function.Supplier; ...@@ -43,6 +43,7 @@ import java.util.function.Supplier;
public class CatchExceptionTest { public class CatchExceptionTest {
private static final List<Class<?>> ARGS_CLASSES; private static final List<Class<?>> ARGS_CLASSES;
protected static final int MAX_ARITY = Helper.MAX_ARITY - 1; protected static final int MAX_ARITY = Helper.MAX_ARITY - 1;
static { static {
Class<?> classes[] = { Class<?> classes[] = {
Object.class, Object.class,
...@@ -53,11 +54,8 @@ public class CatchExceptionTest { ...@@ -53,11 +54,8 @@ public class CatchExceptionTest {
double[].class, double[].class,
String.class, String.class,
}; };
List<Class<?>> list = new ArrayList<>(MAX_ARITY); ARGS_CLASSES = Collections.unmodifiableList(
for (int i = 0; i < MAX_ARITY; ++i) { Helper.randomClasses(classes, MAX_ARITY));
list.add(classes[Helper.RNG.nextInt(classes.length)]);
}
ARGS_CLASSES = Collections.unmodifiableList(list);
} }
private final TestCase testCase; private final TestCase testCase;
...@@ -67,7 +65,6 @@ public class CatchExceptionTest { ...@@ -67,7 +65,6 @@ public class CatchExceptionTest {
private int dropped; private int dropped;
private MethodHandle thrower; private MethodHandle thrower;
public CatchExceptionTest(TestCase testCase, final boolean isVararg, final int argsCount, public CatchExceptionTest(TestCase testCase, final boolean isVararg, final int argsCount,
final int catchDrops) { final int catchDrops) {
this.testCase = testCase; this.testCase = testCase;
...@@ -108,37 +105,7 @@ public class CatchExceptionTest { ...@@ -108,37 +105,7 @@ public class CatchExceptionTest {
} }
private List<Class<?>> getThrowerParams(boolean isVararg, int argsCount) { private List<Class<?>> getThrowerParams(boolean isVararg, int argsCount) {
boolean unmodifiable = true; return Helper.getParams(ARGS_CLASSES, isVararg, argsCount);
List<Class<?>> classes;
classes = ARGS_CLASSES.subList(0,
Math.min(argsCount, (MAX_ARITY / 2) - 1));
int extra = 0;
if (argsCount >= MAX_ARITY / 2) {
classes = new ArrayList<>(classes);
unmodifiable = false;
extra = (int) classes.stream().filter(Helper::isDoubleCost).count();
int i = classes.size();
while (classes.size() + extra < argsCount) {
Class<?> aClass = ARGS_CLASSES.get(i);
if (Helper.isDoubleCost(aClass)) {
++extra;
if (classes.size() + extra >= argsCount) {
break;
}
}
classes.add(aClass);
}
}
if (isVararg && classes.size() > 0) {
if (unmodifiable) {
classes = new ArrayList<>(classes);
}
int last = classes.size() - 1;
Class<?> aClass = classes.get(classes.size() - 1);
aClass = Array.newInstance(aClass, 2).getClass();
classes.set(last, aClass);
}
return classes;
} }
......
...@@ -23,8 +23,10 @@ ...@@ -23,8 +23,10 @@
/* /*
* @test * @test
* @bug 4902952 4905407 4916149 * @bug 4902952 4905407 4916149 8057793
* @summary Tests that the scale of zero is propagated properly and has the proper effect. * @summary Tests that the scale of zero is propagated properly and has the
* proper effect and that setting the scale to zero does not mutate the
* BigDecimal.
* @author Joseph D. Darcy * @author Joseph D. Darcy
*/ */
...@@ -445,6 +447,16 @@ public class ZeroScalingTests { ...@@ -445,6 +447,16 @@ public class ZeroScalingTests {
return failures; return failures;
} }
static int setScaleDoesNotMutateTest() {
BigDecimal total = new BigDecimal("258815507198903607775511093103396443816569106750031264155319238473795838680758514810110764742309284477206138527975952150289602995045050194333030191178778772026538699925775139201970526695485362661420908248887297829319881475178467494779683293036572059595504702727301324759997409522995072582369210284334718757260859794972695026582432867589093687280300148141501712013226636373167978223780290547640482160818746599330924736802844173226042389174403401903999447463440670236056324929325189403433689"
+ ".426167432065785331444814035799717606745777287606858873045971898862329763544687891847664736523584843544347118836628373041412918374550458884706686730726101338872517021688769782894793734049819222924171842793485919753186993388451909096042127903835765393729547730953942175461146061715108701615615142134282261293656760570061554783195726716403304101469782303957325142638493327692352838806741611887655695029948975509680496573999174402058593454203190963443179532640446352828089016874853634851387762579319853267317320515941105912189838719919259277721994880193541634872882180184303434360412344059435559680494807415573269199203376126242271766939666939316648575065702750502798973418978204972336924254702551350654650573582614211506856383897692911422458286912085339575875324832979140870119455620532272318122103640233069115700020760625493816902806241630788230268031695140687964931377988962507263990468276009750998066442971308866347136022907166625330623130307555914930120150437900510530537258665172619821272937026713977709974434967165159545592482710663639966781678268622620229577009317698254134914742098420792313931843709810905414336383757407675429663714210967924767434203021205270369316797752411974617662200898086335322218191674846795163102021505555508444216708745911194321674887527227200297039471799580744303346354057273540730643842091810899490590914195225087593013834388801018488174855060306804024894292757613618190472234110859436472645203753139820658279559340251226992556744343475086923568365637919479462424794554522865559888240039662899509652221329892034706445253487898044421278283079233226845124525434586324657471286953226255430662125870993375281512713207125720748163498642795960457639954616530163959004770092547297392499137383176609646505351001304840762905826237024982330597805063521162285806541220110524989649256399233792799406995068469271941269511818994954109392839548141262324660472253632382325038836831429045617036015122388070240133760858500132713255407855625837956886349324981003917084922808187223285051144454915441134217743066575863563572152133978905444998209075763950909784148142018992367290485890072303179512881131769414783097454103103347826517701720263541869335631166977965013552647906729408522950996105479525445916501155305220090853891226367184989434453290788068397817927893708837722255115237672194162924260945492012622891770365546831236789867922136747819364833843397165107825773447549885351449899330007200651144003961228091210630807333236718793283427788965479074476288255387824982443633190938302785760754436525586544523339170400053128503337395428393881357669568532722167493096151221381017320147344991331421789379785964440840684363041795410525097564979585773948558651896834067324427900848255265001498890329859444233861478388742393060996236783742654761350763876989363052609107226398858310051497856931093693697981165801539060516895227818925342535261227134364063673285588256280386915163875872231395348293505967057794409379709079685798908660258077792158532257603211711587587586356431658240229896344639704");
if (total.setScale(0, RoundingMode.DOWN).equals(total.setScale(0, RoundingMode.DOWN))) {
return 0;
} else {
return 1;
}
}
public static void main(String argv[]) { public static void main(String argv[]) {
int failures = 0; int failures = 0;
...@@ -455,6 +467,7 @@ public class ZeroScalingTests { ...@@ -455,6 +467,7 @@ public class ZeroScalingTests {
failures += setScaleTests(); failures += setScaleTests();
failures += toEngineeringStringTests(); failures += toEngineeringStringTests();
failures += ulpTests(); failures += ulpTests();
failures += setScaleDoesNotMutateTest();
if (failures > 0 ) { if (failures > 0 ) {
throw new RuntimeException("Incurred " + failures + " failures" + throw new RuntimeException("Incurred " + failures + " failures" +
......
...@@ -71,6 +71,7 @@ public class BigIntegerTest { ...@@ -71,6 +71,7 @@ public class BigIntegerTest {
static final int BITS_TOOM_COOK_SQUARE = 6912; static final int BITS_TOOM_COOK_SQUARE = 6912;
static final int BITS_SCHOENHAGE_BASE = 640; static final int BITS_SCHOENHAGE_BASE = 640;
static final int BITS_BURNIKEL_ZIEGLER = 2560; static final int BITS_BURNIKEL_ZIEGLER = 2560;
static final int BITS_BURNIKEL_ZIEGLER_OFFSET = 1280;
static final int ORDER_SMALL = 60; static final int ORDER_SMALL = 60;
static final int ORDER_MEDIUM = 100; static final int ORDER_MEDIUM = 100;
...@@ -288,19 +289,19 @@ public class BigIntegerTest { ...@@ -288,19 +289,19 @@ public class BigIntegerTest {
* where {@code abs(u) > abs(v)} and {@code a > b && b > 0}, then if * where {@code abs(u) > abs(v)} and {@code a > b && b > 0}, then if
* {@code w/z = q1*z + r1} and {@code u/v = q2*v + r2}, then * {@code w/z = q1*z + r1} and {@code u/v = q2*v + r2}, then
* {@code q1 = q2*pow(2,a-b)} and {@code r1 = r2*pow(2,b)}. The test * {@code q1 = q2*pow(2,a-b)} and {@code r1 = r2*pow(2,b)}. The test
* ensures that {@code v} is just under the B-Z threshold and that {@code w} * ensures that {@code v} is just under the B-Z threshold, that {@code z} is
* and {@code z} are both over the threshold. This implies that {@code u/v} * over the threshold and {@code w} is much larger than {@code z}. This
* uses the standard division algorithm and {@code w/z} uses the B-Z * implies that {@code u/v} uses the standard division algorithm and
* algorithm. The results of the two algorithms are then compared using the * {@code w/z} uses the B-Z algorithm. The results of the two algorithms
* observation described in the foregoing and if they are not equal a * are then compared using the observation described in the foregoing and
* failure is logged. * if they are not equal a failure is logged.
*/ */
public static void divideLarge() { public static void divideLarge() {
int failCount = 0; int failCount = 0;
BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER - 33); BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 33);
for (int i=0; i<SIZE; i++) { for (int i=0; i<SIZE; i++) {
BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER - 34, rnd); BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 34, rnd);
BigInteger v = base.add(addend); BigInteger v = base.add(addend);
BigInteger u = v.multiply(BigInteger.valueOf(2 + rnd.nextInt(Short.MAX_VALUE - 1))); BigInteger u = v.multiply(BigInteger.valueOf(2 + rnd.nextInt(Short.MAX_VALUE - 1)));
...@@ -312,14 +313,14 @@ public class BigIntegerTest { ...@@ -312,14 +313,14 @@ public class BigIntegerTest {
v = v.negate(); v = v.negate();
} }
int a = 17 + rnd.nextInt(16); int a = BITS_BURNIKEL_ZIEGLER_OFFSET + rnd.nextInt(16);
int b = 1 + rnd.nextInt(16); int b = 1 + rnd.nextInt(16);
BigInteger w = u.multiply(BigInteger.valueOf(1L << a)); BigInteger w = u.multiply(BigInteger.ONE.shiftLeft(a));
BigInteger z = v.multiply(BigInteger.valueOf(1L << b)); BigInteger z = v.multiply(BigInteger.ONE.shiftLeft(b));
BigInteger[] divideResult = u.divideAndRemainder(v); BigInteger[] divideResult = u.divideAndRemainder(v);
divideResult[0] = divideResult[0].multiply(BigInteger.valueOf(1L << (a - b))); divideResult[0] = divideResult[0].multiply(BigInteger.ONE.shiftLeft(a - b));
divideResult[1] = divideResult[1].multiply(BigInteger.valueOf(1L << b)); divideResult[1] = divideResult[1].multiply(BigInteger.ONE.shiftLeft(b));
BigInteger[] bzResult = w.divideAndRemainder(z); BigInteger[] bzResult = w.divideAndRemainder(z);
if (divideResult[0].compareTo(bzResult[0]) != 0 || if (divideResult[0].compareTo(bzResult[0]) != 0 ||
......
...@@ -22,7 +22,9 @@ ...@@ -22,7 +22,9 @@
*/ */
/* @test /* @test
* @bug 4405354 6594296 * @bug 4405354 6594296 8058216
* @run main Test
* @run main/othervm -Djava.net.preferIPv4Stack=true Test
* @summary Basic tests for NetworkInterface * @summary Basic tests for NetworkInterface
*/ */
import java.net.NetworkInterface; import java.net.NetworkInterface;
......
...@@ -58,9 +58,9 @@ import javax.management.openmbean.SimpleType; ...@@ -58,9 +58,9 @@ import javax.management.openmbean.SimpleType;
public class AttributeArbitraryDataTypeTest implements NotificationListener { public class AttributeArbitraryDataTypeTest implements NotificationListener {
// Flag to notify that a message has been received // Flag to notify that a message has been received
private boolean counterMessageReceived = false; private volatile boolean counterMessageReceived = false;
private boolean gaugeMessageReceived = false; private volatile boolean gaugeMessageReceived = false;
private boolean stringMessageReceived = false; private volatile boolean stringMessageReceived = false;
// Match enum // Match enum
public enum Match { do_not_match_0, public enum Match { do_not_match_0,
...@@ -195,21 +195,33 @@ public class AttributeArbitraryDataTypeTest implements NotificationListener { ...@@ -195,21 +195,33 @@ public class AttributeArbitraryDataTypeTest implements NotificationListener {
" has reached or exceeded the threshold"); " has reached or exceeded the threshold");
echo("\t\tDerived Gauge = " + n.getDerivedGauge()); echo("\t\tDerived Gauge = " + n.getDerivedGauge());
echo("\t\tTrigger = " + n.getTrigger()); echo("\t\tTrigger = " + n.getTrigger());
counterMessageReceived = true;
synchronized (this) {
counterMessageReceived = true;
notifyAll();
}
} else if (type.equals(MonitorNotification. } else if (type.equals(MonitorNotification.
THRESHOLD_HIGH_VALUE_EXCEEDED)) { THRESHOLD_HIGH_VALUE_EXCEEDED)) {
echo("\t\t" + n.getObservedAttribute() + echo("\t\t" + n.getObservedAttribute() +
" has reached or exceeded the high threshold"); " has reached or exceeded the high threshold");
echo("\t\tDerived Gauge = " + n.getDerivedGauge()); echo("\t\tDerived Gauge = " + n.getDerivedGauge());
echo("\t\tTrigger = " + n.getTrigger()); echo("\t\tTrigger = " + n.getTrigger());
gaugeMessageReceived = true;
synchronized (this) {
gaugeMessageReceived = true;
notifyAll();
}
} else if (type.equals(MonitorNotification. } else if (type.equals(MonitorNotification.
STRING_TO_COMPARE_VALUE_MATCHED)) { STRING_TO_COMPARE_VALUE_MATCHED)) {
echo("\t\t" + n.getObservedAttribute() + echo("\t\t" + n.getObservedAttribute() +
" matches the string-to-compare value"); " matches the string-to-compare value");
echo("\t\tDerived Gauge = " + n.getDerivedGauge()); echo("\t\tDerived Gauge = " + n.getDerivedGauge());
echo("\t\tTrigger = " + n.getTrigger()); echo("\t\tTrigger = " + n.getTrigger());
stringMessageReceived = true;
synchronized (this) {
stringMessageReceived = true;
notifyAll();
}
} else { } else {
echo("\t\tSkipping notification of type: " + type); echo("\t\tSkipping notification of type: " + type);
} }
...@@ -358,6 +370,17 @@ public class AttributeArbitraryDataTypeTest implements NotificationListener { ...@@ -358,6 +370,17 @@ public class AttributeArbitraryDataTypeTest implements NotificationListener {
// Check if notification was received // Check if notification was received
// //
synchronized (this) {
while (!counterMessageReceived) {
try {
wait();
} catch (InterruptedException e) {
System.err.println("Got unexpected exception: " + e);
e.printStackTrace();
break;
}
}
}
if (counterMessageReceived) { if (counterMessageReceived) {
echo("\tOK: CounterMonitor notification received"); echo("\tOK: CounterMonitor notification received");
} else { } else {
...@@ -525,6 +548,17 @@ public class AttributeArbitraryDataTypeTest implements NotificationListener { ...@@ -525,6 +548,17 @@ public class AttributeArbitraryDataTypeTest implements NotificationListener {
// Check if notification was received // Check if notification was received
// //
synchronized (this) {
while (!gaugeMessageReceived) {
try {
wait();
} catch (InterruptedException e) {
System.err.println("Got unexpected exception: " + e);
e.printStackTrace();
break;
}
}
}
if (gaugeMessageReceived) { if (gaugeMessageReceived) {
echo("\tOK: GaugeMonitor notification received"); echo("\tOK: GaugeMonitor notification received");
} else { } else {
...@@ -680,6 +714,17 @@ public class AttributeArbitraryDataTypeTest implements NotificationListener { ...@@ -680,6 +714,17 @@ public class AttributeArbitraryDataTypeTest implements NotificationListener {
// Check if notification was received // Check if notification was received
// //
synchronized (this) {
while (!stringMessageReceived) {
try {
wait();
} catch (InterruptedException e) {
System.err.println("Got unexpected exception: " + e);
e.printStackTrace();
break;
}
}
}
if (stringMessageReceived) { if (stringMessageReceived) {
echo("\tOK: StringMonitor notification received"); echo("\tOK: StringMonitor notification received");
} else { } else {
......
...@@ -43,9 +43,6 @@ public class CounterMonitorTest implements NotificationListener { ...@@ -43,9 +43,6 @@ public class CounterMonitorTest implements NotificationListener {
// modulus number // modulus number
private Number modulus = new Integer(7); private Number modulus = new Integer(7);
// offset number
private int offset = 0;
// difference mode flag // difference mode flag
private boolean differenceModeFlag = true; private boolean differenceModeFlag = true;
...@@ -58,9 +55,6 @@ public class CounterMonitorTest implements NotificationListener { ...@@ -58,9 +55,6 @@ public class CounterMonitorTest implements NotificationListener {
// counter values // counter values
private int[] values = new int[] {4, 6, 9, 11}; private int[] values = new int[] {4, 6, 9, 11};
// time to wait for notification (in seconds)
private int timeout = 5;
// flag to notify that a message has been received // flag to notify that a message has been received
private volatile boolean messageReceived = false; private volatile boolean messageReceived = false;
...@@ -92,8 +86,9 @@ public class CounterMonitorTest implements NotificationListener { ...@@ -92,8 +86,9 @@ public class CounterMonitorTest implements NotificationListener {
echo("\t\t" + n.getObservedAttribute() + echo("\t\t" + n.getObservedAttribute() +
" has reached or exceeded the threshold"); " has reached or exceeded the threshold");
echo("\t\tDerived Gauge = " + n.getDerivedGauge()); echo("\t\tDerived Gauge = " + n.getDerivedGauge());
messageReceived = true;
synchronized (this) { synchronized (this) {
messageReceived = true;
notifyAll(); notifyAll();
} }
} else { } else {
...@@ -205,21 +200,16 @@ public class CounterMonitorTest implements NotificationListener { ...@@ -205,21 +200,16 @@ public class CounterMonitorTest implements NotificationListener {
} }
/* /*
* Wait until timeout reached * Wait messageReceived to be true
*/ */
void doWait() { synchronized void doWait() {
for (int i = 0; i < timeout; i++) { while (!messageReceived) {
echo("\tdoWait: Waiting for " + timeout + " seconds. " +
"i = " + i + ", messageReceived = " + messageReceived);
if (messageReceived) {
break;
}
try { try {
synchronized (this) { wait();
wait(1000);
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
// OK: Ignore... System.err.println("Got unexpected exception: " + e);
e.printStackTrace();
break;
} }
} }
} }
......
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
*/ */
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.management.Attribute;
import javax.management.JMX; import javax.management.JMX;
import javax.management.MBeanServer; import javax.management.MBeanServer;
import javax.management.Notification; import javax.management.Notification;
...@@ -47,10 +48,16 @@ import javax.management.monitor.GaugeMonitor; ...@@ -47,10 +48,16 @@ import javax.management.monitor.GaugeMonitor;
import javax.management.monitor.GaugeMonitorMBean; import javax.management.monitor.GaugeMonitorMBean;
public class GaugeMonitorDeadlockTest { public class GaugeMonitorDeadlockTest {
private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
private static long checkingTime;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
if (args.length != 1) if (args.length != 1)
throw new Exception("Arg should be test number"); throw new Exception("Arg should be test number");
double factor = Double.parseDouble(System.getProperty("test.timeout.factor", "1.0"));
checkingTime = (long)factor*1000;
System.out.println("=== checkingTime = " + checkingTime + "ms");
int testNo = Integer.parseInt(args[0]) - 1; int testNo = Integer.parseInt(args[0]) - 1;
TestCase test = testCases[testNo]; TestCase test = testCases[testNo];
System.out.println("Test: " + test.getDescription()); System.out.println("Test: " + test.getDescription());
...@@ -58,8 +65,6 @@ public class GaugeMonitorDeadlockTest { ...@@ -58,8 +65,6 @@ public class GaugeMonitorDeadlockTest {
System.out.println("Test passed"); System.out.println("Test passed");
} }
private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
private static abstract class TestCase { private static abstract class TestCase {
TestCase(String description, When when) { TestCase(String description, When when) {
this.description = description; this.description = description;
...@@ -98,16 +103,29 @@ public class GaugeMonitorDeadlockTest { ...@@ -98,16 +103,29 @@ public class GaugeMonitorDeadlockTest {
monitorProxy.setNotifyLow(true); monitorProxy.setNotifyLow(true);
monitorProxy.start(); monitorProxy.start();
System.out.println("=== Waiting observedProxy.getGetCount() to be "
+ "changed, presumable deadlock if timeout?");
final int initGetCount = observedProxy.getGetCount(); final int initGetCount = observedProxy.getGetCount();
int getCount = initGetCount; long checkedTime = System.currentTimeMillis();
for (int i = 0; i < 2000; i++) { // 2000 * 10 = 20 seconds long nowTime;
getCount = observedProxy.getGetCount(); ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
if (getCount != initGetCount) while (observedProxy.getGetCount() == initGetCount) {
break; Thread.sleep(100);
Thread.sleep(10);
nowTime = System.currentTimeMillis();
if (nowTime - checkedTime >= checkingTime) {
System.out.println("=== Checking deadlocked ...");
if (threadMXBean.findDeadlockedThreads() != null) {
for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
System.out.println(info);
}
throw new Error("Found deadlocked threads: "
+ threadMXBean.findDeadlockedThreads().length);
}
checkedTime = System.currentTimeMillis();
}
} }
if (getCount <= initGetCount)
throw new Exception("Test failed: presumable deadlock");
// This won't show up as a deadlock in CTRL-\ or in // This won't show up as a deadlock in CTRL-\ or in
// ThreadMXBean.findDeadlockedThreads(), because they don't // ThreadMXBean.findDeadlockedThreads(), because they don't
// see that thread A is waiting for thread B (B.join()), and // see that thread A is waiting for thread B (B.join()), and
...@@ -117,13 +135,13 @@ public class GaugeMonitorDeadlockTest { ...@@ -117,13 +135,13 @@ public class GaugeMonitorDeadlockTest {
// so if we want to test notify behaviour we can trigger by // so if we want to test notify behaviour we can trigger by
// exceeding the threshold. // exceeding the threshold.
if (when == When.IN_NOTIFY) { if (when == When.IN_NOTIFY) {
final Thread testedThread = new Thread(sensitiveThing);
final AtomicInteger notifCount = new AtomicInteger(); final AtomicInteger notifCount = new AtomicInteger();
final NotificationListener listener = new NotificationListener() { final NotificationListener listener = new NotificationListener() {
public void handleNotification(Notification n, Object h) { public void handleNotification(Notification n, Object h) {
Thread t = new Thread(sensitiveThing); testedThread.start();
t.start();
try { try {
t.join(); testedThread.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
...@@ -132,12 +150,36 @@ public class GaugeMonitorDeadlockTest { ...@@ -132,12 +150,36 @@ public class GaugeMonitorDeadlockTest {
}; };
mbs.addNotificationListener(monitorName, listener, null, null); mbs.addNotificationListener(monitorName, listener, null, null);
observedProxy.setThing(1000); observedProxy.setThing(1000);
for (int i = 0; i < 2000 && notifCount.get() == 0; i++) System.out.println("=== Waiting notifications, presumable "
Thread.sleep(10); + "deadlock if timeout?");
if (notifCount.get() == 0) long startTime = System.currentTimeMillis();
throw new Exception("Test failed: presumable deadlock"); checkedTime = startTime;
} while (notifCount.get() == 0) {
Thread.sleep(100);
nowTime = System.currentTimeMillis();
if (nowTime - checkedTime >= checkingTime) {
System.out.println("=== Checking the thread state ...");
if (testedThread.isAlive()) {
System.out.println("=== Waiting testedThread to die "
+ "after " + (nowTime - startTime) + "ms");
ThreadInfo tinfo = threadMXBean.getThreadInfo(testedThread.getId());
if (Thread.State.BLOCKED.equals(tinfo.getThreadState())) {
for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
System.out.println(info);
}
} else {
System.out.println(tinfo);
}
} else {
System.out.println("=== The testedThread is dead as wished, "
+ "the test must be passed soon.");
}
checkedTime = System.currentTimeMillis();
}
}
}
} }
abstract void doSensitiveThing(GaugeMonitorMBean monitorProxy, abstract void doSensitiveThing(GaugeMonitorMBean monitorProxy,
......
...@@ -39,7 +39,7 @@ import javax.management.monitor.*; ...@@ -39,7 +39,7 @@ import javax.management.monitor.*;
public class NonComparableAttributeValueTest implements NotificationListener { public class NonComparableAttributeValueTest implements NotificationListener {
// Flag to notify that a message has been received // Flag to notify that a message has been received
private boolean messageReceived = false; private volatile boolean messageReceived = false;
// MBean class // MBean class
public class ObservedObject implements ObservedObjectMBean { public class ObservedObject implements ObservedObjectMBean {
...@@ -69,7 +69,11 @@ public class NonComparableAttributeValueTest implements NotificationListener { ...@@ -69,7 +69,11 @@ public class NonComparableAttributeValueTest implements NotificationListener {
echo("\t\t" + n.getObservedAttribute() + " is null"); echo("\t\t" + n.getObservedAttribute() + " is null");
echo("\t\tDerived Gauge = " + n.getDerivedGauge()); echo("\t\tDerived Gauge = " + n.getDerivedGauge());
echo("\t\tTrigger = " + n.getTrigger()); echo("\t\tTrigger = " + n.getTrigger());
messageReceived = true;
synchronized (this) {
messageReceived = true;
notifyAll();
}
} else { } else {
echo("\t\tSkipping notification of type: " + type); echo("\t\tSkipping notification of type: " + type);
} }
...@@ -134,12 +138,9 @@ public class NonComparableAttributeValueTest implements NotificationListener { ...@@ -134,12 +138,9 @@ public class NonComparableAttributeValueTest implements NotificationListener {
echo(">>> START the CounterMonitor"); echo(">>> START the CounterMonitor");
counterMonitor.start(); counterMonitor.start();
// Wait for granularity period (multiplied by 2 for sure)
//
Thread.sleep(granularityperiod * 2);
// Check if notification was received // Check if notification was received
// //
doWait();
if (messageReceived) { if (messageReceived) {
echo("\tOK: CounterMonitor notification received"); echo("\tOK: CounterMonitor notification received");
} else { } else {
...@@ -212,12 +213,9 @@ public class NonComparableAttributeValueTest implements NotificationListener { ...@@ -212,12 +213,9 @@ public class NonComparableAttributeValueTest implements NotificationListener {
echo(">>> START the GaugeMonitor"); echo(">>> START the GaugeMonitor");
gaugeMonitor.start(); gaugeMonitor.start();
// Wait for granularity period (multiplied by 2 for sure)
//
Thread.sleep(granularityperiod * 2);
// Check if notification was received // Check if notification was received
// //
doWait();
if (messageReceived) { if (messageReceived) {
echo("\tOK: GaugeMonitor notification received"); echo("\tOK: GaugeMonitor notification received");
} else { } else {
...@@ -289,12 +287,9 @@ public class NonComparableAttributeValueTest implements NotificationListener { ...@@ -289,12 +287,9 @@ public class NonComparableAttributeValueTest implements NotificationListener {
echo(">>> START the StringMonitor"); echo(">>> START the StringMonitor");
stringMonitor.start(); stringMonitor.start();
// Wait for granularity period (multiplied by 2 for sure)
//
Thread.sleep(granularityperiod * 2);
// Check if notification was received // Check if notification was received
// //
doWait();
if (messageReceived) { if (messageReceived) {
echo("\tOK: StringMonitor notification received"); echo("\tOK: StringMonitor notification received");
} else { } else {
...@@ -333,6 +328,21 @@ public class NonComparableAttributeValueTest implements NotificationListener { ...@@ -333,6 +328,21 @@ public class NonComparableAttributeValueTest implements NotificationListener {
System.out.println(message); System.out.println(message);
} }
/*
* Wait messageReceived to be true
*/
synchronized void doWait() {
while (!messageReceived) {
try {
wait();
} catch (InterruptedException e) {
System.err.println("Got unexpected exception: " + e);
e.printStackTrace();
break;
}
}
}
/* /*
* Standalone entry point. * Standalone entry point.
* *
......
...@@ -87,7 +87,11 @@ public class ReflectionExceptionTest implements NotificationListener { ...@@ -87,7 +87,11 @@ public class ReflectionExceptionTest implements NotificationListener {
echo("\tObservedAttribute: " + mn.getObservedAttribute()); echo("\tObservedAttribute: " + mn.getObservedAttribute());
echo("\tDerivedGauge: " + mn.getDerivedGauge()); echo("\tDerivedGauge: " + mn.getDerivedGauge());
echo("\tTrigger: " + mn.getTrigger()); echo("\tTrigger: " + mn.getTrigger());
messageReceived = true;
synchronized (this) {
messageReceived = true;
notifyAll();
}
} }
} }
} }
...@@ -135,12 +139,9 @@ public class ReflectionExceptionTest implements NotificationListener { ...@@ -135,12 +139,9 @@ public class ReflectionExceptionTest implements NotificationListener {
echo(">>> START the CounterMonitor"); echo(">>> START the CounterMonitor");
counterMonitor.start(); counterMonitor.start();
// Wait for granularity period (multiplied by 2 for sure)
//
Thread.sleep(granularityperiod * 2);
// Check if notification was received // Check if notification was received
// //
doWait();
if (messageReceived) { if (messageReceived) {
echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!"); echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!");
} else { } else {
...@@ -203,12 +204,9 @@ public class ReflectionExceptionTest implements NotificationListener { ...@@ -203,12 +204,9 @@ public class ReflectionExceptionTest implements NotificationListener {
echo(">>> START the GaugeMonitor"); echo(">>> START the GaugeMonitor");
gaugeMonitor.start(); gaugeMonitor.start();
// Wait for granularity period (multiplied by 2 for sure)
//
Thread.sleep(granularityperiod * 2);
// Check if notification was received // Check if notification was received
// //
doWait();
if (messageReceived) { if (messageReceived) {
echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!"); echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!");
} else { } else {
...@@ -270,12 +268,9 @@ public class ReflectionExceptionTest implements NotificationListener { ...@@ -270,12 +268,9 @@ public class ReflectionExceptionTest implements NotificationListener {
echo(">>> START the StringMonitor"); echo(">>> START the StringMonitor");
stringMonitor.start(); stringMonitor.start();
// Wait for granularity period (multiplied by 2 for sure)
//
Thread.sleep(granularityperiod * 2);
// Check if notification was received // Check if notification was received
// //
doWait();
if (messageReceived) { if (messageReceived) {
echo("\tOK: StringMonitor got RUNTIME_ERROR notification!"); echo("\tOK: StringMonitor got RUNTIME_ERROR notification!");
} else { } else {
...@@ -349,8 +344,23 @@ public class ReflectionExceptionTest implements NotificationListener { ...@@ -349,8 +344,23 @@ public class ReflectionExceptionTest implements NotificationListener {
} }
} }
/*
* Wait messageReceived to be true
*/
synchronized void doWait() {
while (!messageReceived) {
try {
wait();
} catch (InterruptedException e) {
System.err.println("Got unexpected exception: " + e);
e.printStackTrace();
break;
}
}
}
// Flag to notify that a message has been received // Flag to notify that a message has been received
private boolean messageReceived = false; private volatile boolean messageReceived = false;
private MBeanServer server; private MBeanServer server;
private ObjectName obsObjName; private ObjectName obsObjName;
......
...@@ -86,7 +86,11 @@ public class RuntimeExceptionTest implements NotificationListener { ...@@ -86,7 +86,11 @@ public class RuntimeExceptionTest implements NotificationListener {
echo("\tObservedAttribute: " + mn.getObservedAttribute()); echo("\tObservedAttribute: " + mn.getObservedAttribute());
echo("\tDerivedGauge: " + mn.getDerivedGauge()); echo("\tDerivedGauge: " + mn.getDerivedGauge());
echo("\tTrigger: " + mn.getTrigger()); echo("\tTrigger: " + mn.getTrigger());
messageReceived = true;
synchronized (this) {
messageReceived = true;
notifyAll();
}
} }
} }
} }
...@@ -134,12 +138,9 @@ public class RuntimeExceptionTest implements NotificationListener { ...@@ -134,12 +138,9 @@ public class RuntimeExceptionTest implements NotificationListener {
echo(">>> START the CounterMonitor"); echo(">>> START the CounterMonitor");
counterMonitor.start(); counterMonitor.start();
// Wait for granularity period (multiplied by 2 for sure)
//
Thread.sleep(granularityperiod * 2);
// Check if notification was received // Check if notification was received
// //
doWait();
if (messageReceived) { if (messageReceived) {
echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!"); echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!");
} else { } else {
...@@ -202,12 +203,9 @@ public class RuntimeExceptionTest implements NotificationListener { ...@@ -202,12 +203,9 @@ public class RuntimeExceptionTest implements NotificationListener {
echo(">>> START the GaugeMonitor"); echo(">>> START the GaugeMonitor");
gaugeMonitor.start(); gaugeMonitor.start();
// Wait for granularity period (multiplied by 2 for sure)
//
Thread.sleep(granularityperiod * 2);
// Check if notification was received // Check if notification was received
// //
doWait();
if (messageReceived) { if (messageReceived) {
echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!"); echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!");
} else { } else {
...@@ -269,12 +267,9 @@ public class RuntimeExceptionTest implements NotificationListener { ...@@ -269,12 +267,9 @@ public class RuntimeExceptionTest implements NotificationListener {
echo(">>> START the StringMonitor"); echo(">>> START the StringMonitor");
stringMonitor.start(); stringMonitor.start();
// Wait for granularity period (multiplied by 2 for sure)
//
Thread.sleep(granularityperiod * 2);
// Check if notification was received // Check if notification was received
// //
doWait();
if (messageReceived) { if (messageReceived) {
echo("\tOK: StringMonitor got RUNTIME_ERROR notification!"); echo("\tOK: StringMonitor got RUNTIME_ERROR notification!");
} else { } else {
...@@ -347,8 +342,23 @@ public class RuntimeExceptionTest implements NotificationListener { ...@@ -347,8 +342,23 @@ public class RuntimeExceptionTest implements NotificationListener {
} }
} }
/*
* Wait messageReceived to be true
*/
synchronized void doWait() {
while (!messageReceived) {
try {
wait();
} catch (InterruptedException e) {
System.err.println("Got unexpected exception: " + e);
e.printStackTrace();
break;
}
}
}
// Flag to notify that a message has been received // Flag to notify that a message has been received
private boolean messageReceived = false; private volatile boolean messageReceived = false;
private MBeanServer server; private MBeanServer server;
private ObjectName obsObjName; private ObjectName obsObjName;
......
/*
* Copyright (c) 2014, 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.
*/
// SunJSSE does not support dynamic system properties, no way to re-use
// system properties in samevm/agentvm mode.
/*
* @test
* @bug 8052406
* @summary SSLv2Hello protocol may be filter out unexpectedly
* @run main/othervm ProtocolFilter
*/
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
public class ProtocolFilter {
/*
* =============================================================
* Set the various variables needed for the tests, then
* specify what tests to run on each side.
*/
/*
* Should we run the client or server in a separate thread?
* Both sides can throw exceptions, but do you have a preference
* as to which side should be the main thread.
*/
static boolean separateServerThread = false;
/*
* Where do we find the keystores?
*/
static String pathToStores = "../../../../sun/security/ssl/etc";
static String keyStoreFile = "keystore";
static String trustStoreFile = "truststore";
static String passwd = "passphrase";
/*
* Is the server ready to serve?
*/
volatile static boolean serverReady = false;
/*
* Turn on SSL debugging?
*/
static boolean debug = false;
/*
* If the client or server is doing some kind of object creation
* that the other side depends on, and that thread prematurely
* exits, you may experience a hang. The test harness will
* terminate all hung threads after its timeout has expired,
* currently 3 minutes by default, but you might try to be
* smart about it....
*/
/*
* Define the server side of the test.
*
* If the server prematurely exits, serverReady will be set to true
* to avoid infinite hangs.
*/
void doServerSide() throws Exception {
SSLServerSocketFactory sslssf =
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslServerSocket =
(SSLServerSocket) sslssf.createServerSocket(serverPort);
// Only enable cipher suites for TLS v1.2.
sslServerSocket.setEnabledCipherSuites(
new String[]{"TLS_RSA_WITH_AES_128_CBC_SHA256"});
serverPort = sslServerSocket.getLocalPort();
/*
* Signal Client, we're ready for his connect.
*/
serverReady = true;
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
InputStream sslIS = sslSocket.getInputStream();
OutputStream sslOS = sslSocket.getOutputStream();
sslIS.read();
sslOS.write(85);
sslOS.flush();
sslSocket.close();
}
/*
* Define the client side of the test.
*
* If the server prematurely exits, serverReady will be set to true
* to avoid infinite hangs.
*/
void doClientSide() throws Exception {
/*
* Wait for server to get started.
*/
while (!serverReady) {
Thread.sleep(50);
}
SSLSocketFactory sslsf =
(SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket)
sslsf.createSocket("localhost", serverPort);
// Enable all supported protocols, including SSLv2Hello.
sslSocket.setEnabledProtocols(sslSocket.getSupportedProtocols());
InputStream sslIS = sslSocket.getInputStream();
OutputStream sslOS = sslSocket.getOutputStream();
sslOS.write(280);
sslOS.flush();
sslIS.read();
sslSocket.close();
}
/*
* =============================================================
* The remainder is just support stuff
*/
// use any free port by default
volatile int serverPort = 0;
volatile Exception serverException = null;
volatile Exception clientException = null;
public static void main(String[] args) throws Exception {
String keyFilename =
System.getProperty("test.src", ".") + "/" + pathToStores +
"/" + keyStoreFile;
String trustFilename =
System.getProperty("test.src", ".") + "/" + pathToStores +
"/" + trustStoreFile;
System.setProperty("javax.net.ssl.keyStore", keyFilename);
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
System.setProperty("javax.net.ssl.trustStore", trustFilename);
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
if (debug)
System.setProperty("javax.net.debug", "all");
/*
* Start the tests.
*/
new ProtocolFilter();
}
Thread clientThread = null;
Thread serverThread = null;
/*
* Primary constructor, used to drive remainder of the test.
*
* Fork off the other side, then do your work.
*/
ProtocolFilter() throws Exception {
Exception startException = null;
try {
if (separateServerThread) {
startServer(true);
startClient(false);
} else {
startClient(true);
startServer(false);
}
} catch (Exception e) {
startException = e;
}
/*
* Wait for other side to close down.
*/
if (separateServerThread) {
if (serverThread != null) {
serverThread.join();
}
} else {
if (clientThread != null) {
clientThread.join();
}
}
/*
* When we get here, the test is pretty much over.
* Which side threw the error?
*/
Exception local;
Exception remote;
if (separateServerThread) {
remote = serverException;
local = clientException;
} else {
remote = clientException;
local = serverException;
}
Exception exception = null;
/*
* Check various exception conditions.
*/
if ((local != null) && (remote != null)) {
// If both failed, return the curthread's exception.
local.initCause(remote);
exception = local;
} else if (local != null) {
exception = local;
} else if (remote != null) {
exception = remote;
} else if (startException != null) {
exception = startException;
}
/*
* If there was an exception *AND* a startException,
* output it.
*/
if (exception != null) {
if (exception != startException && startException != null) {
exception.addSuppressed(startException);
}
throw exception;
}
// Fall-through: no exception to throw!
}
void startServer(boolean newThread) throws Exception {
if (newThread) {
serverThread = new Thread() {
public void run() {
try {
doServerSide();
} catch (Exception e) {
/*
* Our server thread just died.
*
* Release the client, if not active already...
*/
System.err.println("Server died...");
serverReady = true;
serverException = e;
}
}
};
serverThread.start();
} else {
try {
doServerSide();
} catch (Exception e) {
serverException = e;
} finally {
serverReady = true;
}
}
}
void startClient(boolean newThread) throws Exception {
if (newThread) {
clientThread = new Thread() {
public void run() {
try {
doClientSide();
} catch (Exception e) {
/*
* Our client thread just died.
*/
System.err.println("Client died...");
clientException = e;
}
}
};
clientThread.start();
} else {
try {
doClientSide();
} catch (Exception e) {
clientException = e;
}
}
}
}
/*
* Copyright (c) 2014, 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 8048110
* @summary Using tables in JTextPane leads to infinite loop in FlowLayout.layoutRow
* @author Dmitry Markov
* @run main bug8048110
*/
import sun.awt.SunToolkit;
import javax.swing.*;
import javax.swing.text.Element;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;
public class bug8048110 {
private static SunToolkit toolkit = (SunToolkit)Toolkit.getDefaultToolkit();
private static Object lock = new Object();
private static boolean isRealSyncPerformed = false;
private static final String htmlText = "<table width=\"100%\" cellpadding=\"10\" cellspacing=\"5\" align=\"center\">" +
"<tr><th align=\"left\" bgcolor=\"#bec3c6\">Devices</th><th align=\"left\" bgcolor=\"#bec3c6\">State</th></tr>" +
"<tr><td align=\"left\" bgcolor=\"#bec3c6\">PC</td><td align=\"left\" bgcolor=\"#46a055\">Ok</td></tr></table>";
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
Thread thread = new Thread() {
@Override
public void run() {
toolkit.realSync();
synchronized (lock) {
isRealSyncPerformed = true;
lock.notifyAll();
}
}
};
thread.start();
synchronized (lock) {
if (!isRealSyncPerformed) {
lock.wait(5000);
}
}
if (!isRealSyncPerformed) {
throw new RuntimeException("Test Failed!");
}
}
private static void createAndShowGUI() {
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (Exception ex) {
throw new RuntimeException(ex);
}
HTMLEditorKit editorKit = new HTMLEditorKit();
JTextPane textPane = new JTextPane();
textPane.setContentType("text/html");
textPane.setEditorKit(editorKit);
textPane.setText("Initial text without table");
JFrame frame = new JFrame("bug8048110");
frame.getContentPane().add(textPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(500, 200);
frame.setVisible(true);
textPane.setDocument(textPane.getEditorKit().createDefaultDocument());
HTMLDocument htmlDocument = (HTMLDocument) textPane.getDocument();
Element firstParagraph = findFirstElement(textPane.getDocument().getDefaultRootElement(), "p");
try {
htmlDocument.setInnerHTML(firstParagraph, htmlText);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private static Element findFirstElement(Element e, String name) {
String elementName = e.getName();
if (elementName != null && elementName.equalsIgnoreCase(name)) {
return e;
}
for (int i = 0; i < e.getElementCount(); i++) {
Element result = findFirstElement(e.getElement(i), name);
if (result != null) {
return result;
}
}
return null;
}
}
...@@ -52,7 +52,7 @@ public class Helper { ...@@ -52,7 +52,7 @@ public class Helper {
public static final long TEST_LIMIT; public static final long TEST_LIMIT;
static { static {
String str = System.getProperty("testLimit"); String str = System.getProperty("testLimit");
TEST_LIMIT = str != null ? Long.parseUnsignedLong(str) : 2_000L; TEST_LIMIT = str != null ? Long.parseUnsignedLong(str) : 2000L;
System.out.printf("-DtestLimit=%d%n", TEST_LIMIT); System.out.printf("-DtestLimit=%d%n", TEST_LIMIT);
} }
...@@ -116,6 +116,48 @@ public class Helper { ...@@ -116,6 +116,48 @@ public class Helper {
return size <= lag ? null : calledLog.get(size - lag - 1); return size <= lag ? null : calledLog.get(size - lag - 1);
} }
public static List<Class<?>> randomClasses(Class<?>[] classes, int size) {
List<Class<?>> result = new ArrayList<>(size);
for (int i = 0; i < size; ++i) {
result.add(classes[RNG.nextInt(classes.length)]);
}
return result;
}
public static List<Class<?>> getParams(List<Class<?>> classes,
boolean isVararg, int argsCount) {
boolean unmodifiable = true;
List<Class<?>> result = classes.subList(0,
Math.min(argsCount, (MAX_ARITY / 2) - 1));
int extra = 0;
if (argsCount >= MAX_ARITY / 2) {
result = new ArrayList<>(result);
unmodifiable = false;
extra = (int) result.stream().filter(Helper::isDoubleCost).count();
int i = result.size();
while (result.size() + extra < argsCount) {
Class<?> aClass = classes.get(i);
if (Helper.isDoubleCost(aClass)) {
++extra;
if (result.size() + extra >= argsCount) {
break;
}
}
result.add(aClass);
}
}
if (isVararg && result.size() > 0) {
if (unmodifiable) {
result = new ArrayList<>(result);
}
int last = result.size() - 1;
Class<?> aClass = result.get(last);
aClass = Array.newInstance(aClass, 2).getClass();
result.set(last, aClass);
}
return result;
}
public static MethodHandle addTrailingArgs(MethodHandle target, int nargs, public static MethodHandle addTrailingArgs(MethodHandle target, int nargs,
List<Class<?>> classes) { List<Class<?>> classes) {
int targetLen = target.type().parameterCount(); int targetLen = target.type().parameterCount();
...@@ -230,7 +272,7 @@ public class Helper { ...@@ -230,7 +272,7 @@ public class Helper {
return randomArgs(params.toArray(new Class<?>[params.size()])); return randomArgs(params.toArray(new Class<?>[params.size()]));
} }
private static Object castToWrapper(Object value, Class<?> dst) { public static Object castToWrapper(Object value, Class<?> dst) {
Object wrap = null; Object wrap = null;
if (value instanceof Number) { if (value instanceof Number) {
wrap = castToWrapperOrNull(((Number) value).longValue(), dst); wrap = castToWrapperOrNull(((Number) value).longValue(), dst);
...@@ -268,7 +310,7 @@ public class Helper { ...@@ -268,7 +310,7 @@ public class Helper {
if (dst == byte.class || dst == Byte.class) { if (dst == byte.class || dst == Byte.class) {
return (byte) (value); return (byte) (value);
} }
if (dst == boolean.class || dst == boolean.class) { if (dst == boolean.class || dst == Boolean.class) {
return ((value % 29) & 1) == 0; return ((value % 29) & 1) == 0;
} }
return null; return null;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册