OpenJDK / portola / portola
changeset 41913:8145653753c0
Merge
author | lana |
---|---|
date | Fri, 04 Nov 2016 17:52:55 +0000 |
parents | 65807d31c8e0 3b9082f87fea |
children | b09ce4c1536e |
files | jdk/src/java.base/share/native/libjava/StackFrameInfo.c jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSPrintInfo.java jdk/test/ProblemList.txt jdk/test/java/net/URLPermission/nstest/lookup.sh jdk/test/java/util/stream/bootlib/java.base/java/util/stream/ThowableHelper.java |
diffstat | 211 files changed, 20973 insertions(+), 795 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/make/mapfiles/libjava/mapfile-vers Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/make/mapfiles/libjava/mapfile-vers Fri Nov 04 17:52:55 2016 +0000 @@ -140,7 +140,6 @@ Java_java_lang_Double_doubleToRawLongBits; Java_java_lang_Float_intBitsToFloat; Java_java_lang_Float_floatToRawIntBits; - Java_java_lang_StackFrameInfo_toStackTraceElement0; Java_java_lang_StackStreamFactory_checkStackWalkModes; Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk; Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames; @@ -215,6 +214,8 @@ Java_java_lang_SecurityManager_currentLoadedClass0; Java_java_lang_SecurityManager_getClassContext; Java_java_lang_Shutdown_halt0; + Java_java_lang_StackTraceElement_initStackTraceElement; + Java_java_lang_StackTraceElement_initStackTraceElements; Java_java_lang_String_intern; Java_java_lang_StringCoding_err; Java_java_lang_StringUTF16_isBigEndian; @@ -227,7 +228,6 @@ Java_java_lang_System_setOut0; Java_java_lang_Thread_registerNatives; Java_java_lang_Throwable_fillInStackTrace; - Java_java_lang_Throwable_getStackTraceElements; Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2; Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2; Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2;
--- a/jdk/make/mapfiles/libjava/reorder-sparc Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/make/mapfiles/libjava/reorder-sparc Fri Nov 04 17:52:55 2016 +0000 @@ -78,7 +78,7 @@ text: .text%JNU_GetEnv; text: .text%Java_java_io_UnixFileSystem_checkAccess; text: .text%Java_java_lang_reflect_Array_newArray; -text: .text%Java_java_lang_Throwable_getStackTraceElements; +text: .text%Java_java_lang_StackTraceElement_initStackTraceElements; text: .text%throwFileNotFoundException; text: .text%JNU_NotifyAll; # Test LoadFrame
--- a/jdk/make/mapfiles/libjava/reorder-sparcv9 Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/make/mapfiles/libjava/reorder-sparcv9 Fri Nov 04 17:52:55 2016 +0000 @@ -74,7 +74,7 @@ text: .text%JNU_GetEnv; text: .text%Java_java_io_UnixFileSystem_checkAccess; text: .text%Java_java_lang_reflect_Array_newArray; -text: .text%Java_java_lang_Throwable_getStackTraceElements; +text: .text%Java_java_lang_StackTraceElement_initStackTraceElements; text: .text%throwFileNotFoundException: OUTPUTDIR/io_util.o; text: .text%JNU_NotifyAll; # Test LoadFrame
--- a/jdk/make/mapfiles/libjava/reorder-x86 Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/make/mapfiles/libjava/reorder-x86 Fri Nov 04 17:52:55 2016 +0000 @@ -78,7 +78,7 @@ text: .text%Java_sun_reflect_NativeMethodAccessorImpl_invoke0; text: .text%Java_java_io_FileInputStream_available; text: .text%Java_java_lang_reflect_Array_newArray; -text: .text%Java_java_lang_Throwable_getStackTraceElements; +text: .text%Java_java_lang_StackTraceElement_initStackTraceElements; text: .text%Java_java_lang_System_identityHashCode; text: .text%JNU_NotifyAll; # Test LoadFrame
--- a/jdk/src/java.base/share/classes/java/io/File.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/io/File.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2016, 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 @@ -1907,16 +1907,10 @@ throws IOException { long n = random.nextLong(); - if (n == Long.MIN_VALUE) { - n = 0; // corner case - } else { - n = Math.abs(n); - } // Use only the file name from the supplied prefix prefix = (new File(prefix)).getName(); - - String name = prefix + Long.toString(n) + suffix; + String name = prefix + Long.toUnsignedString(n) + suffix; File f = new File(dir, name); if (!name.equals(f.getName()) || f.isInvalid()) { if (System.getSecurityManager() != null)
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/Class.java Fri Nov 04 17:52:55 2016 +0000 @@ -485,7 +485,7 @@ * can be replaced by * * <pre>{@code - * clazz.getConstructor().newInstance() + * clazz.getDeclaredConstructor().newInstance() * }</pre> * * The latter sequence of calls is inferred to be able to throw
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Fri Nov 04 17:52:55 2016 +0000 @@ -222,6 +222,9 @@ // must be added *after* it. private final ClassLoader parent; + // class loader name + private final String name; + // the unnamed module for this ClassLoader private final Module unnamedModule; @@ -331,6 +334,14 @@ } private static Void checkCreateClassLoader() { + return checkCreateClassLoader(null); + } + + private static Void checkCreateClassLoader(String name) { + if (name != null && name.isEmpty()) { + throw new IllegalArgumentException("name must be non-empty or null"); + } + SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkCreateClassLoader(); @@ -338,7 +349,8 @@ return null; } - private ClassLoader(Void unused, ClassLoader parent) { + private ClassLoader(Void unused, String name, ClassLoader parent) { + this.name = name; this.parent = parent; this.unnamedModule = SharedSecrets.getJavaLangReflectModuleAccess() @@ -356,6 +368,27 @@ } /** + * Creates a new class loader of the specified name and using the + * specified parent class loader for delegation. + * + * @param name class loader name; or {@code null} if not named + * @param parent the parent class loader + * + * @throws IllegalArgumentException if the given name is empty. + * + * @throws SecurityException + * If a security manager exists and its + * {@link SecurityManager#checkCreateClassLoader()} + * method doesn't allow creation of a new class loader. + * + * @since 9 + */ + protected ClassLoader(String name, ClassLoader parent) { + this(checkCreateClassLoader(name), name, parent); + } + + + /** * Creates a new class loader using the specified parent class loader for * delegation. * @@ -375,9 +408,10 @@ * @since 1.2 */ protected ClassLoader(ClassLoader parent) { - this(checkCreateClassLoader(), parent); + this(checkCreateClassLoader(), null, parent); } + /** * Creates a new class loader using the <tt>ClassLoader</tt> returned by * the method {@link #getSystemClassLoader() @@ -394,7 +428,31 @@ * of a new class loader. */ protected ClassLoader() { - this(checkCreateClassLoader(), getSystemClassLoader()); + this(checkCreateClassLoader(), null, getSystemClassLoader()); + } + + + /** + * Returns the name of this class loader or {@code null} if + * this class loader is not named. + * + * @apiNote This method is non-final for compatibility. If this + * method is overridden, this method must return the same name + * as specified when this class loader was instantiated. + * + * @return name of this class loader; or {@code null} if + * this class loader is not named. + * + * @since 9 + */ + public String getName() { + return name; + } + + // package-private used by StackTraceElement to avoid + // calling the overrideable getName method + final String name() { + return name; } // -- Class -- @@ -1628,6 +1686,9 @@ * <a href="#builtinLoaders">platform classes</a> are visible to * the platform class loader. * + * @implNote The name of the builtin platform class loader is + * {@code "platform"}. + * * @return The platform {@code ClassLoader}. * * @throws SecurityException @@ -1681,7 +1742,8 @@ * this method during startup should take care not to cache the return * value until the system is fully initialized. * - * <p> The class path used by the built-in system class loader is determined + * <p> The name of the built-in system class loader is {@code "app"}. + * The class path used by the built-in system class loader is determined * by the system property "{@code java.class.path}" during early * initialization of the VM. If the system property is not defined, * or its value is an empty string, then there is no class path
--- a/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java Fri Nov 04 17:52:55 2016 +0000 @@ -112,11 +112,6 @@ return toStackTraceElement().toString(); } - /** - * Fill in the fields of the given StackTraceElement - */ - private native void toStackTraceElement0(StackTraceElement ste); - @Override public StackTraceElement toStackTraceElement() { StackTraceElement s = ste; @@ -124,9 +119,7 @@ synchronized (this) { s = ste; if (s == null) { - s = new StackTraceElement(); - toStackTraceElement0(s); - ste = s; + ste = s = StackTraceElement.of(this); } } }
--- a/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java Fri Nov 04 17:52:55 2016 +0000 @@ -25,7 +25,18 @@ package java.lang; +import jdk.internal.loader.BuiltinClassLoader; +import jdk.internal.misc.SharedSecrets; +import jdk.internal.misc.VM; +import jdk.internal.module.ModuleHashes; + +import java.lang.module.ModuleDescriptor.Version; +import java.lang.reflect.Layer; +import java.lang.reflect.Module; +import java.util.HashSet; import java.util.Objects; +import java.util.Optional; +import java.util.Set; /** * An element in a stack trace, as returned by {@link @@ -40,7 +51,15 @@ * @author Josh Bloch */ public final class StackTraceElement implements java.io.Serializable { - // Normally initialized by VM (public constructor added in 1.5) + // This field is set to the compacted String representation used + // by StackTraceElement::toString and stored in serial form. + // + // This field is of Object type. VM initially sets this field to + // the Class object of the declaring class to build the compacted string. + private Object classOrLoaderModuleClassName; + + // Normally initialized by VM + private String classLoaderName; private String moduleName; private String moduleVersion; private String declaringClass; @@ -72,19 +91,22 @@ */ public StackTraceElement(String declaringClass, String methodName, String fileName, int lineNumber) { - this(null, null, declaringClass, methodName, fileName, lineNumber); + this(null, null, null, declaringClass, methodName, fileName, lineNumber); } /** * Creates a stack trace element representing the specified execution * point. * + * @param classLoaderName the class loader name if the class loader of + * the class containing the execution point represented by + * the stack trace is named; otherwise {@code null} * @param moduleName the module name if the class containing the * execution point represented by the stack trace is in a named - * module; can be {@code null} + * module; otherwise {@code null} * @param moduleVersion the module version if the class containing the * execution point represented by the stack trace is in a named - * module that has a version; can be {@code null} + * module that has a version; otherwise {@code null} * @param declaringClass the fully qualified name of the class containing * the execution point represented by the stack trace element * @param methodName the name of the method containing the execution point @@ -97,26 +119,30 @@ * a negative number if this information is unavailable. A value * of -2 indicates that the method containing the execution point * is a native method + * * @throws NullPointerException if {@code declaringClass} is {@code null} * or {@code methodName} is {@code null} + * * @since 9 */ - public StackTraceElement(String moduleName, String moduleVersion, + public StackTraceElement(String classLoaderName, + String moduleName, String moduleVersion, String declaringClass, String methodName, String fileName, int lineNumber) { - this.moduleName = moduleName; - this.moduleVersion = moduleVersion; - this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null"); - this.methodName = Objects.requireNonNull(methodName, "Method name is null"); - this.fileName = fileName; - this.lineNumber = lineNumber; + this.classLoaderName = classLoaderName; + this.moduleName = moduleName; + this.moduleVersion = moduleVersion; + this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null"); + this.methodName = Objects.requireNonNull(methodName, "Method name is null"); + this.fileName = fileName; + this.lineNumber = lineNumber; } - - /** - * Creates an empty stack frame element to be filled in by Throwable. + /* + * Private constructor for the factory methods to create StackTraceElement + * for Throwable and StackFrameInfo */ - StackTraceElement() { } + private StackTraceElement() {} /** * Returns the name of the source file containing the execution point @@ -178,6 +204,21 @@ } /** + * Returns the name of the class loader of the class containing the + * execution point represented by this stack trace element. + * + * @return the name of the class loader of the class containing the execution + * point represented by this stack trace element; {@code null} + * if the class loader is not named. + * + * @since 9 + * @see java.lang.ClassLoader#getName() + */ + public String getClassLoaderName() { + return classLoaderName; + } + + /** * Returns the fully qualified name of the class containing the * execution point represented by this stack trace element. * @@ -220,38 +261,83 @@ * examples may be regarded as typical: * <ul> * <li> - * {@code "MyClass.mash(my.module@9.0/MyClass.java:101)"} - Here, - * {@code "MyClass"} is the <i>fully-qualified name</i> of the class - * containing the execution point represented by this stack trace element, - * {@code "mash"} is the name of the method containing the execution - * point, {@code "my.module"} is the module name, {@code "9.0"} is the - * module version, and {@code "101"} is the line number of the source - * line containing the execution point. + * "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Main.java:101)}" + * - See the description below. + * </li> * <li> - * {@code "MyClass.mash(my.module@9.0/MyClass.java)"} - As above, but the - * line number is unavailable. + * "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Main.java)}" + * - The line number is unavailable. + * </li> * <li> - * {@code "MyClass.mash(my.module@9.0/Unknown Source)"} - As above, but - * neither the file name nor the line number are available. + * "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Unknown Source)}" + * - Neither the file name nor the line number is available. + * </li> * <li> - * {@code "MyClass.mash(my.module@9.0/Native Method)"} - As above, but - * neither the file name nor the line number are available, and the - * method containing the execution point is known to be a native method. + * "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Native Method)}" + * - The method containing the execution point is a native method. + * </li> + * <li> + * "{@code com.foo.loader//com.foo.bar.App.run(App.java:12)}" + * - The class of the execution point is defined in the unnamed module of + * the class loader named {@code com.foo.loader}. + * </li> + * <li> + * "{@code acme@2.1/org.acme.Lib.test(Lib.java:80)}" + * - The class of the execution point is defined in {@code acme} module + * loaded by by a built-in class loader such as the application class loader. + * </li> + * <li> + * "{@code MyClass.mash(MyClass.java:9)}" + * - {@code MyClass} class is on the application class path. + * </li> * </ul> - * If the execution point is not in a named module, {@code "my.module@9.0/"} - * will be omitted from the above. + * + * <p> The first example shows a stack trace element consisting of + * three elements, each separated by {@code "/"} followed with + * the source file name and the line number of the source line + * containing the execution point. + * + * The first element "{@code com.foo.loader}" is + * the name of the class loader. The second element "{@code foo@9.0}" + * is the module name and version. The third element is the method + * containing the execution point; "{@code com.foo.Main"}" is the + * fully-qualified class name and "{@code run}" is the name of the method. + * "{@code Main.java}" is the source file name and "{@code 101}" is + * the line number. + * + * <p> If a class is defined in an <em>unnamed module</em> + * then the second element is omitted as shown in + * "{@code com.foo.loader//com.foo.bar.App.run(App.java:12)}". + * + * If the class loader is a <a href="ClassLoader.html#builtinLoaders"> + * built-in class loader</a> or is not named then the first element + * and its following {@code "/"} are omitted as shown in + * "{@code acme@2.1/org.acme.Lib.test(Lib.java:80)}". + * If the first element is omitted and the module is an unnamed module, + * the second element and its following {@code "/"} are also omitted + * as shown in "{@code MyClass.mash(MyClass.java:9)}". * * @see Throwable#printStackTrace() */ public String toString() { - String mid = ""; - if (moduleName != null) { - mid = moduleName; - if (moduleVersion != null) - mid += "@" + moduleVersion; - mid += "/"; + String s = buildLoaderModuleClassName(); + if (s == null) { + // all elements will be included + s = ""; + if (classLoaderName != null && !classLoaderName.isEmpty()) { + s += classLoaderName + "/"; + } + if (moduleName != null && !moduleName.isEmpty()) { + s += moduleName; + + if (moduleVersion != null && !moduleVersion.isEmpty()) { + s += "@" + moduleVersion; + } + } + s = s.isEmpty() ? declaringClass : s + "/" + declaringClass; } - return getClassName() + "." + methodName + "(" + mid + + + return s + "." + methodName + "(" + (isNativeMethod() ? "Native Method)" : (fileName != null && lineNumber >= 0 ? fileName + ":" + lineNumber + ")" : @@ -264,12 +350,14 @@ * point as this instance. Two stack trace elements {@code a} and * {@code b} are equal if and only if: * <pre>{@code - * equals(a.getFileName(), b.getFileName()) && - * a.getLineNumber() == b.getLineNumber()) && + * equals(a.getClassLoaderName(), b.getClassLoaderName()) && * equals(a.getModuleName(), b.getModuleName()) && * equals(a.getModuleVersion(), b.getModuleVersion()) && * equals(a.getClassName(), b.getClassName()) && * equals(a.getMethodName(), b.getMethodName()) + * equals(a.getFileName(), b.getFileName()) && + * a.getLineNumber() == b.getLineNumber() + * * }</pre> * where {@code equals} has the semantics of {@link * java.util.Objects#equals(Object, Object) Objects.equals}. @@ -285,9 +373,10 @@ if (!(obj instanceof StackTraceElement)) return false; StackTraceElement e = (StackTraceElement)obj; - return e.declaringClass.equals(declaringClass) && + return Objects.equals(classLoaderName, e.classLoaderName) && Objects.equals(moduleName, e.moduleName) && Objects.equals(moduleVersion, e.moduleVersion) && + e.declaringClass.equals(declaringClass) && e.lineNumber == lineNumber && Objects.equals(methodName, e.methodName) && Objects.equals(fileName, e.fileName); @@ -298,6 +387,7 @@ */ public int hashCode() { int result = 31*declaringClass.hashCode() + methodName.hashCode(); + result = 31*result + Objects.hashCode(classLoaderName); result = 31*result + Objects.hashCode(moduleName); result = 31*result + Objects.hashCode(moduleVersion); result = 31*result + Objects.hashCode(fileName); @@ -305,5 +395,157 @@ return result; } + + /** + * Build the compacted String representation to be returned by + * toString method from the declaring Class object. + */ + synchronized String buildLoaderModuleClassName() { + if (classOrLoaderModuleClassName == null) + return null; + + if (classOrLoaderModuleClassName instanceof Class) { + Class<?> cls = (Class<?>)classOrLoaderModuleClassName; + classOrLoaderModuleClassName = toLoaderModuleClassName(cls); + } + return (String)classOrLoaderModuleClassName; + } + + /** + * Returns <loader>/<module>/<fully-qualified-classname> string + * representation of the given class. + * <p> + * If the module is a non-upgradeable JDK module then omit + * its version string. + * <p> + * If the loader has no name, or if the loader is one of the built-in + * loaders (`boot`, `platform`, or `app`) then drop the first element + * (`<loader>/`). + * <p> + * If the first element has been dropped and the module is unnamed + * then drop the second element (`<module>/`). + * <p> + * If the first element is not dropped and the module is unnamed + * then drop `<module>`. + */ + private static String toLoaderModuleClassName(Class<?> cls) { + ClassLoader loader = cls.getClassLoader0(); + Module m = cls.getModule(); + + // First element - class loader name + // Call package-private ClassLoader::name method + String s = ""; + if (loader != null && loader.name() != null && + !(loader instanceof BuiltinClassLoader)) { + s = loader.name() + "/"; + } + + // Second element - module name and version + if (m != null && m.isNamed()) { + s += m.getName(); + // Include version if it is a user module or upgradeable module + // + // If it is JDK non-upgradeable module which is recorded + // in the hashes in java.base, omit the version. + if (!isHashedInJavaBase(m)) { + Optional<Version> ov = m.getDescriptor().version(); + if (ov.isPresent()) { + String version = "@" + ov.get().toString(); + s += version; + } + } + } + + // fully-qualified class name + return s.isEmpty() ? cls.getName() : s + "/" + cls.getName(); + } + + /** + * Returns true if the module is hashed with java.base. + * <p> + * This method returns false when running on the exploded image + * since JDK modules are not hashed. They have no Version attribute + * and so "@<version>" part will be omitted anyway. + */ + private static boolean isHashedInJavaBase(Module m) { + // return true if module system is not initialized as the code + // must be in java.base + if (!VM.isModuleSystemInited()) + return true; + + return Layer.boot() == m.getLayer() && HashedModules.contains(m); + } + + /* + * Finds JDK non-upgradeable modules, i.e. the modules that are + * included in the hashes in java.base. + */ + private static class HashedModules { + static Set<String> HASHED_MODULES = hashedModules(); + + static Set<String> hashedModules() { + Module javaBase = Layer.boot().findModule("java.base").get(); + Optional<ModuleHashes> ohashes = + SharedSecrets.getJavaLangModuleAccess() + .hashes(javaBase.getDescriptor()); + + if (ohashes.isPresent()) { + Set<String> names = new HashSet<>(ohashes.get().names()); + names.add("java.base"); + return names; + } + + return Set.of(); + } + + static boolean contains(Module m) { + return HASHED_MODULES.contains(m.getName()); + } + } + + + /* + * Returns an array of StackTraceElements of the given depth + * filled from the backtrace of a given Throwable. + */ + static StackTraceElement[] of(Throwable x, int depth) { + StackTraceElement[] stackTrace = new StackTraceElement[depth]; + for (int i = 0; i < depth; i++) { + stackTrace[i] = new StackTraceElement(); + } + + // VM to fill in StackTraceElement + initStackTraceElements(stackTrace, x); + + // ensure the proper StackTraceElement initialization + for (StackTraceElement ste : stackTrace) { + ste.buildLoaderModuleClassName(); + } + return stackTrace; + } + + /* + * Returns a StackTraceElement from a given StackFrameInfo. + */ + static StackTraceElement of(StackFrameInfo sfi) { + StackTraceElement ste = new StackTraceElement(); + initStackTraceElement(ste, sfi); + + ste.buildLoaderModuleClassName(); + return ste; + } + + /* + * Sets the given stack trace elements with the backtrace + * of the given Throwable. + */ + private static native void initStackTraceElements(StackTraceElement[] elements, + Throwable x); + /* + * Sets the given stack trace element with the given StackFrameInfo + */ + private static native void initStackTraceElement(StackTraceElement element, + StackFrameInfo sfi); + private static final long serialVersionUID = 6992337162326171013L; }
--- a/jdk/src/java.base/share/classes/java/lang/Throwable.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/Throwable.java Fri Nov 04 17:52:55 2016 +0000 @@ -24,7 +24,6 @@ */ package java.lang; -import jdk.internal.misc.VM; import java.io.*; import java.util.*; @@ -826,11 +825,7 @@ // backtrace if this is the first call to this method if (stackTrace == UNASSIGNED_STACK || (stackTrace == null && backtrace != null) /* Out of protocol state */) { - stackTrace = new StackTraceElement[depth]; - for (int i = 0; i < depth; i++) { - stackTrace[i] = new StackTraceElement(); - } - getStackTraceElements(stackTrace); + stackTrace = StackTraceElement.of(this, depth); } else if (stackTrace == null) { return UNASSIGNED_STACK; } @@ -882,13 +877,6 @@ } /** - * Gets the stack trace elements. - * @param elements - * @throws IndexOutOfBoundsException if {@code elements.length != depth } - */ - private native void getStackTraceElements(StackTraceElement[] elements); - - /** * Reads a {@code Throwable} from a stream, enforcing * well-formedness constraints on fields. Null entries and * self-pointers are not allowed in the list of {@code
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Fri Nov 04 17:52:55 2016 +0000 @@ -110,19 +110,19 @@ if (security != null) { security.checkCreateClassLoader(); } - ucp = new URLClassPath(urls); + this.ucp = new URLClassPath(urls); this.acc = AccessController.getContext(); } - URLClassLoader(URL[] urls, ClassLoader parent, + URLClassLoader(String name, URL[] urls, ClassLoader parent, AccessControlContext acc) { - super(parent); + super(name, parent); // this is to make the stack depth consistent with 1.1 SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkCreateClassLoader(); } - ucp = new URLClassPath(urls); + this.ucp = new URLClassPath(urls); this.acc = acc; } @@ -154,7 +154,7 @@ if (security != null) { security.checkCreateClassLoader(); } - ucp = new URLClassPath(urls); + this.ucp = new URLClassPath(urls); this.acc = AccessController.getContext(); } @@ -165,7 +165,7 @@ if (security != null) { security.checkCreateClassLoader(); } - ucp = new URLClassPath(urls); + this.ucp = new URLClassPath(urls); this.acc = acc; } @@ -198,8 +198,76 @@ if (security != null) { security.checkCreateClassLoader(); } - ucp = new URLClassPath(urls, factory); - acc = AccessController.getContext(); + this.ucp = new URLClassPath(urls, factory); + this.acc = AccessController.getContext(); + } + + + /** + * Constructs a new named {@code URLClassLoader} for the specified URLs. + * The URLs will be searched in the order specified for classes + * and resources after first searching in the specified parent class loader. + * Any URL that ends with a '/' is assumed to refer to a directory. + * Otherwise, the URL is assumed to refer to a JAR file which will be + * downloaded and opened as needed. + * + * @param name class loader name; or {@code null} if not named + * @param urls the URLs from which to load classes and resources + * @param parent the parent class loader for delegation + * + * @throws IllegalArgumentException if the given name is empty. + * @throws NullPointerException if {@code urls} is {@code null}. + * + * @throws SecurityException if a security manager exists and its + * {@link SecurityManager#checkCreateClassLoader()} method doesn't + * allow creation of a class loader. + * + * @since 9 + */ + public URLClassLoader(String name, + URL[] urls, + ClassLoader parent) { + super(name, parent); + // this is to make the stack depth consistent with 1.1 + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkCreateClassLoader(); + } + this.ucp = new URLClassPath(urls); + this.acc = AccessController.getContext(); + } + + /** + * Constructs a new named {@code URLClassLoader} for the specified URLs, + * parent class loader, and URLStreamHandlerFactory. + * The parent argument will be used as the parent class loader for delegation. + * The factory argument will be used as the stream handler factory to + * obtain protocol handlers when creating new jar URLs. + * + * @param name class loader name; or {@code null} if not named + * @param urls the URLs from which to load classes and resources + * @param parent the parent class loader for delegation + * @param factory the URLStreamHandlerFactory to use when creating URLs + * + * @throws IllegalArgumentException if the given name is empty. + * @throws NullPointerException if {@code urls} is {@code null}. + * + * @throws SecurityException if a security manager exists and its + * {@code checkCreateClassLoader} method doesn't allow + * creation of a class loader. + * + * @since 9 + */ + public URLClassLoader(String name, URL[] urls, ClassLoader parent, + URLStreamHandlerFactory factory) { + super(name, parent); + // this is to make the stack depth consistent with 1.1 + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkCreateClassLoader(); + } + this.ucp = new URLClassPath(urls, factory); + this.acc = AccessController.getContext(); } /* A map (used as a set) to keep track of closeable local resources @@ -735,7 +803,7 @@ URLClassLoader ucl = AccessController.doPrivileged( new PrivilegedAction<>() { public URLClassLoader run() { - return new FactoryURLClassLoader(urls, parent, acc); + return new FactoryURLClassLoader(null, urls, parent, acc); } }); return ucl; @@ -785,9 +853,9 @@ ClassLoader.registerAsParallelCapable(); } - FactoryURLClassLoader(URL[] urls, ClassLoader parent, + FactoryURLClassLoader(String name, URL[] urls, ClassLoader parent, AccessControlContext acc) { - super(urls, parent, acc); + super(name, urls, parent, acc); } FactoryURLClassLoader(URL[] urls, AccessControlContext acc) {
--- a/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,8 +55,8 @@ private static final SecureRandom random = new SecureRandom(); private static Path generatePath(String prefix, String suffix, Path dir) { long n = random.nextLong(); - n = (n == Long.MIN_VALUE) ? 0 : Math.abs(n); - Path name = dir.getFileSystem().getPath(prefix + Long.toString(n) + suffix); + String s = prefix + Long.toUnsignedString(n) + suffix; + Path name = dir.getFileSystem().getPath(s); // the generated name should be a simple file name if (name.getParent() != null) throw new IllegalArgumentException("Invalid prefix or suffix");
--- a/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java Fri Nov 04 17:52:55 2016 +0000 @@ -25,8 +25,6 @@ package java.security; -import java.net.URL; -import java.util.ArrayList; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; @@ -114,6 +112,30 @@ } /** + * Creates a new {@code SecureClassLoader} of the specified name and + * using the specified parent class loader for delegation. + * + * @param name class loader name; or {@code null} if not named + * @param parent the parent class loader + * + * @throws IllegalArgumentException if the given name is empty. + * + * @throws SecurityException if a security manager exists and its + * {@link SecurityManager#checkCreateClassLoader()} method + * doesn't allow creation of a class loader. + * + * @since 9 + */ + protected SecureClassLoader(String name, ClassLoader parent) { + super(name, parent); + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkCreateClassLoader(); + } + initialized = true; + } + + /** * Converts an array of bytes into an instance of class Class, * with an optional CodeSource. Before the * class can be used it must be resolved.
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Fri Nov 04 17:52:55 2016 +0000 @@ -145,9 +145,9 @@ /** * Create a new instance. */ - BuiltinClassLoader(BuiltinClassLoader parent, URLClassPath ucp) { + BuiltinClassLoader(String name, BuiltinClassLoader parent, URLClassPath ucp) { // ensure getParent() returns null when the parent is the boot loader - super(parent == null || parent == ClassLoaders.bootLoader() ? null : parent); + super(name, parent == null || parent == ClassLoaders.bootLoader() ? null : parent); this.parent = parent; this.ucp = ucp;
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java Fri Nov 04 17:52:55 2016 +0000 @@ -118,7 +118,7 @@ */ private static class BootClassLoader extends BuiltinClassLoader { BootClassLoader(URLClassPath bcp) { - super(null, bcp); + super(null, null, bcp); } @Override @@ -138,7 +138,7 @@ } PlatformClassLoader(BootClassLoader parent) { - super(parent, null); + super("platform", parent, null); } /** @@ -165,7 +165,7 @@ final URLClassPath ucp; AppClassLoader(PlatformClassLoader parent, URLClassPath ucp) { - super(parent, ucp); + super("app", parent, ucp); this.ucp = ucp; }
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Fri Nov 04 17:52:55 2016 +0000 @@ -253,20 +253,20 @@ } private static String toSourceString(char c) { - StringBuilder sb = new StringBuilder(); - sb.append("'"); + StringBuilder sb = new StringBuilder(4); + sb.append('\''); if (c == '\'') sb.append("\\'"); else sb.append(c); - sb.append("'"); - return sb.toString(); + return sb.append('\'') + .toString(); } private static String toSourceString(long ell) { - return (Math.abs(ell) <= Integer.MAX_VALUE) ? - String.valueOf(ell) : - (String.valueOf(ell) + "L"); + String str = String.valueOf(ell); + return (ell < Integer.MIN_VALUE || ell > Integer.MAX_VALUE) + ? (str + 'L') : str; } /** @@ -278,10 +278,7 @@ sb.append('"'); // Escape embedded quote characters, if present, but don't do // anything more heroic. - if (s.indexOf('"') != -1) { - s = s.replace("\"", "\\\""); - } - sb.append(s); + sb.append(s.replace("\"", "\\\"")); sb.append('"'); return sb.toString(); }
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Fri Nov 04 17:52:55 2016 +0000 @@ -1715,12 +1715,17 @@ synchronized void fatal(byte description, String diagnostic) throws SSLException { - fatal(description, diagnostic, null); + fatal(description, diagnostic, null, false); } synchronized void fatal(byte description, Throwable cause) throws SSLException { - fatal(description, null, cause); + fatal(description, null, cause, false); + } + + synchronized void fatal(byte description, String diagnostic, + Throwable cause) throws SSLException { + fatal(description, diagnostic, cause, false); } /* @@ -1732,12 +1737,12 @@ * levels which then call here. This code needs to determine * if one of the lower levels has already started the process. * - * We won't worry about Error's, if we have one of those, + * We won't worry about Errors, if we have one of those, * we're in worse trouble. Note: the networking code doesn't * deal with Errors either. */ synchronized void fatal(byte description, String diagnostic, - Throwable cause) throws SSLException { + Throwable cause, boolean recvFatalAlert) throws SSLException { /* * If we have no further information, make a general-purpose @@ -1798,10 +1803,11 @@ } /* - * If we haven't even started handshaking yet, no need - * to generate the fatal close alert. + * If we haven't even started handshaking yet, or we are the + * recipient of a fatal alert, no need to generate a fatal close + * alert. */ - if (oldState != cs_START) { + if (oldState != cs_START && !recvFatalAlert) { sendAlert(Alerts.alert_fatal, description); } @@ -1841,10 +1847,6 @@ byte level = fragment.get(); byte description = fragment.get(); - if (description == -1) { // check for short message - fatal(Alerts.alert_illegal_parameter, "Short alert message"); - } - if (debug != null && (Debug.isOn("record") || Debug.isOn("handshake"))) { synchronized (System.out) { @@ -1862,7 +1864,9 @@ } if (level == Alerts.alert_warning) { - if (description == Alerts.alert_close_notify) { + if (description == -1) { // check for short message + fatal(Alerts.alert_illegal_parameter, "Short alert message"); + } else if (description == Alerts.alert_close_notify) { if (connectionState == cs_HANDSHAKE) { fatal(Alerts.alert_unexpected_message, "Received close_notify during handshake"); @@ -1885,10 +1889,14 @@ } else { // fatal or unknown level String reason = "Received fatal alert: " + Alerts.alertDescription(description); - if (closeReason == null) { - closeReason = Alerts.getSSLException(description, reason); - } - fatal(Alerts.alert_unexpected_message, reason); + + // The inbound and outbound queues will be closed as part of + // the call to fatal. The handhaker to needs to be set to null + // so subsequent calls to getHandshakeStatus will return + // NOT_HANDSHAKING. + handshaker = null; + Throwable cause = Alerts.getSSLException(description, reason); + fatal(description, null, cause, true); } }
--- a/jdk/src/java.base/share/native/include/jvm.h Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/native/include/jvm.h Fri Nov 04 17:52:55 2016 +0000 @@ -165,14 +165,24 @@ JNIEXPORT jboolean JNICALL JVM_IsSupportedJNIVersion(jint version); +JNIEXPORT jobjectArray JNICALL +JVM_GetVmArguments(JNIEnv *env); + + /* * java.lang.Throwable */ JNIEXPORT void JNICALL JVM_FillInStackTrace(JNIEnv *env, jobject throwable); +/* + * java.lang.StackTraceElement + */ JNIEXPORT void JNICALL -JVM_GetStackTraceElements(JNIEnv *env, jobject throwable, jobjectArray elements); +JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable); + +JNIEXPORT void JNICALL +JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo); /* * java.lang.StackWalker @@ -194,12 +204,6 @@ jint frame_count, jint start_index, jobjectArray frames); -JNIEXPORT void JNICALL -JVM_ToStackTraceElement(JNIEnv* env, jobject frame, jobject stackElement); - -JNIEXPORT jobjectArray JNICALL -JVM_GetVmArguments(JNIEnv *env); - /* * java.lang.Thread */
--- a/jdk/src/java.base/share/native/libjava/StackFrameInfo.c Fri Nov 04 17:24:24 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * Implementation of class StackFrameInfo - */ - -#include <stdio.h> -#include <signal.h> - -#include "jni.h" -#include "jvm.h" - -#include "java_lang_StackFrameInfo.h" - - -/* - * Class: java_lang_StackFrameInfo - * Method: toStackTraceElement0 - * Signature: (Ljava/lang/StackTraceElement;)V - */ -JNIEXPORT void JNICALL Java_java_lang_StackFrameInfo_toStackTraceElement0 - (JNIEnv *env, jobject stackframeinfo, jobject stacktraceinfo) { - JVM_ToStackTraceElement(env, stackframeinfo, stacktraceinfo); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/native/libjava/StackTraceElement.c Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include <stdio.h> +#include <signal.h> + +#include "jni.h" +#include "jvm.h" + +#include "java_lang_StackTraceElement.h" + +JNIEXPORT void JNICALL Java_java_lang_StackTraceElement_initStackTraceElement + (JNIEnv *env, jobject dummy, jobject element, jobject stackframeinfo) { + JVM_InitStackTraceElement(env, element, stackframeinfo); +} + +JNIEXPORT void JNICALL Java_java_lang_StackTraceElement_initStackTraceElements + (JNIEnv *env, jobject dummy, jobjectArray elements, jobject throwable) +{ + JVM_InitStackTraceElementArray(env, elements, throwable); +}
--- a/jdk/src/java.base/share/native/libjava/Throwable.c Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.base/share/native/libjava/Throwable.c Fri Nov 04 17:52:55 2016 +0000 @@ -49,10 +49,3 @@ JVM_FillInStackTrace(env, throwable); return throwable; } - -JNIEXPORT void JNICALL -Java_java_lang_Throwable_getStackTraceElements(JNIEnv *env, - jobject throwable, jobjectArray elements) -{ - JVM_GetStackTraceElements(env, throwable, elements); -}
--- a/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXSurfaceData.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXSurfaceData.java Fri Nov 04 17:52:55 2016 +0000 @@ -74,8 +74,13 @@ this.fGraphicsStatesInt = this.fGraphicsStates.asIntBuffer(); this.fGraphicsStatesFloat = this.fGraphicsStates.asFloatBuffer(); this.fGraphicsStatesLong = this.fGraphicsStates.asLongBuffer(); - this.fGraphicsStatesObject = new Object[6]; // clip coordinates + clip types + texture paint image + stroke dash - // array + font + font paint + this.fGraphicsStatesObject = new Object[8]; // clip coordinates + + // clip types + + // texture paint image + + // stroke dash array + + // font + font paint + + // linear/radial gradient color + + // linear/radial gradient fractions // NOTE: All access to the DrawingQueue comes through this OSXSurfaceData instance. Therefore // every instance method of OSXSurfaceData that accesses the fDrawingQueue is synchronized. @@ -292,10 +297,10 @@ @Native static final int kHintsFractionalMetricsIndex = 46; @Native static final int kHintsRenderingIndex = 47; @Native static final int kHintsInterpolationIndex = 48; - // live resizing info - @Native static final int kCanDrawDuringLiveResizeIndex = 49; + //gradient info + @Native static final int kRadiusIndex = 49; - @Native static final int kSizeOfParameters = kCanDrawDuringLiveResizeIndex + 1; + @Native static final int kSizeOfParameters = kRadiusIndex + 1; // for objectParameters @Native static final int kClipCoordinatesIndex = 0; @@ -304,6 +309,8 @@ @Native static final int kStrokeDashArrayIndex = 3; @Native static final int kFontIndex = 4; @Native static final int kFontPaintIndex = 5; + @Native static final int kColorArrayIndex = 6; + @Native static final int kFractionsArrayIndex = 7; // possible state changes @Native static final int kBoundsChangedBit = 1 << 0; @@ -329,6 +336,8 @@ @Native static final int kColorSystem = 1; @Native static final int kColorGradient = 2; @Native static final int kColorTexture = 3; + @Native static final int kColorLinearGradient = 4; + @Native static final int kColorRadialGradient = 5; // possible gradient color states @Native static final int kColorNonCyclic = 0; @@ -522,6 +531,28 @@ int lastPaintIndex = 0; BufferedImage texturePaintImage = null; + void setGradientViaRasterPath(SunGraphics2D sg2d) { + if ((this.fGraphicsStatesInt.get(kColorStateIndex) != kColorTexture) || (lastPaint != sg2d.paint) || ((this.fChangeFlag & kBoundsChangedBit) != 0)) { + PaintContext context = sg2d.paint.createContext(sg2d.getDeviceColorModel(), userBounds, userBounds, sIdentityMatrix, sg2d.getRenderingHints()); + WritableRaster raster = (WritableRaster) (context.getRaster(userBounds.x, userBounds.y, userBounds.width, userBounds.height)); + ColorModel cm = context.getColorModel(); + texturePaintImage = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null); + + this.fGraphicsStatesInt.put(kColorStateIndex, kColorTexture); + this.fGraphicsStatesInt.put(kColorWidthIndex, texturePaintImage.getWidth()); + this.fGraphicsStatesInt.put(kColorHeightIndex, texturePaintImage.getHeight()); + this.fGraphicsStatesFloat.put(kColortxIndex, (float) userBounds.getX()); + this.fGraphicsStatesFloat.put(kColortyIndex, (float) userBounds.getY()); + this.fGraphicsStatesFloat.put(kColorsxIndex, 1.0f); + this.fGraphicsStatesFloat.put(kColorsyIndex, 1.0f); + this.fGraphicsStatesObject[kTextureImageIndex] = OSXOffScreenSurfaceData.createNewSurface(texturePaintImage); + + this.fChangeFlag = (this.fChangeFlag | kColorChangedBit); + } else { + this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); + } + } + void setupPaint(SunGraphics2D sg2d, int x, int y, int w, int h) { if (sg2d.paint instanceof SystemColor) { SystemColor color = (SystemColor) sg2d.paint; @@ -567,6 +598,75 @@ } else { this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); } + } else if (sg2d.paint instanceof LinearGradientPaint) { + LinearGradientPaint color = (LinearGradientPaint) sg2d.paint; + if (color.getCycleMethod() == LinearGradientPaint.CycleMethod.NO_CYCLE) { + if ((this.fGraphicsStatesInt.get(kColorStateIndex) != kColorLinearGradient) || (lastPaint != sg2d.paint)) { + + this.fGraphicsStatesInt.put(kColorStateIndex, kColorLinearGradient); + int numColor = color.getColors().length; + int colorArray[] = new int[numColor]; + for (int i = 0; i < numColor; i++) { + colorArray[i] = color.getColors()[i].getRGB(); + } + this.fGraphicsStatesObject[kColorArrayIndex] = colorArray; + + int numFractions = color.getFractions().length; + float fractionArray[] = new float[numFractions]; + for (int i = 0; i < numFractions; i++) { + fractionArray[i] = color.getFractions()[i]; + } + this.fGraphicsStatesObject[kFractionsArrayIndex] = color.getFractions(); + + Point2D p = color.getStartPoint(); + this.fGraphicsStatesFloat.put(kColorx1Index, (float) p.getX()); + this.fGraphicsStatesFloat.put(kColory1Index, (float) p.getY()); + p = color.getEndPoint(); + this.fGraphicsStatesFloat.put(kColorx2Index, (float) p.getX()); + this.fGraphicsStatesFloat.put(kColory2Index, (float) p.getY()); + + this.fChangeFlag = (this.fChangeFlag | kColorChangedBit); + } else { + this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); + } + } else { + setGradientViaRasterPath(sg2d); + } + } else if (sg2d.paint instanceof RadialGradientPaint) { + RadialGradientPaint color = (RadialGradientPaint) sg2d.paint; + if (color.getCycleMethod() == RadialGradientPaint.CycleMethod.NO_CYCLE) { + if ((this.fGraphicsStatesInt.get(kColorStateIndex) != kColorRadialGradient) || (lastPaint != sg2d.paint)) { + + this.fGraphicsStatesInt.put(kColorStateIndex, kColorRadialGradient); + int numColor = color.getColors().length; + int colorArray[] = new int[numColor]; + for (int i = 0; i < numColor; i++) { + colorArray[i] = color.getColors()[i].getRGB(); + } + this.fGraphicsStatesObject[kColorArrayIndex] = colorArray; + + int numStops = color.getFractions().length; + float stopsArray[] = new float[numStops]; + for (int i = 0; i < numStops; i++) { + stopsArray[i] = color.getFractions()[i]; + } + this.fGraphicsStatesObject[kFractionsArrayIndex] = color.getFractions(); + + Point2D p = color.getFocusPoint(); + this.fGraphicsStatesFloat.put(kColorx1Index, (float) p.getX()); + this.fGraphicsStatesFloat.put(kColory1Index, (float) p.getY()); + p = color.getCenterPoint(); + this.fGraphicsStatesFloat.put(kColorx2Index, (float) p.getX()); + this.fGraphicsStatesFloat.put(kColory2Index, (float) p.getY()); + this.fGraphicsStatesFloat.put(kRadiusIndex, color.getRadius()); + + this.fChangeFlag = (this.fChangeFlag | kColorChangedBit); + } else { + this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); + } + } else { + setGradientViaRasterPath(sg2d); + } } else if (sg2d.paint instanceof TexturePaint) { if ((this.fGraphicsStatesInt.get(kColorStateIndex) != kColorTexture) || (lastPaint != sg2d.paint)) { TexturePaint color = (TexturePaint) sg2d.paint; @@ -587,27 +687,7 @@ this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); } } else { - if ((this.fGraphicsStatesInt.get(kColorStateIndex) != kColorTexture) || (lastPaint != sg2d.paint) || ((this.fChangeFlag & kBoundsChangedBit) != 0)) { - PaintContext context = sg2d.paint.createContext(sg2d.getDeviceColorModel(), userBounds, userBounds, sIdentityMatrix, sg2d.getRenderingHints()); - WritableRaster raster = (WritableRaster) (context.getRaster(userBounds.x, userBounds.y, userBounds.width, userBounds.height)); - ColorModel cm = context.getColorModel(); - texturePaintImage = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null); - - this.fGraphicsStatesInt.put(kColorStateIndex, kColorTexture); - this.fGraphicsStatesInt.put(kColorWidthIndex, texturePaintImage.getWidth()); - this.fGraphicsStatesInt.put(kColorHeightIndex, texturePaintImage.getHeight()); - this.fGraphicsStatesFloat.put(kColortxIndex, (float) userBounds.getX()); - this.fGraphicsStatesFloat.put(kColortyIndex, (float) userBounds.getY()); - this.fGraphicsStatesFloat.put(kColorsxIndex, 1.0f); - this.fGraphicsStatesFloat.put(kColorsyIndex, 1.0f); - this.fGraphicsStatesObject[kTextureImageIndex] = sun.awt.image.BufImgSurfaceData.createData(texturePaintImage); - - context.dispose(); - - this.fChangeFlag = (this.fChangeFlag | kColorChangedBit); - } else { - this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); - } + setGradientViaRasterPath(sg2d); } lastPaint = sg2d.paint; }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java Fri Nov 04 17:52:55 2016 +0000 @@ -178,12 +178,6 @@ return; } - // See if this has an NSPrintInfo in it. - NSPrintInfo nsPrintInfo = (NSPrintInfo)attributes.get(NSPrintInfo.class); - if (nsPrintInfo != null) { - fNSPrintInfo = nsPrintInfo.getValue(); - } - PageRanges pageRangesAttr = (PageRanges)attributes.get(PageRanges.class); if (isSupportedValue(pageRangesAttr, attributes)) { SunPageSelection rangeSelect = (SunPageSelection)attributes.get(SunPageSelection.class); @@ -563,8 +557,11 @@ @Override protected void finalize() { - if (fNSPrintInfo != -1) { - dispose(fNSPrintInfo); + synchronized (fNSPrintInfoLock) { + if (fNSPrintInfo != -1) { + dispose(fNSPrintInfo); + } + fNSPrintInfo = -1; } }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSPrintInfo.java Fri Nov 04 17:24:24 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2011, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.lwawt.macosx; - - -import java.io.*; -import javax.print.attribute.*; - -@SuppressWarnings("serial") // JDK implementation class -public final class NSPrintInfo implements PrintJobAttribute, PrintRequestAttribute, Serializable, Cloneable { - - private long fNSPrintInfo; - - public NSPrintInfo(long nsPrintInfo) { - fNSPrintInfo = nsPrintInfo; - } - - public long getValue() { - return fNSPrintInfo; - } - - public boolean equals(Object object) { - return (object != null && object instanceof NSPrintInfo && fNSPrintInfo == ((NSPrintInfo)object).fNSPrintInfo); - } - - public int hashCode() { - return (int)fNSPrintInfo; - } - - public String toString() { - return "" + fNSPrintInfo; - } - - public Class<? extends Attribute> getCategory() { - return NSPrintInfo.class; - } - - public String getName() { - return "nsPrintInfo"; - } -}
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/QuartzSurfaceData.h Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/QuartzSurfaceData.h Fri Nov 04 17:52:55 2016 +0000 @@ -44,6 +44,8 @@ SD_Fill, SD_EOFill, SD_Shade, + SD_LinearGradient, + SD_RadialGradient, SD_Pattern, SD_Image, SD_Text, @@ -65,6 +67,17 @@ }; typedef struct _stateShadingInfo StateShadingInfo; +struct _stateGradientInfo +{ + CGPoint start; + CGPoint end; + CGFloat radius; + CGFloat* colordata; + CGFloat* fractionsdata; + jint fractionsLength; +}; +typedef struct _stateGradientInfo StateGradientInfo; + struct _statePatternInfo { CGFloat tx; @@ -122,6 +135,7 @@ // its callees. StateShadingInfo* shadingInfo; // tracks shading and its parameters + StateGradientInfo* gradientInfo; // tracks gradient and its parameters StatePatternInfo* patternInfo; // tracks pattern and its parameters StateGraphicsInfo graphicsStateInfo; // tracks other graphics state
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/QuartzSurfaceData.m Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/QuartzSurfaceData.m Fri Nov 04 17:52:55 2016 +0000 @@ -268,9 +268,105 @@ free(info); } +static inline void contextQuartzLinearGradientPath(QuartzSDOps* qsdo) +{ + +PRINT(" contextQuartzLinearGradientPath"); + + CGContextRef cgRef = qsdo->cgRef; + StateGradientInfo *gradientInfo = qsdo->gradientInfo; + + CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + size_t num_locations = gradientInfo->fractionsLength; + CGFloat *locations = (CGFloat *) malloc(sizeof(CGFloat) * num_locations); + int i = 0; + size_t component_size = num_locations * 4; + CGFloat components[component_size]; + CGGradientRef gradient = NULL; + + for (int i = 0; i < num_locations; i++) { + locations[i] = gradientInfo->fractionsdata[i]; +//fprintf(stderr, "locations[%d] %f\n", i, locations[i]); + } + for (i = 0; i < component_size; i++) { + components[i] = gradientInfo->colordata[i]; +//fprintf(stderr, "components[%d] %f, gradientInfo->colordata[%d] %f\n", +// i, components[i], i, gradientInfo->colordata[i]); + } + CGContextSaveGState(cgRef); + gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, num_locations); +//fprintf(stderr, "gradientInfo->start.x %f, gradientInfo->start.y %f\n", +// gradientInfo->start.x, gradientInfo->start.y); +//fprintf(stderr, "gradientInfo->end.x %f, gradientInfo->end.y %f\n", +// gradientInfo->end.x, gradientInfo->end.y); + if (qsdo->isEvenOddFill) { + CGContextEOClip(cgRef); + } else { + CGContextClip(cgRef); + } + CGContextDrawLinearGradient(cgRef, gradient, gradientInfo->start, gradientInfo->end, kCGGradientDrawsAfterEndLocation); + + CGContextRestoreGState(cgRef); + CGColorSpaceRelease(colorspace); + CGGradientRelease(gradient); + free(locations); + free(gradientInfo->colordata); + free(gradientInfo->fractionsdata); +} + +static inline void contextQuartzRadialGradientPath(QuartzSDOps* qsdo) +{ + +PRINT(" contextQuartzRadialGradientPath"); + + CGContextRef cgRef = qsdo->cgRef; + StateGradientInfo *gradientInfo = qsdo->gradientInfo; + + CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + size_t num_locations = gradientInfo->fractionsLength; + CGFloat *locations = (CGFloat *) malloc(sizeof(CGFloat) * num_locations); + int i = 0; + size_t component_size = num_locations * 4; + CGFloat components[component_size]; + CGGradientRef gradient = NULL; + CGFloat startRadius = gradientInfo->radius; + CGFloat endRadius = gradientInfo->radius; + + for (int i = 0; i < num_locations; i++) { + locations[i] = gradientInfo->fractionsdata[i]; +//fprintf(stderr, "locations[%d] %f\n", i, locations[i]); + } + for (i = 0; i < component_size; i++) { + components[i] = gradientInfo->colordata[i]; +//fprintf(stderr, "components[%d] %f, gradientInfo->colordata[%d] %f\n", +// i, components[i], i, gradientInfo->colordata[i]); + } + CGContextSaveGState(cgRef); + gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, num_locations); +//fprintf(stderr, "gradientInfo->start.x %f, gradientInfo->start.y %f\n", +// gradientInfo->start.x, gradientInfo->start.y); +//fprintf(stderr, "gradientInfo->end.x %f, gradientInfo->end.y %f\n", +// gradientInfo->end.x, gradientInfo->end.y); + if (qsdo->isEvenOddFill) { + CGContextEOClip(cgRef); + } else { + CGContextClip(cgRef); + } +//fprintf(stderr, "gradientInfo->startRadius %f, gradientInfo->endRadius %f\n",startRadius,endRadius); + CGContextDrawRadialGradient(cgRef, gradient, gradientInfo->start, 0, gradientInfo->end, endRadius, kCGGradientDrawsAfterEndLocation); + + CGContextRestoreGState(cgRef); + CGColorSpaceRelease(colorspace); + CGGradientRelease(gradient); + free(locations); + free(gradientInfo->colordata); + free(gradientInfo->fractionsdata); +} + static inline void contextGradientPath(QuartzSDOps* qsdo) { PRINT(" ContextGradientPath") + CGContextRef cgRef = qsdo->cgRef; StateShadingInfo* shadingInfo = qsdo->shadingInfo; @@ -827,6 +923,81 @@ qsdo->renderType = renderType; } +void setupGradient(JNIEnv *env, QuartzSDOps* qsdo, jfloat* javaFloatGraphicsStates) +{ + static const CGFloat kColorConversionMultiplier = 1.0f/255.0f; + qsdo->gradientInfo = (StateGradientInfo*)malloc(sizeof(StateGradientInfo)); + if (qsdo->gradientInfo == NULL) + { + [JNFException raise:env as:kOutOfMemoryError reason:"Failed to malloc memory for gradient paint"]; + } + + qsdo->graphicsStateInfo.simpleStroke = NO; + qsdo->graphicsStateInfo.simpleColor = NO; + + qsdo->gradientInfo->start.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx1Index]; + qsdo->gradientInfo->start.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory1Index]; + qsdo->gradientInfo->end.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx2Index]; + qsdo->gradientInfo->end.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory2Index]; + + jobject colorArray = ((*env)->GetObjectArrayElement(env, qsdo->javaGraphicsStatesObjects, sun_java2d_OSXSurfaceData_kColorArrayIndex)); + if (colorArray != NULL) + { + jint length = (*env)->GetArrayLength(env, colorArray); +//fprintf(stderr, "length %d\n", length); + + jint* jcolorData = (jint*)(*env)->GetPrimitiveArrayCritical(env, colorArray, NULL); + CGFloat* colors= (CGFloat*)calloc(0, sizeof(CGFloat)*length); + if (jcolorData != NULL) + { + jint i; + for (i=0; i<length; i++) + { + colors[i] = (CGFloat)jcolorData[i]; + } + } + (*env)->ReleasePrimitiveArrayCritical(env, colorArray, jcolorData, 0); + qsdo->gradientInfo->colordata = (CGFloat*)calloc(0, sizeof(CGFloat)*4*length); + for (int i = 0; i < length; i++) + { + jint c1 = colors[i]; +//fprintf(stderr, "c1 %x\n", c1); + qsdo->gradientInfo->colordata[i*4] = ((c1>>16)&0xff)*kColorConversionMultiplier; +//fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4, qsdo->gradientInfo->colordata[i*4]); + + qsdo->gradientInfo->colordata[i*4+1] = ((c1>>8)&0xff)*kColorConversionMultiplier; +//fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4+1, qsdo->gradientInfo->colordata[i*4+1]); + + qsdo->gradientInfo->colordata[i*4+2] = ((c1>>0)&0xff)*kColorConversionMultiplier; +//fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4+2, qsdo->gradientInfo->colordata[i*4+2]); + + qsdo->gradientInfo->colordata[i*4+3] = ((c1>>24)&0xff)*kColorConversionMultiplier; +//fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4+3, qsdo->gradientInfo->colordata[i*4+3]); + } + free(colors); + } + jobject fractionsArray = ((*env)->GetObjectArrayElement(env, qsdo->javaGraphicsStatesObjects, sun_java2d_OSXSurfaceData_kFractionsArrayIndex)); + if (fractionsArray != NULL) + { + jint length = (*env)->GetArrayLength(env, fractionsArray); +//fprintf(stderr, "fractions length %d\n", length); + qsdo->gradientInfo->fractionsLength = length; + + jfloat* jfractionsData = (jfloat*)(*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL); + if (jfractionsData != NULL) + { + qsdo->gradientInfo->fractionsdata = (CGFloat *)malloc(sizeof(CGFloat) *length); + jint i; + for (i=0; i<length; i++) + { + qsdo->gradientInfo->fractionsdata[i] = jfractionsData[i]; +//fprintf(stderr, "jfrationsData[%d] %f, qsdo->gradientInfo->fractionsdata[%d] = %f\n", i, jfractionsData[i], i, qsdo->gradientInfo->fractionsdata[i]); + } + (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, jfractionsData, 0); + } + } +} + SDRenderType SetUpPaint(JNIEnv *env, QuartzSDOps *qsdo, SDRenderType renderType) { CGContextRef cgRef = qsdo->cgRef; @@ -898,6 +1069,21 @@ break; } + case sun_java2d_OSXSurfaceData_kColorLinearGradient: + { + renderType = SD_LinearGradient; + setupGradient(env, qsdo, javaFloatGraphicsStates); + break; + } + + case sun_java2d_OSXSurfaceData_kColorRadialGradient: + { + renderType = SD_RadialGradient; + setupGradient(env, qsdo, javaFloatGraphicsStates); + qsdo->gradientInfo->radius = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kRadiusIndex]; + break; + } + case sun_java2d_OSXSurfaceData_kColorTexture: { qsdo->patternInfo = (StatePatternInfo*)malloc(sizeof(StatePatternInfo)); @@ -1076,11 +1262,24 @@ } break; + case SD_LinearGradient: + if (CGContextIsPathEmpty(qsdo->cgRef) == 0) + { + contextQuartzLinearGradientPath(qsdo); + } + break; + + case SD_RadialGradient: + if (CGContextIsPathEmpty(qsdo->cgRef) == 0) + { + contextQuartzRadialGradientPath(qsdo); + } + break; + case SD_Pattern: if (CGContextIsPathEmpty(qsdo->cgRef) == 0) { - //TODO:BG - //contextTexturePath(env, qsdo); + contextTexturePath(env, qsdo); } break; @@ -1111,4 +1310,8 @@ gradientPaintReleaseFunction(qsdo->shadingInfo); qsdo->shadingInfo = NULL; } + if (qsdo->gradientInfo != NULL) { + gradientPaintReleaseFunction(qsdo->gradientInfo); + qsdo->gradientInfo = NULL; + } }
--- a/jdk/src/java.desktop/share/classes/javax/imageio/package.html Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/imageio/package.html Fri Nov 04 17:52:55 2016 +0000 @@ -2,7 +2,7 @@ <html> <head> <!-- -Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2000, 2016, 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 @@ -58,6 +58,25 @@ <th> </th> <th>Reading</th> <th>Writing</th> <th>Notes</th> <th>Metadata</th> </tr> +<!-- BMP plugin --> +<tr> + <td><a href="https://msdn.microsoft.com/en-us/library/dd183391.aspx">BMP</a></td> + <td align='center'>yes</td> + <td align='center'>yes</td> + <td align='center'>none</td> + <td align='center'><a href='metadata/doc-files/bmp_metadata.html'> + BMP metadata format</a></td> +</tr> +<!-- GIF plugin --> +<tr> + <td><a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt">GIF</a></td> + <td align='center'>yes</td> + <td align='center'>yes</td> + <td align='center'><a href="#gif_plugin_notes"> + GIF plug-in notes</a></td> + <td align='center'><a href='metadata/doc-files/gif_metadata.html'> + GIF metadata format</a></td> +</tr> <!-- JPEG plugin --> <tr> <td> <a href="http://www.jpeg.org">JPEG</a></td> @@ -76,14 +95,15 @@ <td align='center'><a href='metadata/doc-files/png_metadata.html'> PNG metadata format</a></td> </tr> -<!-- BMP plugin --> +<!-- TIFF plugin --> <tr> - <td>BMP</td> + <td><a href="https://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf">TIFF</a></td> <td align='center'>yes</td> <td align='center'>yes</td> - <td align='center'>none</td> - <td align='center'><a href='metadata/doc-files/bmp_metadata.html'> - BMP metadata format</a></td> + <td align='center'><a href='metadata/doc-files/tiff_metadata.html#Reading'> + TIFF plug-in notes</td> + <td align='center'><a href='metadata/doc-files/tiff_metadata.html#StreamMetadata'> + TIFF metadata format</a></td> </tr> <!-- WBMP plugin --> <tr> @@ -94,16 +114,6 @@ <td align='center'><a href='metadata/doc-files/wbmp_metadata.html'> WBMP metadata format</a></td> </tr> -<!-- GIF plugin --> -<tr> - <td><a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt">GIF</a></td> - <td align='center'>yes</td> - <td align='center'>yes</td> - <td align='center'><a href="#gif_plugin_notes"> - GIF plug-in notes</a></td> - <td align='center'><a href='metadata/doc-files/gif_metadata.html'> - GIF metadata format</a></td> -</tr> </table> </div> <BR>
--- a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/ExifGPSTagSet.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/ExifGPSTagSet.java Fri Nov 04 17:52:55 2016 +0000 @@ -55,9 +55,7 @@ * * @see #TAG_GPS_VERSION_ID */ - public static final String GPS_VERSION_2_2 = - new String(new byte[] { '2', '2', '0', '0' }, - StandardCharsets.US_ASCII); + public static final String GPS_VERSION_2_2 = "2200"; /** * A tag indicating the North or South latitude (type ASCII, count = 2).
--- a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/ExifTIFFTagSet.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/ExifTIFFTagSet.java Fri Nov 04 17:52:55 2016 +0000 @@ -71,9 +71,7 @@ * * @see #TAG_EXIF_VERSION */ - public static final String EXIF_VERSION_2_1 = - new String(new byte[] { '0', '2', '1', '0' }, - StandardCharsets.US_ASCII); + public static final String EXIF_VERSION_2_1 = "0210"; /** * A value to be used with the "ExifVersion" tag to indicate Exif version @@ -82,9 +80,7 @@ * * @see #TAG_EXIF_VERSION */ - public static final String EXIF_VERSION_2_2 = - new String(new byte[] { '0', '2', '2', '0' }, - StandardCharsets.US_ASCII); + public static final String EXIF_VERSION_2_2 = "0220"; /** * A tag indicating the FlashPix version number (type UNDEFINED,
--- a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFField.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFField.java Fri Nov 04 17:52:55 2016 +0000 @@ -261,7 +261,7 @@ * @see TIFFDirectory * @see TIFFTag */ -public class TIFFField implements Cloneable { +public final class TIFFField implements Cloneable { private static final String[] typeNames = { null,
--- a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFImageReadParam.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFImageReadParam.java Fri Nov 04 17:52:55 2016 +0000 @@ -48,7 +48,7 @@ * * @since 9 */ -public class TIFFImageReadParam extends ImageReadParam { +public final class TIFFImageReadParam extends ImageReadParam { private List<TIFFTagSet> allowedTagSets = new ArrayList<TIFFTagSet>(4);
--- a/jdk/src/java.desktop/share/classes/javax/swing/JRootPane.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/JRootPane.java Fri Nov 04 17:52:55 2016 +0000 @@ -320,28 +320,6 @@ * a UI-specific action like pressing the <b>Enter</b> key occurs. */ protected JButton defaultButton; - /** - * As of Java 2 platform v1.3 this unusable field is no longer used. - * To override the default button you should replace the <code>Action</code> - * in the <code>JRootPane</code>'s <code>ActionMap</code>. Please refer to - * the key bindings specification for further details. - * - * @deprecated As of Java 2 platform v1.3. - * @see #defaultButton - */ - @Deprecated - protected DefaultAction defaultPressAction; - /** - * As of Java 2 platform v1.3 this unusable field is no longer used. - * To override the default button you should replace the <code>Action</code> - * in the <code>JRootPane</code>'s <code>ActionMap</code>. Please refer to - * the key bindings specification for further details. - * - * @deprecated As of Java 2 platform v1.3. - * @see #defaultButton - */ - @Deprecated - protected DefaultAction defaultReleaseAction; /** * Whether or not true double buffering should be used. This is typically @@ -829,35 +807,6 @@ } } - @SuppressWarnings("serial") - static class DefaultAction extends AbstractAction { - JButton owner; - JRootPane root; - boolean press; - DefaultAction(JRootPane root, boolean press) { - this.root = root; - this.press = press; - } - public void setOwner(JButton owner) { - this.owner = owner; - } - public void actionPerformed(ActionEvent e) { - if (owner != null && SwingUtilities.getRootPane(owner) == root) { - ButtonModel model = owner.getModel(); - if (press) { - model.setArmed(true); - model.setPressed(true); - } else { - model.setPressed(false); - } - } - } - public boolean isEnabled() { - return owner.getModel().isEnabled(); - } - } - - /** * Overridden to enforce the position of the glass component as * the zero child.
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java Fri Nov 04 17:52:55 2016 +0000 @@ -739,7 +739,7 @@ /** * The instance of {@code MetalBumps}. */ - protected MetalBumps bumps = new MetalBumps( 10, 10, + private MetalBumps bumps = new MetalBumps( 10, 10, MetalLookAndFeel.getControlHighlight(), MetalLookAndFeel.getControlDarkShadow(), UIManager.getColor("ToolBar.background"));
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java Fri Nov 04 17:52:55 2016 +0000 @@ -923,7 +923,7 @@ * @param fc a {@code JFileChooser} * @return a new instance of {@code DirectoryComboBoxRenderer} */ - protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser fc) { + private DefaultListCellRenderer createDirectoryComboBoxRenderer(JFileChooser fc) { return new DirectoryComboBoxRenderer(); }
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalScrollBarUI.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalScrollBarUI.java Fri Nov 04 17:52:55 2016 +0000 @@ -62,7 +62,7 @@ /** * The metal bumps. */ - protected MetalBumps bumps; + private MetalBumps bumps; /** * The increase button.
--- a/jdk/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java Fri Nov 04 17:52:55 2016 +0000 @@ -30,6 +30,9 @@ import java.awt.Toolkit; import java.io.*; import java.io.FileNotFoundException; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; import java.util.*; import java.util.concurrent.Callable; @@ -243,7 +246,8 @@ if (file instanceof ShellFolder) { return (ShellFolder)file; } - if (!file.exists()) { + + if (!Files.exists(file.toPath(), LinkOption.NOFOLLOW_LINKS)) { throw new FileNotFoundException(); } return shellFolderManager.createShellFolder(file);
--- a/jdk/src/java.desktop/share/classes/sun/font/NullFontScaler.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/sun/font/NullFontScaler.java Fri Nov 04 17:52:55 2016 +0000 @@ -36,8 +36,8 @@ boolean supportsCJK, int filesize) {} StrikeMetrics getFontMetrics(long pScalerContext) { - return new StrikeMetrics(0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, - 0xf0,0xf0,0xf0,0xf0); + return new StrikeMetrics(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f); } float getGlyphAdvance(long pScalerContext, int glyphCode) { @@ -71,7 +71,7 @@ return getNullScalerContext(); } - void invalidateScalerContext(long ppScalerContext) { + void invalidateScalerContext(long pScalerContext) { //nothing to do }
--- a/jdk/src/java.desktop/share/classes/sun/swing/plaf/GTKKeybindings.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/sun/swing/plaf/GTKKeybindings.java Fri Nov 04 17:52:55 2016 +0000 @@ -219,6 +219,38 @@ "KP_UP", "selectPrevious" }), + "Desktop.ancestorInputMap", + new UIDefaults.LazyInputMap(new Object[] { + "ctrl F5", "restore", + "ctrl F4", "close", + "ctrl F7", "move", + "ctrl F8", "resize", + "RIGHT", "right", + "KP_RIGHT", "right", + "shift RIGHT", "shrinkRight", + "shift KP_RIGHT", "shrinkRight", + "LEFT", "left", + "KP_LEFT", "left", + "shift LEFT", "shrinkLeft", + "shift KP_LEFT", "shrinkLeft", + "UP", "up", + "KP_UP", "up", + "shift UP", "shrinkUp", + "shift KP_UP", "shrinkUp", + "DOWN", "down", + "KP_DOWN", "down", + "shift DOWN", "shrinkDown", + "shift KP_DOWN", "shrinkDown", + "ESCAPE", "escape", + "ctrl F9", "minimize", + "ctrl F10", "maximize", + "ctrl F6", "selectNextFrame", + "ctrl TAB", "selectNextFrame", + "ctrl alt F6", "selectNextFrame", + "shift ctrl alt F6", "selectPreviousFrame", + "ctrl F12", "navigateNext", + "shift ctrl F12", "navigatePrevious" + }), "EditorPane.focusInputMap", multilineInputMap, "FileChooser.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[]{
--- a/jdk/src/java.management/share/classes/sun/management/StackTraceElementCompositeData.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.management/share/classes/sun/management/StackTraceElementCompositeData.java Fri Nov 04 17:52:55 2016 +0000 @@ -58,7 +58,8 @@ getString(cd, FILE_NAME), getInt(cd, LINE_NUMBER)); } else { - return new StackTraceElement(getString(cd, MODULE_NAME), + return new StackTraceElement(getString(cd, CLASS_LOADER_NAME), + getString(cd, MODULE_NAME), getString(cd, MODULE_VERSION), getString(cd, CLASS_NAME), getString(cd, METHOD_NAME), @@ -76,13 +77,14 @@ // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH // stackTraceElementItemNames! final Object[] stackTraceElementItemValues = { + ste.getClassLoaderName(), + ste.getModuleName(), + ste.getModuleVersion(), ste.getClassName(), ste.getMethodName(), ste.getFileName(), ste.getLineNumber(), ste.isNativeMethod(), - ste.getModuleName(), - ste.getModuleVersion(), }; try { return new CompositeDataSupport(stackTraceElementCompositeType, @@ -95,25 +97,29 @@ } // Attribute names - private static final String CLASS_NAME = "className"; - private static final String METHOD_NAME = "methodName"; - private static final String FILE_NAME = "fileName"; - private static final String LINE_NUMBER = "lineNumber"; - private static final String NATIVE_METHOD = "nativeMethod"; - private static final String MODULE_NAME = "moduleName"; - private static final String MODULE_VERSION = "moduleVersion"; + private static final String CLASS_LOADER_NAME = "classLoaderName"; + private static final String MODULE_NAME = "moduleName"; + private static final String MODULE_VERSION = "moduleVersion"; + private static final String CLASS_NAME = "className"; + private static final String METHOD_NAME = "methodName"; + private static final String FILE_NAME = "fileName"; + private static final String LINE_NUMBER = "lineNumber"; + private static final String NATIVE_METHOD = "nativeMethod"; + private static final String[] stackTraceElementItemNames = { + CLASS_LOADER_NAME, + MODULE_NAME, + MODULE_VERSION, CLASS_NAME, METHOD_NAME, FILE_NAME, LINE_NUMBER, NATIVE_METHOD, - MODULE_NAME, - MODULE_VERSION, }; private static final String[] stackTraceElementV9ItemNames = { + CLASS_LOADER_NAME, MODULE_NAME, MODULE_VERSION, };
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java Fri Nov 04 17:52:55 2016 +0000 @@ -102,6 +102,11 @@ AccessController.doPrivileged((PrivilegedAction<Long>) () -> Long.getLong("sun.rmi.transport.tcp.threadKeepAliveTime", 60000)); + /** enable multiplexing protocol */ + private static final boolean enableMultiplexProtocol = // default false + AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> + Boolean.getBoolean("sun.rmi.transport.tcp.enableMultiplexProtocol")); + /** thread pool for connection handlers */ private static final ExecutorService connectionThreadPool = new ThreadPoolExecutor(0, maxConnectionThreads, @@ -796,6 +801,19 @@ break; case TransportConstants.MultiplexProtocol: + + if (!enableMultiplexProtocol) { + if (tcpLog.isLoggable(Log.VERBOSE)) { + tcpLog.log(Log.VERBOSE, "(port " + port + + ") rejecting multiplex protocol"); + } + + // If MultiplexProtocol is disabled, send NACK immediately. + out.writeByte(TransportConstants.ProtocolNack); + out.flush(); + break; + } + if (tcpLog.isLoggable(Log.VERBOSE)) { tcpLog.log(Log.VERBOSE, "(port " + port + ") accepting multiplex protocol");
--- a/jdk/src/java.sql/share/classes/java/sql/CallableStatement.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.sql/share/classes/java/sql/CallableStatement.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -295,7 +295,7 @@ * or <code>getBigDecimal(String parameterName)</code> * @see #setBigDecimal */ - @Deprecated + @Deprecated(since="1.2") BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException;
--- a/jdk/src/java.sql/share/classes/java/sql/Date.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.sql/share/classes/java/sql/Date.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -58,7 +58,7 @@ * @param day 1 to 31 * @deprecated instead use the constructor <code>Date(long date)</code> */ - @Deprecated + @Deprecated(since="1.2") public Date(int year, int month, int day) { super(year, month, day); } @@ -199,7 +199,7 @@ * @exception java.lang.IllegalArgumentException if this method is invoked * @see #setHours */ - @Deprecated + @Deprecated(since="1.2") public int getHours() { throw new java.lang.IllegalArgumentException(); } @@ -212,7 +212,7 @@ * @exception java.lang.IllegalArgumentException if this method is invoked * @see #setMinutes */ - @Deprecated + @Deprecated(since="1.2") public int getMinutes() { throw new java.lang.IllegalArgumentException(); } @@ -225,7 +225,7 @@ * @exception java.lang.IllegalArgumentException if this method is invoked * @see #setSeconds */ - @Deprecated + @Deprecated(since="1.2") public int getSeconds() { throw new java.lang.IllegalArgumentException(); } @@ -238,7 +238,7 @@ * @exception java.lang.IllegalArgumentException if this method is invoked * @see #getHours */ - @Deprecated + @Deprecated(since="1.2") public void setHours(int i) { throw new java.lang.IllegalArgumentException(); } @@ -251,7 +251,7 @@ * @exception java.lang.IllegalArgumentException if this method is invoked * @see #getMinutes */ - @Deprecated + @Deprecated(since="1.2") public void setMinutes(int i) { throw new java.lang.IllegalArgumentException(); } @@ -264,7 +264,7 @@ * @exception java.lang.IllegalArgumentException if this method is invoked * @see #getSeconds */ - @Deprecated + @Deprecated(since="1.2") public void setSeconds(int i) { throw new java.lang.IllegalArgumentException(); }
--- a/jdk/src/java.sql/share/classes/java/sql/DriverManager.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.sql/share/classes/java/sql/DriverManager.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -515,7 +515,7 @@ * @see SecurityManager#checkPermission * @see #getLogStream */ - @Deprecated + @Deprecated(since="1.2") public static void setLogStream(java.io.PrintStream out) { SecurityManager sec = System.getSecurityManager(); @@ -538,7 +538,7 @@ * @deprecated Use {@code getLogWriter} * @see #setLogStream */ - @Deprecated + @Deprecated(since="1.2") public static java.io.PrintStream getLogStream() { return logStream; }
--- a/jdk/src/java.sql/share/classes/java/sql/PreparedStatement.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.sql/share/classes/java/sql/PreparedStatement.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -344,7 +344,7 @@ * this method * @deprecated Use {@code setCharacterStream} */ - @Deprecated + @Deprecated(since="1.2") void setUnicodeStream(int parameterIndex, java.io.InputStream x, int length) throws SQLException;
--- a/jdk/src/java.sql/share/classes/java/sql/ResultSet.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.sql/share/classes/java/sql/ResultSet.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -358,7 +358,7 @@ * @deprecated Use {@code getBigDecimal(int columnIndex)} * or {@code getBigDecimal(String columnLabel)} */ - @Deprecated + @Deprecated(since="1.2") BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException; /** @@ -478,7 +478,7 @@ * @deprecated use <code>getCharacterStream</code> in place of * <code>getUnicodeStream</code> */ - @Deprecated + @Deprecated(since="1.2") java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException; /** @@ -646,7 +646,7 @@ * @deprecated Use {@code getBigDecimal(int columnIndex)} * or {@code getBigDecimal(String columnLabel)} */ - @Deprecated + @Deprecated(since="1.2") BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException; /** @@ -764,7 +764,7 @@ * this method * @deprecated use <code>getCharacterStream</code> instead */ - @Deprecated + @Deprecated(since="1.2") java.io.InputStream getUnicodeStream(String columnLabel) throws SQLException; /**
--- a/jdk/src/java.sql/share/classes/java/sql/Time.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.sql/share/classes/java/sql/Time.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @deprecated Use the constructor that takes a milliseconds value * in place of this constructor */ - @Deprecated + @Deprecated(since="1.2") public Time(int hour, int minute, int second) { super(70, 0, 1, hour, minute, second); } @@ -146,7 +146,7 @@ * method is invoked * @see #setYear */ - @Deprecated + @Deprecated(since="1.2") public int getYear() { throw new java.lang.IllegalArgumentException(); } @@ -160,7 +160,7 @@ * method is invoked * @see #setMonth */ - @Deprecated + @Deprecated(since="1.2") public int getMonth() { throw new java.lang.IllegalArgumentException(); } @@ -173,7 +173,7 @@ * @exception java.lang.IllegalArgumentException if this * method is invoked */ - @Deprecated + @Deprecated(since="1.2") public int getDay() { throw new java.lang.IllegalArgumentException(); } @@ -187,7 +187,7 @@ * method is invoked * @see #setDate */ - @Deprecated + @Deprecated(since="1.2") public int getDate() { throw new java.lang.IllegalArgumentException(); } @@ -201,7 +201,7 @@ * method is invoked * @see #getYear */ - @Deprecated + @Deprecated(since="1.2") public void setYear(int i) { throw new java.lang.IllegalArgumentException(); } @@ -215,7 +215,7 @@ * method is invoked * @see #getMonth */ - @Deprecated + @Deprecated(since="1.2") public void setMonth(int i) { throw new java.lang.IllegalArgumentException(); } @@ -229,7 +229,7 @@ * method is invoked * @see #getDate */ - @Deprecated + @Deprecated(since="1.2") public void setDate(int i) { throw new java.lang.IllegalArgumentException(); }
--- a/jdk/src/java.sql/share/classes/java/sql/Timestamp.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/src/java.sql/share/classes/java/sql/Timestamp.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -88,7 +88,7 @@ * @deprecated instead use the constructor {@code Timestamp(long millis)} * @exception IllegalArgumentException if the nano argument is out of bounds */ - @Deprecated + @Deprecated(since="1.2") public Timestamp(int year, int month, int date, int hour, int minute, int second, int nano) { super(year, month, date, hour, minute, second);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.editpad/share/classes/jdk/editpad/EditPad.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.editpad; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.function.Consumer; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +/** + * A minimal Swing editor as a fallback when the user does not specify an + * external editor. + */ +class EditPad implements Runnable { + + private static final String L10N_RB_NAME = "jdk.editpad.resources.l10n"; + private ResourceBundle rb = null; + private final String windowLabel; + private final Consumer<String> errorHandler; + private final String initialText; + private final Runnable closeMark; + private final Consumer<String> saveHandler; + + /** + * Create an Edit Pad minimal editor. + * + * @param windowLabel the label string for the Edit Pad window + * @param errorHandler a handler for unexpected errors + * @param initialText the source to load in the Edit Pad + * @param closeMark a Runnable that is run when Edit Pad closes + * @param saveHandler a handler for changed source (sent the full source) + */ + EditPad(String windowLabel, Consumer<String> errorHandler, String initialText, + Runnable closeMark, Consumer<String> saveHandler) { + this.windowLabel = windowLabel; + this.errorHandler = errorHandler; + this.initialText = initialText; + this.closeMark = closeMark; + this.saveHandler = saveHandler; + } + + @Override + public void run() { + JFrame jframe = new JFrame(windowLabel == null + ? getResourceString("editpad.name") + : windowLabel); + Runnable closer = () -> { + jframe.setVisible(false); + jframe.dispose(); + closeMark.run(); + }; + jframe.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + closer.run(); + } + }); + jframe.setLocationRelativeTo(null); + jframe.setLayout(new BorderLayout()); + JTextArea textArea = new JTextArea(initialText); + textArea.setFont(new Font("monospaced", Font.PLAIN, 13)); + jframe.add(new JScrollPane(textArea), BorderLayout.CENTER); + jframe.add(buttons(closer, textArea), BorderLayout.SOUTH); + + jframe.setSize(800, 600); + jframe.setVisible(true); + } + + private JPanel buttons(Runnable closer, JTextArea textArea) { + FlowLayout flow = new FlowLayout(); + flow.setHgap(35); + JPanel buttons = new JPanel(flow); + addButton(buttons, "editpad.cancel", KeyEvent.VK_C, e -> { + closer.run(); + }); + addButton(buttons, "editpad.accept", KeyEvent.VK_A, e -> { + saveHandler.accept(textArea.getText()); + }); + addButton(buttons, "editpad.exit", KeyEvent.VK_X, e -> { + saveHandler.accept(textArea.getText()); + closer.run(); + }); + return buttons; + } + + private void addButton(JPanel buttons, String rkey, int mnemonic, ActionListener action) { + JButton but = new JButton(getResourceString(rkey)); + but.setMnemonic(mnemonic); + buttons.add(but); + but.addActionListener(action); + } + + private String getResourceString(String key) { + if (rb == null) { + try { + rb = ResourceBundle.getBundle(L10N_RB_NAME); + } catch (MissingResourceException mre) { + error("Cannot find ResourceBundle: %s", L10N_RB_NAME); + return ""; + } + } + String s; + try { + s = rb.getString(key); + } catch (MissingResourceException mre) { + error("Missing resource: %s in %s", key, L10N_RB_NAME); + return ""; + } + return s; + } + + private void error(String fmt, Object... args) { + errorHandler.accept(String.format(fmt, args)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.editpad/share/classes/jdk/editpad/EditPadProvider.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.editpad; + +import java.util.concurrent.CountDownLatch; +import java.util.function.Consumer; +import javax.swing.SwingUtilities; +import jdk.internal.editor.spi.BuildInEditorProvider; + +/** + * Defines the provider of an Edit Pad implementation. + * + * @author Robert Field + */ +public class EditPadProvider implements BuildInEditorProvider { + + /** + * @return the rank of a provider, greater is better. + */ + @Override + public int rank() { + return 5; + } + + /** + * Create an Edit Pad minimal editor. + * + * @param windowLabel the label string for the Edit Pad window, or null, + * for default window label + * @param initialText the source to load in the Edit Pad + * @param saveHandler a handler for changed source (can be sent the full source) + * @param errorHandler a handler for unexpected errors + */ + @Override + public void edit(String windowLabel, String initialText, + Consumer<String> saveHandler, Consumer<String> errorHandler) { + CountDownLatch closeLock = new CountDownLatch(1); + SwingUtilities.invokeLater( + new EditPad(windowLabel, errorHandler, initialText, closeLock::countDown, saveHandler)); + do { + try { + closeLock.await(); + break; + } catch (InterruptedException ex) { + // ignore and loop + } + } while (true); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.editpad/share/classes/jdk/editpad/resources/l10n.properties Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,29 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +editpad.name = Edit Pad +editpad.cancel = Cancel +editpad.accept = Accept +editpad.exit = Exit
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.editpad/share/classes/module-info.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Implementation of the edit pad service. + */ +module jdk.editpad { + requires jdk.internal.ed; + requires java.desktop; + provides jdk.internal.editor.spi.BuildInEditorProvider + with jdk.editpad.EditPadProvider; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.ed/share/classes/jdk/internal/editor/external/ExternalEditor.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.editor.external; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.ClosedWatchServiceException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import java.util.Arrays; +import java.util.Scanner; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; +import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; +import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; + +/** + * Wrapper for controlling an external editor. + */ +public class ExternalEditor { + private final Consumer<String> errorHandler; + private final Consumer<String> saveHandler; + private final boolean wait; + + private final Runnable suspendInteractiveInput; + private final Runnable resumeInteractiveInput; + private final Runnable promptForNewLineToEndWait; + + private WatchService watcher; + private Thread watchedThread; + private Path dir; + private Path tmpfile; + + /** + * Launch an external editor. + * + * @param cmd the command to launch (with parameters) + * @param initialText initial text in the editor buffer + * @param errorHandler handler for error messages + * @param saveHandler handler sent the buffer contents on save + * @param suspendInteractiveInput a callback to suspend caller (shell) input + * @param resumeInteractiveInput a callback to resume caller input + * @param wait true, if editor process termination cannot be used to + * determine when done + * @param promptForNewLineToEndWait a callback to prompt for newline if + * wait==true + */ + public static void edit(String[] cmd, String initialText, + Consumer<String> errorHandler, + Consumer<String> saveHandler, + Runnable suspendInteractiveInput, + Runnable resumeInteractiveInput, + boolean wait, + Runnable promptForNewLineToEndWait) { + ExternalEditor ed = new ExternalEditor(errorHandler, saveHandler, suspendInteractiveInput, + resumeInteractiveInput, wait, promptForNewLineToEndWait); + ed.edit(cmd, initialText); + } + + ExternalEditor(Consumer<String> errorHandler, + Consumer<String> saveHandler, + Runnable suspendInteractiveInput, + Runnable resumeInteractiveInput, + boolean wait, + Runnable promptForNewLineToEndWait) { + this.errorHandler = errorHandler; + this.saveHandler = saveHandler; + this.wait = wait; + this.suspendInteractiveInput = suspendInteractiveInput; + this.resumeInteractiveInput = resumeInteractiveInput; + this.promptForNewLineToEndWait = promptForNewLineToEndWait; + } + + private void edit(String[] cmd, String initialText) { + try { + setupWatch(initialText); + launch(cmd); + } catch (IOException ex) { + errorHandler.accept(ex.getMessage()); + } + } + + /** + * Creates a WatchService and registers the given directory + */ + private void setupWatch(String initialText) throws IOException { + this.watcher = FileSystems.getDefault().newWatchService(); + this.dir = Files.createTempDirectory("extedit"); + this.tmpfile = Files.createTempFile(dir, null, ".java"); + Files.write(tmpfile, initialText.getBytes(Charset.forName("UTF-8"))); + dir.register(watcher, + ENTRY_CREATE, + ENTRY_DELETE, + ENTRY_MODIFY); + watchedThread = new Thread(() -> { + for (;;) { + WatchKey key; + try { + key = watcher.take(); + } catch (ClosedWatchServiceException ex) { + // The watch service has been closed, we are done + break; + } catch (InterruptedException ex) { + // tolerate an interrupt + continue; + } + + if (!key.pollEvents().isEmpty()) { + saveFile(); + } + + boolean valid = key.reset(); + if (!valid) { + // The watch service has been closed, we are done + break; + } + } + }); + watchedThread.start(); + } + + private void launch(String[] cmd) throws IOException { + String[] params = Arrays.copyOf(cmd, cmd.length + 1); + params[cmd.length] = tmpfile.toString(); + ProcessBuilder pb = new ProcessBuilder(params); + pb = pb.inheritIO(); + + try { + suspendInteractiveInput.run(); + Process process = pb.start(); + // wait to exit edit mode in one of these ways... + if (wait) { + // -wait option -- ignore process exit, wait for carriage-return + Scanner scanner = new Scanner(System.in); + promptForNewLineToEndWait.run(); + scanner.nextLine(); + } else { + // wait for process to exit + process.waitFor(); + } + } catch (IOException ex) { + errorHandler.accept("process IO failure: " + ex.getMessage()); + } catch (InterruptedException ex) { + errorHandler.accept("process interrupt: " + ex.getMessage()); + } finally { + try { + watcher.close(); + watchedThread.join(); //so that saveFile() is finished. + saveFile(); + } catch (InterruptedException ex) { + errorHandler.accept("process interrupt: " + ex.getMessage()); + } finally { + resumeInteractiveInput.run(); + } + } + } + + private void saveFile() { + try { + saveHandler.accept(Files.lines(tmpfile).collect(Collectors.joining("\n", "", "\n"))); + } catch (IOException ex) { + errorHandler.accept("Failure in read edit file: " + ex.getMessage()); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.ed/share/classes/jdk/internal/editor/spi/BuildInEditorProvider.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.editor.spi; + +import java.util.function.Consumer; + +/** + * Defines the provider of a built-in editor. + */ +public interface BuildInEditorProvider { + + /** + * @return the rank of a provider, greater is better. + */ + int rank(); + + /** + * Create a simple built-in editor. + * + * @param windowLabel the label string for the Edit Pad window, or null, + * for default window label + * @param initialText the source to load in the Edit Pad + * @param saveHandler a handler for changed source (can be sent the full source) + * @param errorHandler a handler for unexpected errors + */ + void edit(String windowLabel, String initialText, + Consumer<String> saveHandler, Consumer<String> errorHandler); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.ed/share/classes/module-info.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Internal editor support for JDK tools. Includes the Service Provider + * Interface to built-in editors. + */ +module jdk.internal.ed { + + exports jdk.internal.editor.spi to jdk.editpad, jdk.jshell, jdk.scripting.nashorn.shell; + exports jdk.internal.editor.external to jdk.jshell, jdk.scripting.nashorn.shell; +}
--- a/jdk/test/ProblemList.txt Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/ProblemList.txt Fri Nov 04 17:52:55 2016 +0000 @@ -217,6 +217,13 @@ ############################################################################ # jdk_sound +javax/sound/sampled/DirectAudio/bug6372428.java 8055097 generic-all +javax/sound/sampled/Clip/bug5070081.java 8055097 generic-all +javax/sound/sampled/DataLine/LongFramePosition.java 8055097 generic-all + +javax/sound/sampled/Clip/Drain/ClipDrain.java 7062792 generic-all + +javax/sound/sampled/Mixers/DisabledAssertionCrash.java 7067310 generic-all javax/sound/sampled/Clip/OpenNonIntegralNumberOfSampleframes.java 8168881 generic-all
--- a/jdk/test/java/awt/FileDialog/8017487/bug8017487.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/awt/FileDialog/8017487/bug8017487.java Fri Nov 04 17:52:55 2016 +0000 @@ -22,7 +22,7 @@ */ /* @test - @bug 8017487 + @bug 8017487 8167988 @summary filechooser in Windows-Libraries folder: columns are mixed up @author Semyon Sadetsky @modules java.desktop/sun.awt.shell
--- a/jdk/test/java/awt/TrayIcon/DragEventSource/DragEventSource.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/awt/TrayIcon/DragEventSource/DragEventSource.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,8 @@ /* @test - @bug 6565779 - @library ../../../regtesthelpers + @bug 6565779 8168292 + @library ../../regtesthelpers @compile DragEventSource.java @summary Exception if source of some event is TrayIcon @author Andrei Dmitriev: area=awt.tray @@ -38,9 +38,19 @@ * instance as source. */ -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.FileDialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Image; +import java.awt.Panel; +import java.awt.SystemTray; +import java.awt.TextArea; +import java.awt.TrayIcon; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; public class DragEventSource { @@ -81,11 +91,10 @@ String[] instructions = { - "Use see a Frame with a button in it.", - "Press the button. FileDialog should appear.", - "Drag the mouse from the Tray icon to FileDialog ", - "using left mouse button.", - "If exception happens, the test fails.", + "Click 'Open file dialog' button. FileDialog should appear.", + "Using left mouse button,", + "Drag the mouse from the Tray icon to FileDialog.", + "If exception is thrown, the test fails.", "Otherwise, pass." };
--- a/jdk/test/java/awt/Window/ChangeWindowResizabilty/ChangeWindowResizabiltyTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/awt/Window/ChangeWindowResizabilty/ChangeWindowResizabiltyTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -21,12 +21,19 @@ * questions. */ -/* @bug 8166897 +/* @test + @key headful + @bug 8166897 @summary Some font overlap in the Optionpane dialog. @run main ChangeWindowResizabiltyTest */ -import java.awt.*; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Robot; public class ChangeWindowResizabiltyTest { public static void main(String[] args) throws Exception {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/print/PrinterJob/LinearGradientPrintingTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2016, 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 8162796 + * @summary Verifies if LinearGradientPaint is printed in osx + * @run main/manual LinearGradientPrintingTest + */ +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.LinearGradientPaint; +import java.awt.Shape; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; + +public class LinearGradientPrintingTest extends Component implements Printable { + private static Thread mainThread; + private static boolean testPassed; + private static boolean testGeneratedInterrupt; + private static JFrame f = null; + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + //createUI(); + doTest(LinearGradientPrintingTest::createUI); + } + }); + mainThread = Thread.currentThread(); + try { + Thread.sleep(120000); + } catch (InterruptedException e) { + if (!testPassed && testGeneratedInterrupt) { + throw new RuntimeException("LinearGradientPaint did not print"); + } + } + if (!testGeneratedInterrupt) { + throw new RuntimeException("user has not executed the test"); + } + } + + public static void createUI() { + f = new JFrame("LinearGradient Printing Test"); + f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + final LinearGradientPrintingTest gpt = new LinearGradientPrintingTest(); + Container c = f.getContentPane(); + c.add(BorderLayout.CENTER, gpt); + + final JButton print = new JButton("Print"); + print.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(gpt); + final boolean doPrint = job.printDialog(); + if (doPrint) { + try { + job.print(); + } catch (PrinterException ex) { + throw new RuntimeException(ex); + } + } + } + }); + c.add(print, BorderLayout.SOUTH); + + f.pack(); + f.setVisible(true); + } + + public Dimension getPreferredSize() { + return new Dimension(500,500); + } + + public void paint(Graphics g) { + doPaint((Graphics2D)g); + } + + public int print( Graphics graphics, PageFormat format, int index ) { + Graphics2D g2d = (Graphics2D)graphics; + g2d.translate(format.getImageableX(), format.getImageableY()); + doPaint(g2d); + return index == 0 ? PAGE_EXISTS : NO_SUCH_PAGE; + } + + static final float DIM = 100; + public void doPaint(Graphics2D g2d) { + + g2d.translate(DIM*0.2, DIM*0.2); + Shape s = new Rectangle2D.Float(0, 0, DIM*2, DIM*2); + Point2D.Double p1 = new Point2D.Double(0.0, 0.0); + Point2D.Double p2 = new Point2D.Double(DIM/2.0, DIM/2.0); + + // LinearGradientPaint + //g2d.translate(DIM*2.2, 0); + Color colors[] = { Color.red, Color.blue} ; + float fractions[] = { 0.0f, 1.0f }; + + LinearGradientPaint lgp = + new LinearGradientPaint(p1, p2, fractions, colors, + LinearGradientPaint.CycleMethod.NO_CYCLE); + g2d.setPaint(lgp); + g2d.fill(s); + + g2d.translate(DIM*2.2, 0); + Color colors1[] = { Color.red, Color.blue, Color.green, Color.white} ; + float fractions1[] = { 0.0f, 0.3f, 0.6f, 1.0f }; + + LinearGradientPaint lgp1 = + new LinearGradientPaint(p1, p2, fractions1, colors1, + LinearGradientPaint.CycleMethod.REFLECT); + g2d.setPaint(lgp1); + g2d.fill(s); + + g2d.translate(-DIM*2.2, DIM*2.2); + Color colors2[] = { Color.red, Color.blue, Color.green, Color.white} ; + float fractions2[] = { 0.0f, 0.3f, 0.6f, 1.0f }; + + LinearGradientPaint lgp2 = + new LinearGradientPaint(p1, p2, fractions2, colors2, + LinearGradientPaint.CycleMethod.REPEAT); + g2d.setPaint(lgp2); + g2d.fill(s); + } + + public static synchronized void pass() { + testPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + public static synchronized void fail() { + testPassed = false; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + private static void doTest(Runnable action) { + String description + = " A LinearGradientPaint graphics will be shown on console.\n" + + " The same graphics is sent to printer.\n" + + " Please verify if LinearGradientPaint shading is printed.\n" + + " If none is printed, press FAIL else press PASS"; + + final JDialog dialog = new JDialog(); + dialog.setTitle("printSelectionTest"); + JTextArea textArea = new JTextArea(description); + textArea.setEditable(false); + final JButton testButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + f.dispose(); + dialog.dispose(); + pass(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + f.dispose(); + dialog.dispose(); + fail(); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + action.run(); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + + dialog.pack(); + dialog.setVisible(true); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.out.println("main dialog closing"); + testGeneratedInterrupt = false; + mainThread.interrupt(); + } + }); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/print/PrinterJob/RadialGradientPrintingTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2016, 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 8162796 + * @summary Verifies if RadialGradientPaint is printed in osx + * @run main/manual RadialGradientPrintingTest + */ +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RadialGradientPaint; +import java.awt.Shape; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import static java.awt.print.Printable.NO_SUCH_PAGE; +import static java.awt.print.Printable.PAGE_EXISTS; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; + +public class RadialGradientPrintingTest extends Component implements Printable { + private static Thread mainThread; + private static boolean testPassed; + private static boolean testGeneratedInterrupt; + private static JFrame f = null; + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + //createUI(); + doTest(RadialGradientPrintingTest::createUI); + } + }); + mainThread = Thread.currentThread(); + try { + Thread.sleep(120000); + } catch (InterruptedException e) { + if (!testPassed && testGeneratedInterrupt) { + throw new RuntimeException("LinearGradientPaint did not print"); + } + } + if (!testGeneratedInterrupt) { + throw new RuntimeException("user has not executed the test"); + } + } + + public static void createUI() { + f = new JFrame("RadialGradient Printing Test"); + f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + final RadialGradientPrintingTest gpt = new RadialGradientPrintingTest(); + Container c = f.getContentPane(); + c.add(BorderLayout.CENTER, gpt); + + final JButton print = new JButton("Print"); + print.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(gpt); + final boolean doPrint = job.printDialog(); + if (doPrint) { + try { + job.print(); + } catch (PrinterException ex) { + throw new RuntimeException(ex); + } + } + } + }); + c.add(print, BorderLayout.SOUTH); + + f.pack(); + f.setVisible(true); + } + + public Dimension getPreferredSize() { + return new Dimension(500,500); + } + + public void paint(Graphics g) { + doPaint((Graphics2D)g); + } + + public int print( Graphics graphics, PageFormat format, int index ) { + Graphics2D g2d = (Graphics2D)graphics; + g2d.translate(format.getImageableX(), format.getImageableY()); + doPaint(g2d); + return index == 0 ? PAGE_EXISTS : NO_SUCH_PAGE; + } + + static final float DIM = 100; + public void doPaint(Graphics2D g2d) { + + g2d.translate(DIM*0.2, DIM*0.2); + Shape s = new Rectangle2D.Float(0, 0, DIM*2, DIM*2); + + // RadialGradientPaint + Point2D centre = new Point2D.Float(DIM/2.0f, DIM/2.0f); + float radius = DIM/2.0f; + Point2D focus = new Point2D.Float(DIM/3.0f, DIM/3.0f); + float stops[] = {0.0f, 1.0f}; + Color colors[] = { Color.red, Color.white} ; + + RadialGradientPaint rgp = + new RadialGradientPaint(centre, radius, focus, stops, colors, + RadialGradientPaint.CycleMethod.NO_CYCLE); + g2d.setPaint(rgp); + g2d.fill(s); + + g2d.translate(DIM*2.2, 0); + Color colors1[] = { Color.red, Color.blue, Color.green} ; + float stops1[] = {0.0f, 0.5f, 1.0f}; + RadialGradientPaint rgp1 = + new RadialGradientPaint(centre, radius, focus, stops1, colors1, + RadialGradientPaint.CycleMethod.REFLECT); + g2d.setPaint(rgp1); + g2d.fill(s); + + g2d.translate(-DIM*2.2, DIM*2.2); + Color colors2[] = { Color.red, Color.blue, Color.green, Color.white} ; + float stops2[] = {0.0f, 0.3f, 0.6f, 1.0f}; + RadialGradientPaint rgp2 = + new RadialGradientPaint(centre, radius, focus, stops2, colors2, + RadialGradientPaint.CycleMethod.REPEAT); + g2d.setPaint(rgp2); + g2d.fill(s); + + } + + public static synchronized void pass() { + testPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + public static synchronized void fail() { + testPassed = false; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + private static void doTest(Runnable action) { + String description + = " A RadialGradientPaint graphics will be shown on console.\n" + + " The same graphics is sent to printer.\n" + + " Please verify if RadialGradientPaint shading is printed.\n" + + " If none is printed, press FAIL else press PASS"; + + final JDialog dialog = new JDialog(); + dialog.setTitle("printSelectionTest"); + JTextArea textArea = new JTextArea(description); + textArea.setEditable(false); + final JButton testButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + f.dispose(); + dialog.dispose(); + pass(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + f.dispose(); + dialog.dispose(); + fail(); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + action.run(); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + + dialog.pack(); + dialog.setVisible(true); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.out.println("main dialog closing"); + testGeneratedInterrupt = false; + mainThread.interrupt(); + } + }); + } + +}
--- a/jdk/test/java/io/Serializable/serialFilter/SerialFilterTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/io/Serializable/serialFilter/SerialFilterTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -40,7 +40,7 @@ import java.util.Set; import java.util.concurrent.atomic.LongAdder; -import javax.lang.model.SourceVersion; +import javax.net.ssl.SSLEngineResult; import org.testng.Assert; import org.testng.annotations.Test; @@ -82,8 +82,8 @@ Object[][] patterns = new Object[][]{ {"java.util.Hashtable"}, {"java.util.Hash*"}, - {"javax.lang.model.*"}, - {"javax.lang.**"}, + {"javax.net.ssl.*"}, + {"javax.net.**"}, {"*"}, {"maxarray=47"}, {"maxdepth=5"}, @@ -543,20 +543,20 @@ static Object genTestObjectWildcard(String pattern, boolean allowed) { if (pattern.endsWith(".**")) { // package hierarchy wildcard - if (pattern.startsWith("javax.lang.")) { - return SourceVersion.RELEASE_5; + if (pattern.startsWith("javax.net.")) { + return SSLEngineResult.Status.BUFFER_OVERFLOW; } if (pattern.startsWith("java.")) { return 4; } if (pattern.startsWith("javax.")) { - return SourceVersion.RELEASE_6; + return SSLEngineResult.Status.BUFFER_UNDERFLOW; } return otherObject; } else if (pattern.endsWith(".*")) { // package wildcard - if (pattern.startsWith("javax.lang.model")) { - return SourceVersion.RELEASE_6; + if (pattern.startsWith("javax.net.ssl")) { + return SSLEngineResult.Status.BUFFER_UNDERFLOW; } } else { // class wildcard
--- a/jdk/test/java/lang/StackTraceElement/PublicConstructor.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/lang/StackTraceElement/PublicConstructor.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,43 +23,74 @@ /* * @test - * @bug 4712607 + * @bug 4712607 6479237 * @summary Basic test for StackTraceElementPublic constructor * @author Josh Bloch */ -import java.util.*; +import java.lang.module.ModuleDescriptor; +import java.lang.reflect.Module; public class PublicConstructor { - public static void main(String args[]) { + public static void main(String... args) { + testConstructor(); + testConstructorWithModule(); + } + + static void testConstructor() { StackTraceElement ste = new StackTraceElement("com.acme.Widget", - "frobnicate", "Widget.java", 42); + "frobnicate", + "Widget.java", 42); if (!(ste.getClassName().equals("com.acme.Widget") && - ste.getFileName().equals("Widget.java") && - ste.getMethodName().equals("frobnicate") && - ste.getLineNumber() == 42)) + ste.getFileName().equals("Widget.java") && + ste.getMethodName().equals("frobnicate") && + ste.getLineNumber() == 42)) throw new RuntimeException("1"); + if (ste.isNativeMethod()) throw new RuntimeException("2"); - StackTraceElement ste2 - = new StackTraceElement("jdk.module", - "9.0", - "com.acme.Widget", - "frobnicate", - "Widget.java", - 42); - if (!(ste2.getClassName().equals("com.acme.Widget") && - ste2.getModuleName().equals("jdk.module") && - ste2.getModuleVersion().equals("9.0") && - ste2.getFileName().equals("Widget.java") && - ste2.getMethodName().equals("frobnicate") && - ste2.getLineNumber() == 42)) + + assertEquals(ste.toString(), + "com.acme.Widget.frobnicate(Widget.java:42)"); + + StackTraceElement ste1 = new StackTraceElement("com.acme.Widget", + "frobnicate", + "Widget.java", + -2); + if (!ste1.isNativeMethod()) throw new RuntimeException("3"); - if (ste2.isNativeMethod()) + + assertEquals(ste1.toString(), + "com.acme.Widget.frobnicate(Native Method)"); + } + + static void testConstructorWithModule() { + StackTraceElement ste = new StackTraceElement("app", + "jdk.module", + "9.0", + "com.acme.Widget", + "frobnicate", + "Widget.java", + 42); + if (!(ste.getClassName().equals("com.acme.Widget") && + ste.getModuleName().equals("jdk.module") && + ste.getModuleVersion().equals("9.0") && + ste.getClassLoaderName().equals("app") && + ste.getFileName().equals("Widget.java") && + ste.getMethodName().equals("frobnicate") && + ste.getLineNumber() == 42)) + throw new RuntimeException("3"); + + if (ste.isNativeMethod()) throw new RuntimeException("4"); - StackTraceElement ste3 = new StackTraceElement("com.acme.Widget", - "frobnicate", "Widget.java", -2); - if (!ste3.isNativeMethod()) - throw new RuntimeException("5"); + + assertEquals(ste.toString(), + "app/jdk.module@9.0/com.acme.Widget.frobnicate(Widget.java:42)"); + } + + static void assertEquals(String s, String expected) { + if (!s.equals(expected)) { + throw new RuntimeException("Expected: " + expected + " but found: " + s); + } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackTraceElement/SerialTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2016, 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 6479237 + * @summary Test the format of StackTraceElement::toString and its serial form + * @modules java.logging + * java.xml.bind + * @run main SerialTest + */ + +import javax.xml.bind.JAXBElement; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.logging.Logger; + +public class SerialTest { + private static final Path SER_DIR = Paths.get("sers"); + private static final String JAVA_BASE = "java.base"; + private static final String JAVA_LOGGING = "java.logging"; + private static final String JAVA_XML_BIND = "java.xml.bind"; + + private static boolean isImage; + + public static void main(String... args) throws Exception { + Files.createDirectories(SER_DIR); + + // detect if exploded image build + Path home = Paths.get(System.getProperty("java.home")); + isImage = Files.exists(home.resolve("lib").resolve("modules")); + + // test stack trace from built-in loaders + try { + Logger.getLogger(null); + } catch (NullPointerException e) { + Arrays.stream(e.getStackTrace()) + .filter(ste -> ste.getClassName().startsWith("java.util.logging.") || + ste.getClassName().equals("SerialTest")) + .forEach(SerialTest::test); + } + + // test stack trace with upgradeable module + try { + new JAXBElement(null, null, null); + } catch (IllegalArgumentException e) { + Arrays.stream(e.getStackTrace()) + .filter(ste -> ste.getModuleName() != null) + .forEach(SerialTest::test); + } + + // test stack trace with class loader name from other class loader + Loader loader = new Loader("myloader"); + Class<?> cls = Class.forName("SerialTest", true, loader); + Method method = cls.getMethod("throwException"); + StackTraceElement ste = (StackTraceElement)method.invoke(null); + test(ste, loader); + + // verify the class loader name and in the stack trace + if (!cls.getClassLoader().getName().equals("myloader.hacked")) { + throw new RuntimeException("Unexpected loader name: " + + cls.getClassLoader().getName()); + } + if (!ste.getClassLoaderName().equals("myloader")) { + throw new RuntimeException("Unexpected loader name: " + + ste.getClassLoaderName()); + } + } + + private static void test(StackTraceElement ste) { + test(ste, null); + } + + private static void test(StackTraceElement ste, ClassLoader loader) { + try { + SerialTest serialTest = new SerialTest(ste); + StackTraceElement ste2 = serialTest.serialize().deserialize(); + System.out.println(ste2); + // verify StackTraceElement::toString returns the same string + if (!ste.equals(ste2) || !ste.toString().equals(ste2.toString())) { + throw new RuntimeException(ste + " != " + ste2); + } + + String mn = ste.getModuleName(); + if (mn != null) { + switch (mn) { + case JAVA_BASE: + case JAVA_LOGGING: + checkNamedModule(ste, loader, false); + break; + case JAVA_XML_BIND: + // for exploded build, no version is shown + checkNamedModule(ste, loader, isImage); + break; + default: // ignore + } + } else { + checkUnnamedModule(ste, loader); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private static void checkUnnamedModule(StackTraceElement ste, ClassLoader loader) { + String mn = ste.getModuleName(); + String s = ste.toString(); + int i = s.indexOf('/'); + + if (mn != null) { + throw new RuntimeException("expected null but got " + mn); + } + + if (loader != null) { + // Expect <loader>//<classname>.<method>(<src>:<ln>) + if (i <= 0) { + throw new RuntimeException("loader name missing: " + s); + } + if (!getLoaderName(loader).equals(s.substring(0, i))) { + throw new RuntimeException("unexpected loader name: " + s); + } + int j = s.substring(i+1).indexOf('/'); + if (j != 0) { + throw new RuntimeException("unexpected element for unnamed module: " + s); + } + } + } + + /* + * Loader::getName is overridden to return some other name + */ + private static String getLoaderName(ClassLoader loader) { + if (loader == null) + return ""; + + if (loader instanceof Loader) { + return ((Loader) loader).name; + } else { + return loader.getName(); + } + } + + private static void checkNamedModule(StackTraceElement ste, + ClassLoader loader, + boolean showVersion) { + String loaderName = getLoaderName(loader); + String mn = ste.getModuleName(); + String s = ste.toString(); + int i = s.indexOf('/'); + + if (mn == null) { + throw new RuntimeException("expected module name: " + s); + } + + if (i <= 0) { + throw new RuntimeException("module name missing: " + s); + } + + // Expect <module>/<classname>.<method>(<src>:<ln>) + if (!loaderName.isEmpty()) { + throw new IllegalArgumentException(loaderName); + } + + // <module>: name@version + int j = s.indexOf('@'); + if ((showVersion && j <= 0) || (!showVersion && j >= 0)) { + throw new RuntimeException("unexpected version: " + s); + } + + String name = j < 0 ? s.substring(0, i) : s.substring(0, j); + if (!name.equals(mn)) { + throw new RuntimeException("unexpected module name: " + s); + } + } + + private final Path ser; + private final StackTraceElement ste; + SerialTest(StackTraceElement ste) throws IOException { + this.ser = Files.createTempFile(SER_DIR, "SerialTest", ".ser"); + this.ste = ste; + } + + private StackTraceElement deserialize() throws IOException { + try (InputStream in = Files.newInputStream(ser); + BufferedInputStream bis = new BufferedInputStream(in); + ObjectInputStream ois = new ObjectInputStream(bis)) { + return (StackTraceElement)ois.readObject(); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + private SerialTest serialize() throws IOException { + try (OutputStream out = Files.newOutputStream(ser); + BufferedOutputStream bos = new BufferedOutputStream(out); + ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(ste); + } + return this; + } + + + public static StackTraceElement throwException() { + try { + Integer.parseInt(null); + } catch (NumberFormatException e) { + return Arrays.stream(e.getStackTrace()) + .filter(ste -> ste.getMethodName().equals("throwException")) + .findFirst().get(); + } + return null; + } + + public static class Loader extends URLClassLoader { + final String name; + Loader(String name) throws MalformedURLException { + super(name, new URL[] { testClassesURL() } , null); + this.name = name; + } + + private static URL testClassesURL() throws MalformedURLException { + Path path = Paths.get(System.getProperty("test.classes")); + return path.toUri().toURL(); + } + + public String getName() { + return name + ".hacked"; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackTraceElement/WithClassLoaderName.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016, 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 6479237 + * @summary Basic test StackTraceElement with class loader names + * @library lib /lib/testlibrary + * @build m1/* WithClassLoaderName + * @run main/othervm m1/com.app.Main + * @run main/othervm WithClassLoaderName + */ + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.nio.file.Paths; + +import com.app.Utils; + +public class WithClassLoaderName { + private static final String TEST_SRC = System.getProperty("test.src"); + private static final String SRC_FILENAME = "WithClassLoaderName.java"; + + private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); + private static final Path CLASSES_DIR = Paths.get("classes"); + private static final String THROW_EXCEPTION_CLASS = "p.ThrowException"; + + public static void main(String... args) throws Exception { + /* + * Test the following frames both have the same class loader name "app" + * com.app.Test::test + * WithClassLoaderName::test + */ + Utils.verify(WithClassLoaderName.class, "app", "main", SRC_FILENAME); + + /* + * Test StackTraceElement for a class loaded by a named URLClassLoader + */ + compile(); + testURLClassLoader("myloader"); + + // loader name same as application class loader + testURLClassLoader("app"); + } + + private static void compile() throws Exception { + boolean rc = CompilerUtils.compile(SRC_DIR, CLASSES_DIR); + if (!rc) { + throw new RuntimeException("compilation fails"); + } + } + + public static void testURLClassLoader(String loaderName) throws Exception { + System.err.println("---- test URLClassLoader name: " + loaderName); + + URL[] urls = new URL[] { CLASSES_DIR.toUri().toURL() }; + ClassLoader parent = ClassLoader.getSystemClassLoader(); + URLClassLoader loader = new URLClassLoader(loaderName, urls, parent); + + Class<?> c = Class.forName(THROW_EXCEPTION_CLASS, true, loader); + Method method = c.getMethod("throwError"); + try { + // invoke p.ThrowException::throwError + method.invoke(null); + } catch (InvocationTargetException x) { + Throwable e = x.getCause(); + e.printStackTrace(); + + StackTraceElement[] stes = e.getStackTrace(); + StackWalker.StackFrame[] frames = new StackWalker.StackFrame[] { + Utils.makeStackFrame(c, "throwError", "ThrowException.java"), + Utils.makeStackFrame(WithClassLoaderName.class, "testURLClassLoader", + SRC_FILENAME), + Utils.makeStackFrame(WithClassLoaderName.class, "main", SRC_FILENAME), + }; + + // p.ThrowException.throwError + Utils.checkFrame(loaderName, frames[0], stes[0]); + // skip reflection frames + int i = 1; + while (i < stes.length) { + String cn = stes[i].getClassName(); + if (!cn.startsWith("java.lang.reflect.") && + !cn.startsWith("jdk.internal.reflect.")) + break; + i++; + } + // WithClassLoaderName.testURLClassLoader + Utils.checkFrame("app", frames[1], stes[i]); + + // WithClassLoaderName.main + Utils.checkFrame("app", frames[2], stes[i+1]); + + } + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackTraceElement/lib/m1/com/app/Main.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, 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. + */ + +package com.app; + +import java.lang.StackWalker.StackFrame; + +public class Main { + public static void main(String... args) throws Exception { + StackFrame frame = Utils.makeStackFrame(Main.class, "main", "Main.java"); + Utils.checkFrame("app", frame, caller()); + } + + private static StackTraceElement caller() { + StackTraceElement[] stes = Thread.currentThread().getStackTrace(); + return stes[2]; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackTraceElement/lib/m1/com/app/Utils.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016, 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. + */ + +package com.app; + +import java.lang.StackWalker.StackFrame; +import java.lang.module.ModuleDescriptor; +import java.lang.reflect.Module; +import java.util.Objects; + +public class Utils { + public static void verify(Class<?> caller, String loaderName, + String methodname, String filename) { + StackTraceElement[] stes = Thread.currentThread().getStackTrace(); + StackWalker.StackFrame[] frames = new StackFrame[] { + makeStackFrame(Utils.class, "verify", "Utils.java"), + makeStackFrame(caller, methodname, filename) + }; + + checkFrame("app", frames[0], stes[1]); + checkFrame(loaderName, frames[1], stes[2]); + } + + public static StackFrame makeStackFrame(Class<?> c, String methodname, String filename) { + return new StackFrame() { + @Override + public String getClassName() { + return c.getName(); + } + @Override + public String getMethodName() { + return methodname; + } + @Override + public Class<?> getDeclaringClass() { + return c; + } + @Override + public int getByteCodeIndex() { + return 0; + } + @Override + public String getFileName() { + return filename; + } + + @Override + public int getLineNumber() { + return 0; + } + @Override + public boolean isNativeMethod() { + return false; + } + @Override + public StackTraceElement toStackTraceElement() { + return null; + } + + private String getClassLoaderName(Class<?> c) { + ClassLoader loader = c.getClassLoader(); + String name = ""; + if (loader == null) { + name = "boot"; + } else if (loader.getName() != null) { + name = loader.getName(); + } + return name; + } + + @Override + public String toString() { + String mid = getClassLoaderName(c); + Module module = c.getModule(); + if (module.isNamed()) { + ModuleDescriptor md = module.getDescriptor(); + mid = md.name(); + if (md.version().isPresent()) + mid += "@" + md.version().get().toString(); + mid += "/"; + } + String fileName = getFileName(); + int lineNumber = getLineNumber(); + String sourceinfo = "Unknown Source"; + if (isNativeMethod()) { + sourceinfo = "Native Method"; + } else if (fileName != null && lineNumber >= 0) { + sourceinfo = fileName + ":" + lineNumber; + } + return String.format("%s/%s.%s(%s)", mid, getClassName(), getMethodName(), + sourceinfo); + + } + }; + } + + public static void checkFrame(String loaderName, StackFrame frame, + StackTraceElement ste) { + System.err.println("checking " + ste.toString() + " expected: " + frame.toString()); + Class<?> c = frame.getDeclaringClass(); + Module module = c.getModule(); + assertEquals(ste.getModuleName(), module.getName(), "module name"); + assertEquals(ste.getClassLoaderName(), loaderName, "class loader name"); + assertEquals(ste.getClassLoaderName(), c.getClassLoader().getName(), + "class loader name"); + assertEquals(ste.getClassName(), c.getName(), "class name"); + assertEquals(ste.getMethodName(), frame.getMethodName(), "method name"); + assertEquals(ste.getFileName(), frame.getFileName(), "file name"); + + } + private static void assertEquals(String actual, String expected, String msg) { + if (!Objects.equals(actual, expected)) + throw new AssertionError("Actual: " + actual + " Excepted: " + + expected + " mismatched " + msg); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackTraceElement/lib/m1/module-info.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016, 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. + */ + +module m1 { + exports com.app; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackTraceElement/src/p/ThrowException.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016, 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. + */ + +package p; + +import java.lang.StackWalker.StackFrame; + +public class ThrowException { + public static void throwError() { + throw new Error("testing"); + } +}
--- a/jdk/test/java/lang/StackWalker/VerifyStackTrace.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java Fri Nov 04 17:52:55 2016 +0000 @@ -71,7 +71,7 @@ "3: VerifyStackTrace$Handle.run(VerifyStackTrace.java:158)\n" + "4: VerifyStackTrace.invoke(VerifyStackTrace.java:188)\n" + "5: VerifyStackTrace$1.run(VerifyStackTrace.java:218)\n" + - "6: java.security.AccessController.doPrivileged(java.base/Native Method)\n" + + "6: java.base/java.security.AccessController.doPrivileged(Native Method)\n" + "7: VerifyStackTrace.test(VerifyStackTrace.java:227)\n" + "8: VerifyStackTrace.main(VerifyStackTrace.java:182)\n"; @@ -100,12 +100,12 @@ "2: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:147)\n" + "3: VerifyStackTrace$Handle.run(VerifyStackTrace.java:160)\n" + "4: VerifyStackTrace.invoke(VerifyStackTrace.java:190)\n" + - "5: jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base/Native Method)\n" + - "6: jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base/NativeMethodAccessorImpl.java:62)\n" + - "7: jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base/DelegatingMethodAccessorImpl.java:43)\n" + - "8: java.lang.reflect.Method.invoke(java.base/Method.java:520)\n" + + "5: java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" + + "6: java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n" + + "7: java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n" + + "8: java.base/java.lang.reflect.Method.invoke(Method.java:520)\n" + "9: VerifyStackTrace$1.run(VerifyStackTrace.java:220)\n" + - "10: java.security.AccessController.doPrivileged(java.base/Native Method)\n" + + "10: java.base/java.security.AccessController.doPrivileged(Native Method)\n" + "11: VerifyStackTrace.test(VerifyStackTrace.java:229)\n" + "12: VerifyStackTrace.main(VerifyStackTrace.java:185)\n"; @@ -133,16 +133,16 @@ "1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:213)\n" + "2: VerifyStackTrace$$Lambda$1/662441761.run(Unknown Source)\n" + "3: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:149)\n" + - "4: java.lang.invoke.LambdaForm$DMH/2008017533.invokeVirtual_LL_V(java.base/LambdaForm$DMH)\n" + - "5: java.lang.invoke.LambdaForm$MH/1395089624.invoke_MT(java.base/LambdaForm$MH)\n" + + "4: java.base/java.lang.invoke.LambdaForm$DMH/2008017533.invokeVirtual_LL_V(LambdaForm$DMH)\n" + + "5: java.base/java.lang.invoke.LambdaForm$MH/1395089624.invoke_MT(LambdaForm$MH)\n" + "6: VerifyStackTrace$Handle.run(VerifyStackTrace.java:162)\n" + "7: VerifyStackTrace.invoke(VerifyStackTrace.java:192)\n" + - "8: jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base/Native Method)\n" + - "9: jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base/NativeMethodAccessorImpl.java:62)\n" + - "10: jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base/DelegatingMethodAccessorImpl.java:43)\n" + - "11: java.lang.reflect.Method.invoke(java.base/Method.java:520)\n" + + "8: java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" + + "9: java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n" + + "10: java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n" + + "11: java.base/java.lang.reflect.Method.invoke(Method.java:520)\n" + "12: VerifyStackTrace$1.run(VerifyStackTrace.java:222)\n" + - "13: java.security.AccessController.doPrivileged(java.base/Native Method)\n" + + "13: java.base/java.security.AccessController.doPrivileged(Native Method)\n" + "14: VerifyStackTrace.test(VerifyStackTrace.java:231)\n" + "15: VerifyStackTrace.main(VerifyStackTrace.java:188)\n"; @@ -201,8 +201,6 @@ // out before comparing. We also erase the hash-like names of // synthetic frames introduced by lambdas & method handles return produced.replaceAll(":[1-9][0-9]*\\)", ":00)") - .replaceAll("-internal/", "/").replaceAll("-ea/", "/") - .replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/") .replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run") .replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke") // LFs may or may not be pre-generated, making frames differ
--- a/jdk/test/java/lang/annotation/AnnotationToStringTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/lang/annotation/AnnotationToStringTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8162817 + * @bug 8162817 8168921 * @summary Test of toString on normal annotations */ @@ -70,6 +70,8 @@ "d1=1.0/0.0, " + "l0=5, " + "l1=9223372036854775807L, " + + "l2=-9223372036854775808L, " + + "l3=-2147483648, " + "s0=\"Hello world.\", " + "s1=\"a\\\"b\", " + "class0=Obj[].class)") @@ -84,6 +86,8 @@ d1=2.0/0.0, l0=5, l1=Long.MAX_VALUE, + l2=Long.MIN_VALUE, + l3=Integer.MIN_VALUE, s0="Hello world.", s1="a\"b", class0=Obj[].class @@ -185,8 +189,10 @@ public int[] f6; @ExpectedString( - "@LongArray(value={-2147483647, 2147483648L, 9223372036854775807L})") - @LongArray(value={-Integer.MAX_VALUE, Integer.MAX_VALUE+1L, Long.MAX_VALUE}) + "@LongArray(value={-9223372036854775808L, -2147483649L, -2147483648," + + " -2147483647, 2147483648L, 9223372036854775807L})") + @LongArray(value={Long.MIN_VALUE, Integer.MIN_VALUE-1L, Integer.MIN_VALUE, + -Integer.MAX_VALUE, Integer.MAX_VALUE+1L, Long.MAX_VALUE}) public long[] f7; @ExpectedString( @@ -287,6 +293,8 @@ double d1(); long l0(); long l1(); + long l2(); + long l3(); String s0(); String s1(); Class<?> class0();
--- a/jdk/test/java/lang/management/CompositeData/ThreadInfoCompositeData.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/lang/management/CompositeData/ThreadInfoCompositeData.java Fri Nov 04 17:52:55 2016 +0000 @@ -337,9 +337,10 @@ }; private static final String[] steItemNames = { - "className", + "classLoaderName", "moduleName", "moduleVersion", + "className", "methodName", "fileName", "lineNumber", @@ -362,9 +363,10 @@ validItemTypes[STACK_TRACE] = new ArrayType(1, steCType); final Object[] steValue = { - ste[0].getClassName(), + ste[0].getClassLoaderName(), ste[0].getModuleName(), ste[0].getModuleVersion(), + ste[0].getClassName(), ste[0].getMethodName(), ste[0].getFileName(), new Integer(ste[0].getLineNumber()),
--- a/jdk/test/java/net/URLClassLoader/NullURLTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/net/URLClassLoader/NullURLTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -109,7 +109,7 @@ failures++; } try { - loader = new URLClassLoader(null, null, null); + loader = new URLClassLoader((URL[])null, null, null); System.err.println("URLClassLoader(null, null, null) did not throw NPE"); failures++; } catch (NullPointerException e) {
--- a/jdk/test/java/net/URLPermission/nstest/LookupTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/net/URLPermission/nstest/LookupTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -22,124 +22,195 @@ */ /** - * This is a simple smoke test of the HttpURLPermission mechanism, which - * checks for either IOException (due to unknown host) or SecurityException - * due to lack of permission to connect + * @test + * @summary A simple smoke test of the HttpURLPermission mechanism, which checks + * for either IOException (due to unknown host) or SecurityException + * due to lack of permission to connect + * @run main/othervm LookupTest */ -import java.net.*; -import java.io.*; -import jdk.testlibrary.Utils; +import java.io.BufferedWriter; +import java.io.FilePermission; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.net.NetPermission; +import java.net.ProxySelector; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketPermission; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLPermission; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import static java.nio.charset.StandardCharsets.US_ASCII; public class LookupTest { - static void test( - String url, boolean throwsSecException, boolean throwsIOException) - { + static int port; + static volatile ServerSocket serverSocket; + + static void test(String url, + boolean throwsSecException, + boolean throwsIOException) { + ProxySelector.setDefault(null); + URL u; + InputStream is = null; try { - ProxySelector.setDefault(null); - URL u = new URL(url); - System.err.println ("Connecting to " + u); + u = new URL(url); + System.err.println("Connecting to " + u); URLConnection urlc = u.openConnection(); - InputStream is = urlc.getInputStream(); + is = urlc.getInputStream(); } catch (SecurityException e) { if (!throwsSecException) { - throw new RuntimeException ("(1) was not expecting ", e); + throw new RuntimeException("Unexpected SecurityException:", e); } return; - } catch (IOException ioe) { + } catch (IOException e) { if (!throwsIOException) { - throw new RuntimeException ("(2) was not expecting ", ioe); + System.err.println("Unexpected IOException:" + e.getMessage()); + throw new RuntimeException(e); } return; + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + System.err.println("Unexpected IOException:" + e.getMessage()); + throw new RuntimeException(e); + } + } } + if (throwsSecException || throwsIOException) { - System.err.printf ("was expecting a %s\n", throwsSecException ? - "security exception" : "IOException"); + System.err.printf("was expecting a %s\n", throwsSecException + ? "security exception" : "IOException"); throw new RuntimeException("was expecting an exception"); } } - static int port; - static ServerSocket serverSocket; + static final String CWD = System.getProperty("user.dir", "."); public static void main(String args[]) throws Exception { - - - String cmd = args[0]; - if (cmd.equals("-getport")) { - port = Utils.getFreePort(); - System.out.print(port); - } else if (cmd.equals("-runtest")) { - port = Integer.parseInt(args[1]); - String hostsFileName = System.getProperty("user.dir", ".") + "/LookupTestHosts"; - System.setProperty("jdk.net.hosts.file", hostsFileName); - addMappingToHostsFile("allowedAndFound.com", "127.0.0.1", hostsFileName, false); - addMappingToHostsFile("notAllowedButFound.com", "99.99.99.99", hostsFileName, true); - // name "notAllowedAndNotFound.com" is not in map - // name "allowedButNotfound.com" is not in map - try { - startServer(); - - System.setSecurityManager(new SecurityManager()); - - test("http://allowedAndFound.com:" + port + "/foo", false, false); - - test("http://notAllowedButFound.com:" + port + "/foo", true, false); - - test("http://allowedButNotfound.com:" + port + "/foo", false, true); - - test("http://notAllowedAndNotFound.com:" + port + "/foo", true, false); - } finally { - serverSocket.close(); - } - } else { - throw new RuntimeException("Bad invocation: " + cmd); + String hostsFileName = CWD + "/LookupTestHosts"; + System.setProperty("jdk.net.hosts.file", hostsFileName); + addMappingToHostsFile("allowedAndFound.com", + "127.0.0.1", + hostsFileName, + false); + addMappingToHostsFile("notAllowedButFound.com", + "99.99.99.99", + hostsFileName, + true); + // name "notAllowedAndNotFound.com" is not in map + // name "allowedButNotfound.com" is not in map + Server server = new Server(); + try { + Policy.setPolicy(new LookupTestPolicy()); + System.setSecurityManager(new SecurityManager()); + server.start(); + test("http://allowedAndFound.com:" + port + "/foo", false, false); + test("http://notAllowedButFound.com:" + port + "/foo", true, false); + test("http://allowedButNotfound.com:" + port + "/foo", false, true); + test("http://notAllowedAndNotFound.com:" + port + "/foo", true, false); + } finally { + server.terminate(); } } - static Thread server; + static class Server extends Thread { + private volatile boolean done; - static class Server extends Thread { + public Server() throws IOException { + serverSocket = new ServerSocket(0); + port = serverSocket.getLocalPort(); + } + public void run() { - byte[] buf = new byte[1000]; try { - while (true) { - Socket s = serverSocket.accept(); - InputStream i = s.getInputStream(); - i.read(buf); - OutputStream o = s.getOutputStream(); - String rsp = "HTTP/1.1 200 Ok\r\n" + - "Connection: close\r\nContent-length: 0\r\n\r\n"; - o.write(rsp.getBytes()); - o.close(); + while (!done) { + try (Socket s = serverSocket.accept()) { + readOneRequest(s.getInputStream()); + OutputStream o = s.getOutputStream(); + String rsp = "HTTP/1.1 200 Ok\r\n" + + "Connection: close\r\n" + + "Content-length: 0\r\n\r\n"; + o.write(rsp.getBytes(US_ASCII)); + } } } catch (IOException e) { - return; + if (!done) + e.printStackTrace(); } + } + + void terminate() { + done = true; + try { serverSocket.close(); } + catch (IOException unexpected) { unexpected.printStackTrace(); } + } + + static final byte[] requestEnd = new byte[] {'\r', '\n', '\r', '\n' }; + + // Read until the end of a HTTP request + void readOneRequest(InputStream is) throws IOException { + int requestEndCount = 0, r; + while ((r = is.read()) != -1) { + if (r == requestEnd[requestEndCount]) { + requestEndCount++; + if (requestEndCount == 4) { + break; + } + } else { + requestEndCount = 0; + } } - } - - static void startServer() { - try { - serverSocket = new ServerSocket(port); - server = new Server(); - server.start(); - } catch (Exception e) { - throw new RuntimeException ("Test failed to initialize", e); } } - private static void addMappingToHostsFile (String host, - String addr, - String hostsFileName, - boolean append) - throws Exception { + private static void addMappingToHostsFile(String host, + String addr, + String hostsFileName, + boolean append) + throws IOException + { String mapping = addr + " " + host; - try (PrintWriter hfPWriter = new PrintWriter(new BufferedWriter( - new FileWriter(hostsFileName, append)))) { + try (FileWriter fr = new FileWriter(hostsFileName, append); + PrintWriter hfPWriter = new PrintWriter(new BufferedWriter(fr))) { hfPWriter.println(mapping); -} + } } + static class LookupTestPolicy extends Policy { + final PermissionCollection perms = new Permissions(); + + LookupTestPolicy() throws Exception { + perms.add(new NetPermission("setProxySelector")); + perms.add(new SocketPermission("localhost:1024-", "resolve,accept")); + perms.add(new URLPermission("http://allowedAndFound.com:" + port + "/-", "*:*")); + perms.add(new URLPermission("http://allowedButNotfound.com:" + port + "/-", "*:*")); + perms.add(new FilePermission("<<ALL FILES>>", "read,write,delete")); + //perms.add(new PropertyPermission("java.io.tmpdir", "read")); + } + + public PermissionCollection getPermissions(ProtectionDomain domain) { + return perms; + } + + public PermissionCollection getPermissions(CodeSource codesource) { + return perms; + } + + public boolean implies(ProtectionDomain domain, Permission perm) { + return perms.implies(perm); + } + } }
--- a/jdk/test/java/net/URLPermission/nstest/lookup.sh Fri Nov 04 17:24:24 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2013, 2016 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 -# @library /lib/testlibrary -# @build jdk.testlibrary.* -# @compile -XDignore.symbol.file=true LookupTest.java -# @run shell/timeout=50 lookup.sh -# @key intermittent -# - -OS=`uname -s` -case ${OS} in -Windows_* | CYGWIN*) - PS=";" - FS="\\" - ;; -*) - PS=":" - FS="/" - ;; -esac - -port=`${TESTJAVA}/bin/java -cp ${TESTCLASSPATH} LookupTest -getport` - -cat << POLICY > policy -grant { - permission java.net.URLPermission "http://allowedAndFound.com:${port}/-", "*:*"; - permission java.net.URLPermission "http://allowedButNotfound.com:${port}/-", "*:*"; - permission java.net.NetPermission "setProxySelector"; - permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete"; - permission java.util.PropertyPermission "java.io.tmpdir", "read"; - - // needed for HttpServer - permission "java.net.SocketPermission" "localhost:1024-", "resolve,accept"; -}; -POLICY - -${TESTJAVA}/bin/java ${TESTVMOPTS} \ - -Djava.security.policy=file:./policy \ - -Dtest.src=${TESTSRC} \ - -cp ${TESTCLASSPATH}${PS}${TESTSRC} LookupTest -runtest ${port}
--- a/jdk/test/java/net/httpclient/APIErrors.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/net/httpclient/APIErrors.java Fri Nov 04 17:52:55 2016 +0000 @@ -21,10 +21,11 @@ * questions. */ -/** +/* * @test * @bug 8087112 * @modules java.httpclient + * java.logging * jdk.httpserver * @library /lib/testlibrary/ * @build jdk.testlibrary.SimpleSSLContext ProxyServer @@ -35,13 +36,23 @@ */ //package javaapplication16; -import com.sun.net.httpserver.*; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsServer; import java.io.IOException; -import java.net.*; -import java.net.http.*; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.ProxySelector; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.util.LinkedList; import java.util.List; -import java.util.concurrent.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; import java.util.function.Supplier; /**
--- a/jdk/test/java/net/httpclient/ManyRequests.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/net/httpclient/ManyRequests.java Fri Nov 04 17:52:55 2016 +0000 @@ -21,10 +21,11 @@ * questions. */ -/** +/* * @test * @bug 8087112 * @modules java.httpclient + * java.logging * jdk.httpserver * @library /lib/testlibrary/ / * @build jdk.testlibrary.SimpleSSLContext EchoHandler @@ -36,7 +37,9 @@ //package javaapplication16; -import com.sun.net.httpserver.*; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsParameters; +import com.sun.net.httpserver.HttpsServer; import java.io.IOException; import java.io.UncheckedIOException; import java.net.http.HttpClient; @@ -48,9 +51,10 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.Random; -import java.util.logging.*; +import java.util.logging.Logger; +import java.util.logging.Level; import java.util.concurrent.CompletableFuture; -import javax.net.ssl.*; +import javax.net.ssl.SSLContext; import jdk.testlibrary.SimpleSSLContext; public class ManyRequests {
--- a/jdk/test/java/net/httpclient/RequestBodyTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/net/httpclient/RequestBodyTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -21,9 +21,10 @@ * questions. */ -/** +/* * @test @bug 8087112 * @modules java.httpclient + * java.logging * jdk.httpserver * @library /lib/testlibrary/ / * @compile ../../../com/sun/net/httpserver/LogFilter.java
--- a/jdk/test/java/net/httpclient/SmokeTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/net/httpclient/SmokeTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -21,10 +21,11 @@ * questions. */ -/** +/* * @test * @bug 8087112 * @modules java.httpclient + * java.logging * jdk.httpserver * @library /lib/testlibrary/ / * @build jdk.testlibrary.SimpleSSLContext ProxyServer EchoHandler @@ -33,13 +34,40 @@ * @run main/othervm SmokeTest */ -import com.sun.net.httpserver.*; -import java.net.*; -import java.net.http.*; -import java.io.*; -import java.util.concurrent.*; -import javax.net.ssl.*; -import java.nio.file.*; +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsParameters; +import com.sun.net.httpserver.HttpsServer; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.ProxySelector; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.HashSet; import java.util.LinkedList; import java.util.List;
--- a/jdk/test/java/net/httpclient/security/Driver.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/Driver.java Fri Nov 04 17:52:55 2016 +0000 @@ -28,6 +28,7 @@ * @bug 8087112 * @library /lib/testlibrary/ * @modules java.httpclient + * java.logging * jdk.httpserver * @build jdk.testlibrary.SimpleSSLContext jdk.testlibrary.Utils * @compile ../../../../com/sun/net/httpserver/LogFilter.java
--- a/jdk/test/java/net/httpclient/security/Security.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/Security.java Fri Nov 04 17:52:55 2016 +0000 @@ -23,10 +23,11 @@ * questions. */ -/** +/* * @test * @bug 8087112 * @modules java.httpclient + * java.logging * jdk.httpserver * @library /lib/testlibrary/ * @build jdk.testlibrary.SimpleSSLContext @@ -50,14 +51,27 @@ // Tests 1, 10, 11 and 12 executed from Driver -import com.sun.net.httpserver.*; +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsServer; import java.io.IOException; import java.io.InputStream; import java.io.File; import java.io.OutputStream; import java.lang.reflect.Constructor; -import java.net.*; -import java.net.http.*; +import java.net.BindException; +import java.net.InetSocketAddress; +import java.net.ProxySelector; +import java.net.URI; +import java.net.URLClassLoader; +import java.net.URL; +import java.net.http.HttpHeaders; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -66,13 +80,15 @@ import java.nio.file.StandardCopyOption; import java.util.LinkedList; import java.util.List; -import java.util.concurrent.*; -import java.util.function.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.function.LongConsumer; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.Logger; import java.lang.reflect.InvocationTargetException; -import java.net.BindException; /** * Security checks test
--- a/jdk/test/java/net/ipv6tests/Tests.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/net/ipv6tests/Tests.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -139,11 +139,17 @@ /* check the time got is within 50% of the time expected */ public static void checkTime (long got, long expected) { - dprintln ("checkTime: got " + got + " expected " + expected); - long upper = expected + (expected / 2); - long lower = expected - (expected / 2); + checkTime(got, expected, expected); + } + + /* check the time got is between start and end, given 50% tolerance */ + public static void checkTime(long got, long start, long end) { + dprintln("checkTime: got = " + got + " start = " + start + " end = " + end); + long upper = end + (end / 2); + long lower = start - (start / 2); if (got > upper || got < lower) { - throw new RuntimeException ("checkTime failed: got " + got + " expected " + expected); + throw new RuntimeException("checkTime failed: got " + got + + ", expected between " + start + " and " + end); } }
--- a/jdk/test/java/net/ipv6tests/UdpTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/net/ipv6tests/UdpTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -24,7 +24,6 @@ /* * @test * @bug 4868820 - * @key intermittent * @summary IPv6 support for Windows XP and 2003 server */ @@ -159,7 +158,7 @@ }); t1 = System.currentTimeMillis(); s1.receive (new DatagramPacket (new byte [128], 128)); - checkTime (System.currentTimeMillis() - t1, 4000); + checkTime (System.currentTimeMillis() - t1, 2000, 10000); s1.close (); s2.close (); System.out.println ("Test2: OK");
--- a/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/ThowableHelper.java Fri Nov 04 17:24:24 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * 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. - */ -package java.util.stream; - -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; - -public final class ThowableHelper { - - public static void checkException(Class<? extends Exception> ce, Runnable r) { - Exception caught = null; - try { - r.run(); - } catch (Exception e) { - caught = e; - } - - assertNotNull(caught); - assertTrue(ce.isInstance(caught)); - } - - public static void checkNPE(Runnable r) { - checkException(NullPointerException.class, r); - } - - public static void checkISE(Runnable r) { - checkException(IllegalStateException.class, r); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/ThrowableHelper.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, 2016, 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. + */ +package java.util.stream; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +public final class ThrowableHelper { + + public static void checkException(Class<? extends Exception> ce, Runnable r) { + Exception caught = null; + try { + r.run(); + } catch (Exception e) { + caught = e; + } + + assertNotNull(caught); + assertTrue(ce.isInstance(caught)); + } + + public static void checkNPE(Runnable r) { + checkException(NullPointerException.class, r); + } + + public static void checkISE(Runnable r) { + checkException(IllegalStateException.class, r); + } +}
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ import java.util.stream.OpTestCase; import static java.util.stream.LambdaTestHelpers.countTo; -import static java.util.stream.ThowableHelper.checkNPE; +import static java.util.stream.ThrowableHelper.checkNPE; @Test public class CollectAndSummaryStatisticsTest extends OpTestCase {
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectionAndMapModifyStreamTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectionAndMapModifyStreamTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, 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 @@ -113,7 +113,7 @@ Map<String, Supplier<Map<Integer, Integer>>> maps = new HashMap<>(); maps.put(HashMap.class.getName(), () -> new HashMap<>(content)); - maps.put(HashMap.class.getName(), () -> new LinkedHashMap<>(content)); + maps.put(LinkedHashMap.class.getName(), () -> new LinkedHashMap<>(content)); maps.put(IdentityHashMap.class.getName(), () -> new IdentityHashMap<>(content)); maps.put(WeakHashMap.class.getName(), () -> new WeakHashMap<>(content));
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -49,7 +49,7 @@ import java.util.stream.TestData; import static java.util.stream.LambdaTestHelpers.*; -import static java.util.stream.ThowableHelper.checkNPE; +import static java.util.stream.ThrowableHelper.checkNPE; @Test public class FlatMapOpTest extends OpTestCase {
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IterateTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IterateTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -38,7 +38,7 @@ import java.util.stream.TestData; import java.util.stream.TestData.Factory; -import static java.util.stream.ThowableHelper.checkNPE; +import static java.util.stream.ThrowableHelper.checkNPE; import org.testng.annotations.DataProvider; import org.testng.annotations.Test;
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, 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 @@ -38,7 +38,7 @@ import java.util.stream.TestData; import static java.util.stream.Collectors.toList; -import static java.util.stream.ThowableHelper.checkISE; +import static java.util.stream.ThrowableHelper.checkISE; @Test public class StreamBuilderTest extends OpTestCase {
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java Fri Nov 04 17:24:24 2016 +0000 +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java Fri Nov 04 17:52:55 2016 +0000 @@ -36,8 +36,8 @@ import org.testng.annotations.Test; import static java.util.stream.LambdaTestHelpers.countTo; -import static java.util.stream.ThowableHelper.checkNPE; -import static java.util.stream.ThowableHelper.checkISE; +import static java.util.stream.ThrowableHelper.checkNPE; +import static java.util.stream.ThrowableHelper.checkISE; @Test(groups = { "serialization-hostile" }) public class StreamCloseTest extends OpTestCase {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/net/ssl/SSLEngine/EngineCloseOnAlert.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2004, 2016, 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 8133632 + * @summary javax.net.ssl.SSLEngine does not properly handle received + * SSL fatal alerts + * @run main/othervm EngineCloseOnAlert + */ + +import java.io.FileInputStream; +import java.io.IOException; +import javax.net.ssl.*; +import java.nio.ByteBuffer; +import java.util.*; +import java.security.*; +import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*; + +public class EngineCloseOnAlert { + + private static final String pathToStores = "../etc"; + private static final String keyStoreFile = "keystore"; + private static final String trustStoreFile = "truststore"; + private static final String passwd = "passphrase"; + private static final String keyFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + keyStoreFile; + private static final String trustFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + trustStoreFile; + + private static KeyManagerFactory KMF; + private static TrustManagerFactory TMF; + private static TrustManagerFactory EMPTY_TMF; + + private static final String[] TLS10ONLY = { "TLSv1" }; + private static final String[] TLS12ONLY = { "TLSv1.2" }; + private static final String[] ONECIPHER = + { "TLS_RSA_WITH_AES_128_CBC_SHA" }; + + public interface TestCase { + public void runTest() throws Exception; + } + + public static void main(String[] args) throws Exception { + int failed = 0; + List<TestCase> testMatrix = new LinkedList<TestCase>() {{ + add(clientReceivesAlert); + add(serverReceivesAlert); + }}; + + // Create the various key/trust manager factories we'll need + createManagerFactories(); + + for (TestCase test : testMatrix) { + try { + test.runTest(); + } catch (Exception e) { + System.out.println("Exception in test:\n" + e); + e.printStackTrace(System.out); + failed++; + } + } + + System.out.println("Total tests: " + testMatrix.size() + ", passed: " + + (testMatrix.size() - failed) + ", failed: " + failed); + if (failed > 0) { + throw new RuntimeException("One or more tests failed."); + } + } + + private static final TestCase clientReceivesAlert = new TestCase() { + @Override + public void runTest() throws Exception { + System.out.println(""); + System.out.println("======================================="); + System.out.println("Test: Client receives alert from server"); + System.out.println("======================================="); + + // For this test, we won't initialize any keystore so the + // server will throw an exception because it has no key/cert to + // match the requested ciphers offered by the client. This + // will generate an alert from the server to the client. + + SSLContext context = SSLContext.getDefault(); + SSLEngine client = context.createSSLEngine(); + SSLEngine server = context.createSSLEngine(); + client.setUseClientMode(true); + server.setUseClientMode(false); + SSLEngineResult clientResult; + SSLEngineResult serverResult; + + ByteBuffer raw = ByteBuffer.allocate(32768); + ByteBuffer plain = ByteBuffer.allocate(32768); + + // Generate the client hello and have the server unwrap it + client.wrap(plain, raw); + checkEngineState(client, NEED_UNWRAP, false, false); + raw.flip(); + System.out.println("Client-to-Server:\n-----------------\n" + + dumpHexBytes(raw, 16, "\n", ":")); + + + // The server should need to run a delegated task while processing + // the client hello data. + serverResult = server.unwrap(raw, plain); + checkEngineState(server, NEED_TASK, false, false); + System.out.println("Server result: " + serverResult); + runDelegatedTasks(serverResult, server); + checkEngineState(server, NEED_WRAP, true, false); + + try { + raw.clear(); + serverResult = server.wrap(plain, raw); + System.out.println("Server result: " + serverResult); + runDelegatedTasks(serverResult, server); + } catch (SSLException e) { + // This is the expected code path + System.out.println("Server throws exception: " + e); + System.out.println("Server engine state: " + + "isInboundDone = "+ server.isInboundDone() + + ", isOutboundDone = " + server.isOutboundDone() + + ", handshake status = " + server.getHandshakeStatus()); + checkEngineState(server, NEED_WRAP, true, false); + } + raw.clear(); + + // The above should show that isInboundDone returns true, and + // handshake status is NEED_WRAP. That is the correct behavior, + // wrap will put a fatal alert message in the buffer. + serverResult = server.wrap(plain, raw); + System.out.println("Server result (wrap after exception): " + + serverResult); + System.out.println("Server engine closure state: isInboundDone=" + + server.isInboundDone() + ", isOutboundDone=" + + server.isOutboundDone()); + checkEngineState(server, NEED_UNWRAP, true, true); + raw.flip(); + + System.out.println("Server-to-Client:\n-----------------\n" + + dumpHexBytes(raw, 16, "\n", ":")); + + // Client side will read the fatal alert and throw exception. + try { + clientResult = client.unwrap(raw, plain); + System.out.println("Client result (unwrap alert): " + + clientResult); + } catch (SSLException e) { + System.out.println("Client throws exception: " + e); + System.out.println("Engine closure status: isInboundDone=" + + client.isInboundDone() + ", isOutboundDone=" + + client.isOutboundDone() + ", handshake status=" + + client.getHandshakeStatus()); + checkEngineState(client, NOT_HANDSHAKING, true, true); + } + raw.clear(); + + // Last test, we try to unwrap + clientResult = client.unwrap(raw, plain); + checkEngineState(client, NOT_HANDSHAKING, true, true); + System.out.println("Client result (wrap after exception): " + + clientResult); + } + }; + + private static final TestCase serverReceivesAlert = new TestCase() { + @Override + public void runTest() throws Exception { + SSLContext cliContext = SSLContext.getDefault(); + SSLContext servContext = SSLContext.getInstance("TLS"); + servContext.init(KMF.getKeyManagers(), TMF.getTrustManagers(), + null); + SSLEngine client = cliContext.createSSLEngine(); + SSLEngine server = servContext.createSSLEngine(); + client.setUseClientMode(true); + client.setEnabledProtocols(TLS12ONLY); + client.setEnabledCipherSuites(ONECIPHER); + server.setUseClientMode(false); + server.setEnabledProtocols(TLS10ONLY); + SSLEngineResult clientResult; + SSLEngineResult serverResult; + ByteBuffer raw = ByteBuffer.allocate(32768); + ByteBuffer plain = ByteBuffer.allocate(32768); + + System.out.println(""); + System.out.println("======================================="); + System.out.println("Test: Server receives alert from client"); + System.out.println("======================================="); + + // Generate the client hello and have the server unwrap it + checkEngineState(client, NOT_HANDSHAKING, false, false); + client.wrap(plain, raw); + checkEngineState(client, NEED_UNWRAP, false, false); + raw.flip(); + System.out.println("Client-to-Server:\n-----------------\n" + + dumpHexBytes(raw, 16, "\n", ":")); + + // The server should need to run a delegated task while processing + // the client hello data. + serverResult = server.unwrap(raw, plain); + checkEngineState(server, NEED_TASK, false, false); + runDelegatedTasks(serverResult, server); + checkEngineState(server, NEED_WRAP, false, false); + raw.compact(); + + // The server should now wrap the response back to the client + server.wrap(plain, raw); + checkEngineState(server, NEED_UNWRAP, false, false); + raw.flip(); + System.out.println("Server-to-Client:\n-----------------\n" + + dumpHexBytes(raw, 16, "\n", ":")); + + // The client should parse this and throw an exception because + // It is unwiling to do TLS 1.0 + clientResult = client.unwrap(raw, plain); + checkEngineState(client, NEED_TASK, false, false); + runDelegatedTasks(clientResult, client); + checkEngineState(client, NEED_UNWRAP, false, false); + + try { + client.unwrap(raw, plain); + } catch (SSLException e) { + System.out.println("Client throws exception: " + e); + System.out.println("Engine closure status: isInboundDone=" + + client.isInboundDone() + ", isOutboundDone=" + + client.isOutboundDone() + ", handshake status=" + + client.getHandshakeStatus()); + checkEngineState(client, NEED_WRAP, true, false); + } + raw.clear(); + + // Now the client should wrap the exception + client.wrap(plain, raw); + checkEngineState(client, NEED_UNWRAP, true, true); + raw.flip(); + System.out.println("Client-to-Server:\n-----------------\n" + + dumpHexBytes(raw, 16, "\n", ":")); + + try { + server.unwrap(raw, plain); + checkEngineState(server, NEED_UNWRAP, false, false); + } catch (SSLException e) { + System.out.println("Server throws exception: " + e); + System.out.println("Engine closure status: isInboundDone=" + + server.isInboundDone() + ", isOutboundDone=" + + server.isOutboundDone() + ", handshake status=" + + server.getHandshakeStatus()); + checkEngineState(server, NOT_HANDSHAKING, true, true); + } + raw.clear(); + } + }; + + + /* + * If the result indicates that we have outstanding tasks to do, + * go ahead and run them in this thread. + */ + private static void runDelegatedTasks(SSLEngineResult result, + SSLEngine engine) throws Exception { + + if (result.getHandshakeStatus() == + SSLEngineResult.HandshakeStatus.NEED_TASK) { + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + System.out.println("\trunning delegated task..."); + runnable.run(); + } + SSLEngineResult.HandshakeStatus hsStatus = + engine.getHandshakeStatus(); + if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_TASK) { + throw new Exception( + "handshake shouldn't need additional tasks"); + } + System.out.println("\tnew HandshakeStatus: " + hsStatus); + } + } + + /** + * + * @param data The array of bytes to dump to stdout. + * @param itemsPerLine The number of bytes to display per line + * if the {@code lineDelim} character is blank then all bytes will be + * printed on a single line. + * @param lineDelim The delimiter between lines + * @param itemDelim The delimiter between bytes + * + * @return The hexdump of the byte array + */ + private static String dumpHexBytes(ByteBuffer data, int itemsPerLine, + String lineDelim, String itemDelim) { + StringBuilder sb = new StringBuilder(); + + if (data != null) { + data.mark(); + for (int i = 0; i < data.limit(); i++) { + if (i % itemsPerLine == 0 && i != 0) { + sb.append(lineDelim); + } + sb.append(String.format("%02X", data.get(i))); + if (i % itemsPerLine != (itemsPerLine - 1) && + i != (data.limit() -1)) { + sb.append(itemDelim); + } + } + data.reset(); + } + + return sb.toString(); + } + + private static void createManagerFactories() + throws GeneralSecurityException, IOException { + KeyStore keystore = KeyStore.getInstance("PKCS12"); + KeyStore truststore = KeyStore.getInstance("PKCS12"); + KeyStore empty_ts = KeyStore.getInstance("PKCS12"); + char[] passphrase = passwd.toCharArray(); + + keystore.load(new FileInputStream(keyFilename), passphrase); + truststore.load(new FileInputStream(trustFilename), passphrase); + empty_ts.load(null, "".toCharArray()); + + KMF = KeyManagerFactory.getInstance("PKIX"); + KMF.init(keystore, passphrase); + TMF = TrustManagerFactory.getInstance("PKIX"); + TMF.init(truststore); + EMPTY_TMF = TrustManagerFactory.getInstance("PKIX"); + EMPTY_TMF.init(truststore); + } + + private static void checkEngineState(SSLEngine engine, + SSLEngineResult.HandshakeStatus expectedHSStat, + boolean expectedInboundDone, boolean expectedOutboundDone) { + if (engine.getHandshakeStatus() != expectedHSStat || + engine.isInboundDone() != expectedInboundDone || + engine.isOutboundDone() != expectedOutboundDone) { + throw new RuntimeException("Error: engine not in expected state\n" + + "Expected: state = " + expectedHSStat + + ", inDone = " + expectedInboundDone + + ", outDone = " + expectedOutboundDone + "\n" + + "Actual: state = " + engine.getHandshakeStatus() + + ", inDone = " + engine.isInboundDone() + + ", outDone = " + engine.isOutboundDone()); + } else { + System.out.println((engine.getUseClientMode() ? + "Client" : "Server") + " handshake status: " + + engine.getHandshakeStatus() + ", inDone = " + + engine.isInboundDone() + ", outDone = " + + engine.isOutboundDone()); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/Devices/ClosedReceiver.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2003, 2016, 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 javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Synthesizer; + +/** + * @test + * @bug 4616517 + * @summary Receiver.send() does not work properly + */ +public class ClosedReceiver { + + public static void main(String[] args) throws Exception { + out("#4616517: Receiver.send() does not work properly"); + if (!isMidiInstalled()) { + out("Soundcard does not exist or sound drivers not installed!"); + out("This test requires sound drivers for execution."); + return; + } + + boolean passed = true; + + passed &= testReceiverSend(); + passed &= testClosedReceivers(); + if (passed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } + + /** + * Execute Receiver.send() and expect that there is no exception. + */ + private static boolean testReceiverSend() { + boolean result = true; + + Receiver receiver; + ShortMessage shMsg = new ShortMessage(); + + try { + receiver = MidiSystem.getReceiver(); + shMsg.setMessage(ShortMessage.NOTE_ON, 0,60, 93); + try { + receiver.send( shMsg, -1 ); + } catch(IllegalStateException ilEx) { + ilEx.printStackTrace(System.out); + out("IllegalStateException was thrown incorrectly!"); + result = false; + } + receiver.close(); + } catch(MidiUnavailableException e) { + out("Midi unavailable, cannot test."); + } catch(InvalidMidiDataException ine) { + out("InvalidMidiDataException, cannot test."); + } + return result; + } + + private static boolean testClosedReceivers() { + boolean result = true; + Receiver receiver; + Synthesizer synt = null; + + // test Synthesizer's Receiver + try { + synt = MidiSystem.getSynthesizer(); + synt.open(); + } catch(MidiUnavailableException e) { + out("Midi unavailable, cannot test."); + return result; + } + try { + receiver = synt.getReceiver(); + } catch (MidiUnavailableException e) { + out("unable to get Receiver from synthesizer, cannot test."); + return result; + } + result &= testClosedReceiver(receiver); + synt.close(); + + // test all MidiDevices' Receivers + + MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < devices.length; i++) { + try { + MidiDevice device = MidiSystem.getMidiDevice(devices[i]); + if (device.getMaxReceivers() != 0) { + receiver = device.getReceiver(); + result &= testClosedReceiver(receiver); + } + } catch (Exception e) { + out(e); + out("cannot test."); + return result; + } + } + return result; + } + + /** + * Execute send() on a closed Receivers and expect IllegalStateException. + */ + private static boolean testClosedReceiver(Receiver receiver) { + boolean result = true; + out("testing Receiver: " + receiver); + ShortMessage shMsg = new ShortMessage(); + try { + shMsg.setMessage(ShortMessage.NOTE_ON, 0,60, 93); + } catch(InvalidMidiDataException e) { + out(e); + out("unable to construct ShortMessage, cannot test."); + return result; + } + + // begin of test + receiver.close(); + try { + receiver.send( shMsg, -1 ); + out("IllegalStateException was not thrown " + + "on Receiver.send()!"); + result = false; + } catch(IllegalStateException e) { + out("IllegalStateException was thrown. Ok."); + } + return result; + } + + private static void out(Throwable t) { + t.printStackTrace(System.out); + } + + private static void out(String message) { + System.out.println(message); + } + + /** + * Returns true if at least one MIDI (port) device is correctly installed on + * the system. + */ + private static boolean isMidiInstalled() { + boolean result = false; + MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < devices.length; i++) { + try { + MidiDevice device = MidiSystem.getMidiDevice(devices[i]); + result = !(device instanceof Sequencer) + && !(device instanceof Synthesizer); + } catch (Exception e1) { + System.err.println(e1); + } + if (result) + break; + } + return result; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/Devices/IOLoop.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2002, 2016, 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.io.ByteArrayOutputStream; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiMessage; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Receiver; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.SysexMessage; +import javax.sound.midi.Transmitter; + +/** + * @test + * @bug 4782924 + * @bug 4812168 + * @bug 4356787 + * @summary MIDI i/o. This is an interactive test! Start it and follow the + * instructions. + * @run main/manual IOLoop + */ +public class IOLoop { + private static final int LONG_SYSEX_LENGTH = 2000; + + private static Receiver receiver; + private static Transmitter transmitter; + private static MidiMessage receivedMessage; + private static ByteArrayOutputStream baos; + private static int expectedBytes; + private static int receivedBytes; + private static Object lock = new Object(); + private static long lastTimestamp; + + public static void main(String[] args) throws Exception { + ShortMessage sMsg = new ShortMessage(); + SysexMessage syMsg = new SysexMessage(); + boolean isTestPassed = true; + boolean sysExTestPassed = true; + boolean isTestExecuted = true; + + out("To run this test successfully, you need to have attached"); + out(" your MIDI out port with the MIDI in port."); + + MidiDevice inDev = null; + MidiDevice outDev = null; + + // setup + try { + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + + int devNum = Integer.decode(args[0]).intValue(); + out("-> opening Transmitter from "+infos[devNum]); + inDev = MidiSystem.getMidiDevice(infos[devNum]); + inDev.open(); + transmitter = inDev.getTransmitter(); + Receiver testReceiver = new TestReceiver(); + transmitter.setReceiver(testReceiver); + + devNum = Integer.decode(args[1]).intValue(); + out("-> opening Receiver from "+infos[devNum]); + outDev = MidiSystem.getMidiDevice(infos[devNum]); + outDev.open(); + receiver = outDev.getReceiver(); + + } catch (Exception e) { + System.out.println(e); + System.out.println("Cannot test!"); + return; + } + + // test + sMsg.setMessage(ShortMessage.NOTE_OFF | 0, 27, 100); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.NOTE_OFF | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.NOTE_OFF | 15, 127, 127); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.NOTE_ON | 4, 27, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.NOTE_ON | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.NOTE_ON | 15, 127, 127); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.POLY_PRESSURE | 11, 98, 99); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.POLY_PRESSURE | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.POLY_PRESSURE | 15, 127, 127); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 13, 1, 63); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 15, 127, 127); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 2, 120, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 15, 127, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 6, 30, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 15, 127, 0); + isTestPassed &= testMessage(sMsg); + + sMsg.setMessage(ShortMessage.PITCH_BEND | 6, 56, 4); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.PITCH_BEND | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.PITCH_BEND | 15, 127, 127); + isTestPassed &= testMessage(sMsg); + + sMsg.setMessage(ShortMessage.MIDI_TIME_CODE, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.MIDI_TIME_CODE, 127, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 1, 77); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 127, 127); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_SELECT, 51, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_SELECT, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_SELECT, 127, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.TUNE_REQUEST); + isTestPassed &= testMessage(sMsg); + + sMsg.setMessage(ShortMessage.TIMING_CLOCK); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.START); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CONTINUE); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.STOP); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.ACTIVE_SENSING); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SYSTEM_RESET); + isTestPassed &= testMessage(sMsg); + + syMsg.setMessage(new byte[]{(byte) 0xF0, (byte) 0xF7}, 2); + isTestPassed &= testMessage(syMsg); + syMsg.setMessage(new byte[]{(byte) 0xF0, 0x01, (byte) 0xF7}, 3); + isTestPassed &= testMessage(syMsg); + syMsg.setMessage(new byte[]{(byte) 0xF0, 0x02, 0x03, (byte) 0xF7}, 4); + isTestPassed &= testMessage(syMsg); + syMsg.setMessage(new byte[]{(byte) 0xF0, 0x04, 0x05, 0x06, (byte) 0xF7}, 5); + isTestPassed &= testMessage(syMsg); + + if (isTestPassed) { + byte[] sysexArray = new byte[LONG_SYSEX_LENGTH]; + sysexArray[0] = (byte) 0xF0; + for (int i = 1; i < sysexArray.length; i++) { + sysexArray[i] = (byte) (i % 0x80); + } +// syMsg.setMessage(new byte[]{(byte) 0xF7, (byte) ShortMessage.START}, 2); +// sMsg.setMessage(ShortMessage.START); +// isTestPassed &= testMessage(syMsg, sMsg, DEFAULT_SLEEP_INTERVALL); + for (int trial = sysexArray.length; trial > 4; trial -= 1234) { + sleep(500); + sysexArray[trial - 1] = (byte) 0xF7; + syMsg.setMessage(sysexArray, trial); + sysExTestPassed &= testMessage(syMsg); + break; + } + } + + // cleanup + receiver.close(); + transmitter.close(); + inDev.close(); + outDev.close(); + + if (isTestExecuted) { + if (isTestPassed && sysExTestPassed) { + + out("Test PASSED."); + } else { + if (isTestPassed + && !sysExTestPassed + && (System.getProperty("os.name").startsWith("Windows"))) { + out("Some Windows MIDI i/o drivers have a problem with larger "); + out("sys ex messages. The failing sys ex cases are OK, therefore."); + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } + } else { + out("Test NOT FAILED"); + } + } + + private static boolean testMessage(MidiMessage message) { + receivedMessage = null; + baos = new ByteArrayOutputStream(); + expectedBytes = message.getLength(); + receivedBytes = 0; + System.out.print("Sending message " + getMessageString(message.getMessage())+"..."); + receiver.send(message, -1); + /* sending 3 bytes can roughly be done in 1 millisecond, + * so this estimate waits at max 3 times longer than the message takes, + * plus a little offset to allow the MIDI subsystem some processing time + */ + int offset = 300; // standard offset 100 millis + if (message instanceof SysexMessage) { + // add a little processing time to sysex messages + offset += 1000; + } + if (receivedBytes < expectedBytes) { + sleep(expectedBytes + offset); + } + boolean equal; + byte[] data = baos.toByteArray(); + if (data.length > 0) { + equal = messagesEqual(message.getMessage(), data); + } else { + equal = messagesEqual(message, receivedMessage); + if (receivedMessage != null) { + data = receivedMessage.getMessage(); + } else { + data = null; + } + } + if (!equal) { + if ((message.getStatus() & 0xF0) == ShortMessage.PITCH_BEND) { + out("NOT failed (may expose a bug in ALSA)"); + equal = true; + sleep(100); + } + if ((message.getStatus() == 0xF6) && (message.getLength() == 1)) { + out("NOT failed (may expose an issue on Solaris)"); + equal = true; + sleep(100); + } + else if ((message.getStatus()) == 0xF0 && message.getLength() < 4) { + out("NOT failed (not a correct sys ex message)"); + equal = true; + sleep(200); + } else { + out("FAILED:"); + out(" received as " + getMessageString(data)); + } + } else { + System.out.println("OK"); + } + return equal; + } + + private static void sleep(int milliseconds) { + synchronized(lock) { + try { + lock.wait(milliseconds); + } catch (InterruptedException e) { + } + } + } + + private static String getMessageString(byte[] data) { + String s; + if (data == null) { + s = "<null>"; + } else if (data.length == 0) { + s = "0-sized array"; + } else { + int status = data[0] & 0xFF; + if (data.length <= 3) { + if (status < 240) { + s = "command 0x" + Integer.toHexString(status & 0xF0) + " channel " + (status & 0x0F); + } else { + s = "status 0x" + Integer.toHexString(status); + } + if (data.length > 1) { + s += " data 0x" + Integer.toHexString(data[1] & 0xFF); + if (data.length > 2) { + s += " 0x" + Integer.toHexString(data[2] & 0xFF); + } + } + } else { + s = "status " + Integer.toHexString(status)+" and length "+data.length+" bytes"; + } + } + return s; + } + + private static boolean messagesEqual(MidiMessage m1, MidiMessage m2) { + if (m1 == null || m2 == null) { + return false; + } + if (m1.getLength() != m2.getLength()) { + return false; + } + byte[] array1 = m1.getMessage(); + byte[] array2 = m2.getMessage(); + return messagesEqual(array1, array2); + } + + private static boolean messagesEqual(byte[] a1, byte[] a2) { + if (a1.length != a2.length) return false; + for (int i = 0; i < a1.length; i++) { + if (a1[i] != a2[i]) { + return false; + } + } + return true; + } + + private static void out(String s) { + System.out.println(s); + System.out.flush(); + } + + private static String canIn(MidiDevice dev) { + if (dev.getMaxTransmitters() != 0) { + return "IN "; + } + return " "; + } + + private static String canOut(MidiDevice dev) { + if (dev.getMaxReceivers() != 0) { + return "OUT "; + } + return " "; + } + + + private static void checkTimestamp(long timestamp) { + // out("checking timestamp..."); + if (timestamp < 1) { + out("timestamp 0 or negative!"); + } + if (timestamp < lastTimestamp) { + out("timestamp not progressive!"); + } + lastTimestamp = timestamp; + } + + private static class TestReceiver implements Receiver { + public void send(MidiMessage message, long timestamp) { + //System.out.print(""+message.getLength()+".."); + checkTimestamp(timestamp); + try { + receivedMessage = message; + if (message.getStatus() == 0xF0 + || (message.getLength() > 3 && message.getStatus() != 0xF7)) { + // sys ex message + byte[] data = message.getMessage(); + baos.write(data); + receivedBytes += data.length; + } + else if (message.getStatus() == 0xF7) { + // sys ex cont'd message + byte[] data = message.getMessage(); + // ignore the prepended 0xF7 + baos.write(data, 1, data.length-1); + receivedBytes += (data.length - 1); + } else { + receivedBytes += message.getLength(); + } + if (receivedBytes >= expectedBytes) { + synchronized(lock) { + lock.notify(); + } + } + System.out.print(""+receivedBytes+".."); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void close() { + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/Devices/MidiDeviceGetReceivers.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Transmitter; + +/** + * @test + * @bug 4931387 + * @summary Add methods to MidiDevice to get list of Transmitters and Receivers + */ +public class MidiDeviceGetReceivers { + + private static boolean executed = false; + private static boolean failed = false; + + public static void main(String[] args) throws Exception { + out("unit test 4931387: Add methods to MidiDevice to get list of Transmitters and Receivers"); + doAllTests(); + if (executed) { + if (failed) throw new Exception("Test FAILED!"); + out("Test PASSED."); + } else { + out("Test NOT failed."); + } + } + + private static void doAllTests() { + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < infos.length; i++) { + MidiDevice device = null; + try { + device = MidiSystem.getMidiDevice(infos[i]); + doTest(device); + } catch (MidiUnavailableException e) { + out("Exception occured when retrieving device "+infos[i]+": "+e); + } + } + if (infos.length == 0) { + out("No MIDI devices exist or sound drivers not installed!"); + } + } + + private static boolean containsReceiver(MidiDevice dev, Receiver rec) { + List<Receiver> recvs = dev.getReceivers(); + return recvs.contains(rec); + } + + private static boolean containsTransmitter(MidiDevice dev, Transmitter tra) { + List<Transmitter> tras = dev.getTransmitters(); + return tras.contains(tra); + } + + private static void doTest(MidiDevice device) { + boolean thisFailed = false; + out1("Testing: " + device+"..."); + try { + device.open(); + } catch (Exception e) { + out2("device.open threw exception: "+e); + out2("cannot test this device."); + return; + } + if (device.getMaxReceivers() != 0) { + // device offers receivers + try { + List<Receiver> origList = device.getReceivers(); + Receiver rec = device.getReceiver(); + if (!containsReceiver(device, rec)) { + out2("Getting a receiver did not add it to device list!"); + thisFailed = true; + } + if (origList.contains(rec)) { + out2("Original unmodifiable list was modified by adding a receiver!"); + thisFailed = true; + } + rec.close(); + if (containsReceiver(device, rec)) { + out2("Closing a receiver did not remove it from device list!"); + thisFailed = true; + } + // add a new receiver so that the device.close will really test + // that the receiver is removed + rec = device.getReceiver(); + if (!containsReceiver(device, rec)) { + out2("Getting a receiver again did not add it to device list!"); + thisFailed = true; + } + } catch (MidiUnavailableException e) { + out2("Exception on getting Receiver: " + e); + } + } + if (device.getMaxTransmitters() != 0) { + // device offers transmitters + try { + List<Transmitter> origList = device.getTransmitters(); + Transmitter tra = device.getTransmitter(); + if (!containsTransmitter(device, tra)) { + out2("Getting a transmitter did not add it to device list!"); + thisFailed = true; + } + if (origList.contains(tra)) { + out2("Original unmodifiable list was modified by adding a transmitter!"); + thisFailed = true; + } + tra.close(); + if (containsTransmitter(device, tra)) { + out2("Closing a transmitter did not remove it from device list!"); + thisFailed = true; + } + tra = device.getTransmitter(); + if (!containsTransmitter(device, tra)) { + out2("Getting a transmitter again did not add it to device list!"); + thisFailed = true; + } + } catch (MidiUnavailableException e) { + out("Exception on getting Transmitter: " + e); + } + } + try { + device.close(); + if (device.getTransmitters().size() > 0) { + out2(" Device still has transmitters after close() was called!"); + thisFailed = true; + } + if (device.getReceivers().size() > 0) { + out2(" Device still has receivers after close() was called!"); + thisFailed = true; + } + } catch (Exception e) { + out2("device.close threw exception: "+e); + } + if (!thisFailed) { + out("OK"); + } else { + failed = true; + } + executed = true; + } + + static boolean lfMissing = false; + + private static void out(String message) { + lfMissing = true; + System.out.println(message); + } + + /* don't print LF at end */ + private static void out1(String message) { + System.out.print(message); + lfMissing = true; + } + + /* print at a new line, indented */ + private static void out2(String message) { + if (lfMissing) { + System.out.println(); + lfMissing = false; + } + System.out.println(" "+message); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/Devices/MidiIO.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2002, 2016, 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 javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; + +/** + * @test + * @bug 4356787 + * @summary MIDI device I/O is not working + */ +public class MidiIO { + + public static void main(String[] args) throws Exception { + out("4356787: MIDI device I/O is not working (windows)"); + + if (System.getProperty("os.name").startsWith("Windows")) { + boolean forInput=true; + boolean forOutput=true; + int outOnlyCount=0; + int inOnlyCount=0; + out(" available MIDI devices:"); + MidiDevice.Info[] aInfos = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < aInfos.length; i++) { + try { + MidiDevice device = MidiSystem.getMidiDevice(aInfos[i]); + boolean bAllowsInput = (device.getMaxTransmitters() != 0); + boolean bAllowsOutput = (device.getMaxReceivers() != 0); + if (bAllowsInput && !bAllowsOutput) { + inOnlyCount++; + } + if (!bAllowsInput && bAllowsOutput) { + outOnlyCount++; + } + if ((bAllowsInput && forInput) || (bAllowsOutput && forOutput)) { + out(""+i+" " + +(bAllowsInput?"IN ":" ") + +(bAllowsOutput?"OUT ":" ") + +aInfos[i].getName()+", " + +aInfos[i].getVendor()+", " + +aInfos[i].getVersion()+", " + +aInfos[i].getDescription()); + } + } + catch (MidiUnavailableException e) { + // device is obviously not available... + } + } + if (aInfos.length == 0) { + out("No devices available. Test should be run on systems with MIDI drivers installed."); + } else { + if (outOnlyCount>1) { + if (inOnlyCount==0) { + //throw new Exception("No input devices! test fails."); + out("System provides out devices, but no input devices. This means either"); + out("a bug in Java Sound, or the drivers are not set up correctly."); + } + out("Test passed."); + } else { + out("no MIDI I/O installed. Test should be run on systems with MIDI drivers installed."); + } + } + } else { + out(" -- not on Windows. Test doesn't apply."); + } + } + + static void out(String s) { + System.out.println(s); System.out.flush(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/Devices/MidiOutGetMicrosecondPositionBug.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2003, 2016, 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 javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; + +/** + * @test + * @bug 4903786 + * @summary MIDI OUT does not implement getMicrosecondPosition() consistently + */ +public class MidiOutGetMicrosecondPositionBug { + static int successfulTests = 0; + + private static void testDevice(MidiDevice device) throws Exception { + boolean timestampsAvailable = false; + boolean timestampPrecisionOk = false; + try { + // expected behaviour if not opened? + device.open(); + /* First, we're testing if timestamps are provided at all. + Returning -1 (unsupported), while allowed by the API + specification, is not sufficient to pass this test. */ + long timestamp = device.getMicrosecondPosition(); + timestampsAvailable = (timestamp != -1); + + /* Then, we're testing the precision. Note that the system time + is measured in milliseconds, while the device time is measured + in microseconds. */ + + long systemTime1 = System.currentTimeMillis(); + long deviceTime1 = device.getMicrosecondPosition(); + // rest for 5 seconds + Thread.sleep(5000); + long systemTime2 = System.currentTimeMillis(); + long deviceTime2 = device.getMicrosecondPosition(); + + // now both period measurements are calculated in milliseconds. + long systemDuration = systemTime2 - systemTime1; + long deviceDuration = (deviceTime2 - deviceTime1) / 1000; + long delta = Math.abs(systemDuration - deviceDuration); + // a deviation of 0.5 seconds (= 500 ms) is allowed. + timestampPrecisionOk = (delta <= 500); + } catch (Throwable t) { + System.out.println(" - Caught exception. Not failed."); + System.out.println(" - " + t.toString()); + return; + } finally { + device.close(); + } + if (! timestampsAvailable) { + throw new Exception("timestamps are not supported"); + } + if (! timestampPrecisionOk) { + throw new Exception("device timer not precise enough"); + } + successfulTests++; + } + + private static void doAll() throws Exception { + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + for (int i=0; i < infos.length; i++) { + MidiDevice device = MidiSystem.getMidiDevice(infos[i]); + if ((! (device instanceof Sequencer)) && + (! (device instanceof Synthesizer)) && + (device.getMaxReceivers() > 0 || device.getMaxReceivers() == -1)) { + + System.out.println("--------------"); + System.out.println("Testing MIDI device: " + infos[i]); + testDevice(device); + } + if (infos.length==0) { + System.out.println("No MIDI devices available!"); + } + } + } + + public static void main(String[] args) throws Exception { + if (!isMidiInstalled()) { + return; + } + doAll(); + if (successfulTests==0) { + System.out.println("Could not execute any of the tests. Test NOT failed."); + } else { + System.out.println("Test PASSED."); + } + } + + /** + * Returns true if at least one MIDI (port) device is correctly installed on + * the system. + */ + public static boolean isMidiInstalled() { + boolean result = false; + MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < devices.length; i++) { + try { + MidiDevice device = MidiSystem.getMidiDevice(devices[i]); + result = ! (device instanceof Sequencer) && ! (device instanceof Synthesizer); + } catch (Exception e1) { + System.err.println(e1); + } + if (result) + break; + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/Devices/OpenClose.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,611 @@ +/* + * Copyright (c) 2003, 2016, 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 javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; +import javax.sound.midi.Transmitter; + +/** + * @test + * @bug 4616517 + * @summary Receiver.send() does not work properly. Tests open/close behaviour + * of MidiDevices. For this test, it is essential that the MidiDevice + * picked from the list of devices (MidiSystem.getMidiDeviceInfo()) is + * the same as the one used by + * MidiSystem.getReceiver()/getTransmitter(). To achieve this, default + * provider properties for Receivers/Transmitters are used. + */ +public class OpenClose { + + private static boolean isTestExecuted; + private static boolean isTestPassed; + + public static void main(String[] args) throws Exception { + boolean failed = false; + out("#4616517: Receiver.send() does not work properly"); + if (!isMidiInstalled()) { + out("Soundcard does not exist or sound drivers not installed!"); + out("This test requires sound drivers for execution."); + return; + } + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + MidiDevice outDevice = null; + MidiDevice inDevice = null; + for (int i = 0; i < infos.length; i++) { + MidiDevice device = MidiSystem.getMidiDevice(infos[i]); + if (! (device instanceof Synthesizer) && + ! (device instanceof Sequencer)) { + if (device.getMaxReceivers() != 0) { + outDevice = device; + } + if (device.getMaxTransmitters() != 0) { + inDevice = device; + } + } + } + if (outDevice != null) { + // set the default provider properties + System.setProperty(Receiver.class.getName(), + "#" + outDevice.getDeviceInfo().getName()); + } + if (inDevice != null) { + System.setProperty(Transmitter.class.getName(), + "#" + inDevice.getDeviceInfo().getName()); + } + out("Using MIDI OUT Device: " + outDevice); + out("Using MIDI IN Device: " + inDevice); + + isTestExecuted = false; + if (outDevice != null) { + isTestExecuted = true; + TestHelper testHelper = new ReceiverTestHelper(outDevice); + try { + doTest("Receiver", testHelper); + failed |= testHelper.hasFailed(); + } catch (Exception e) { + out("Exception occured, cannot test!"); + isTestExecuted = false; + } + } + + if (inDevice != null) { + isTestExecuted = true; + TestHelper testHelper = new TransmitterTestHelper(inDevice); + try { + doTest("Transmitter", testHelper); + failed |= testHelper.hasFailed(); + } catch (Exception e) { + out("Exception occured, cannot test!"); + isTestExecuted = false; + } + } + + isTestPassed = ! failed; + + if (isTestExecuted) { + if (isTestPassed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } else { + out("Test NOT FAILED"); + } + } + + private static void doTest(String type, + TestHelper testHelper) throws Exception { + /* Case 1: + - MidiDevice.open() + - MidiDevice.close() + */ + out("checking " + type + " case 1..."); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 2a: + - MidiSystem.get[Receiver|Transmitter]() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 2a..."); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 2b: + - MidiDevice.get[Receiver|Transmitter]() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 2b..."); + testHelper.checkClosed(); + + testHelper.fetchObjectDevice(); + testHelper.checkClosed(); + + testHelper.closeObjectDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 3a: + - MidiSystem.get[Receiver|Transmitter]() + - MidiDevice.open() + - MidiDevice.close() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 3a..."); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 3b: + - MidiDevice.get[Receiver|Transmitter]() + - MidiDevice.open() + - MidiDevice.close() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 3b..."); + testHelper.checkClosed(); + + testHelper.fetchObjectDevice(); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + testHelper.closeObjectDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 4a: + - MidiSystem.get[Receiver|Transmitter]() + - MidiDevice.open() + - [Receiver|Transmitter].close() + - MidiDevice.close() + */ + out("checking " + type + " case 4a..."); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 4b: + - MidiDevice.get[Receiver|Transmitter]() + - MidiDevice.open() + - [Receiver|Transmitter].close() + - MidiDevice.close() + */ + out("checking " + type + " case 4b..."); + testHelper.checkClosed(); + + testHelper.fetchObjectDevice(); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 5a: + - MidiDevice.open() + - MidiSystem.get[Receiver|Transmitter]() + - MidiDevice.close() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 5a..."); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 5b: + - MidiDevice.open() + - MidiDevice.get[Receiver|Transmitter]() + - MidiDevice.close() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 5b..."); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.fetchObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + testHelper.closeObjectDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 6a: + - MidiDevice.open() + - MidiSystem.get[Receiver|Transmitter]() + - [Receiver|Transmitter].close() + - MidiDevice.close() + */ + out("checking " + type + " case 6a..."); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 6b: + - MidiDevice.open() + - MidiDevice.get[Receiver|Transmitter]() + - [Receiver|Transmitter].close() + - MidiDevice.close() + */ + out("checking " + type + " case 6b..."); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.fetchObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 7: + - MidiSystem.get[Receiver|Transmitter]() // 1 + - MidiDevice.get[Receiver|Transmitter]() // 2 + - [Receiver|Transmitter].close() // 2 + - [Receiver|Transmitter].close() // 1 + */ + out("checking " + type + " case 7..."); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.fetchObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 8: + - MidiSystem.get[Receiver|Transmitter]() // 1 + - MidiDevice.get[Receiver|Transmitter]() // 2 + - [Receiver|Transmitter].close() // 1 + - [Receiver|Transmitter].close() // 2 + */ + out("checking " + type + " case 8..."); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.fetchObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + testHelper.closeObjectDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 9: + - MidiDevice.get[Receiver|Transmitter]() // 2 + - MidiSystem.get[Receiver|Transmitter]() // 1 + - [Receiver|Transmitter].close() // 2 + - [Receiver|Transmitter].close() // 1 + */ + out("checking " + type + " case 9..."); + testHelper.checkClosed(); + + testHelper.fetchObjectDevice(); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 10: + - MidiDevice.get[Receiver|Transmitter]() // 2 + - MidiSystem.get[Receiver|Transmitter]() // 1 + - [Receiver|Transmitter].close() // 1 + - [Receiver|Transmitter].close() // 2 + */ + out("checking " + type + " case 10..."); + testHelper.checkClosed(); + + testHelper.fetchObjectDevice(); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + testHelper.closeObjectDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case N - 1: + - 10 x MidiSystem.get[Receiver|Transmitter]() + - 10 x [Receiver|Transmitter].close() + */ + out("checking " + type + " case N - 1..."); + TestHelper[] testHelpers = new TestHelper[10]; + for (int i = 0; i < 10; i++) { + testHelpers[i] = (TestHelper) testHelper.clone(); + } + testHelper.checkClosed(); + + for (int i = 0; i < 10; i++) { + testHelpers[i].fetchObjectMidiSystem(); + testHelper.checkOpen(); + } + + + for (int i = 0; i < 9; i++) { + testHelpers[i].closeObjectMidiSystem(); + testHelper.checkOpen(); + } + + testHelpers[9].closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + } + + private static void out(String message) { + System.out.println(message); + } + + private static abstract class TestHelper implements Cloneable { + private MidiDevice device; + private boolean failed; + + protected TestHelper(MidiDevice device) { + this.device = device; + failed = false; + } + + protected MidiDevice getDevice() { + return device; + } + + public boolean hasFailed() { + return failed; + } + + public void openDevice() throws MidiUnavailableException { + getDevice().open(); + } + + public void closeDevice() { + getDevice().close(); + } + + public void checkOpen(){ + checkOpen(getDevice(), true); + } + + public void checkClosed(){ + checkOpen(getDevice(), false); + } + + private void checkOpen(MidiDevice device, boolean desiredState) { + if (device.isOpen() != desiredState) { + out("device should be " + + getStateString(desiredState) + ", but isn't!"); + failed = true; + } + } + + + private String getStateString(boolean state) { + return state ? "open" : "closed"; + } + + + public abstract void fetchObjectMidiSystem() throws MidiUnavailableException; + public abstract void fetchObjectDevice() throws MidiUnavailableException; + public abstract void closeObjectMidiSystem(); + public abstract void closeObjectDevice(); + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + return null; + } + } + } + + private static class ReceiverTestHelper extends TestHelper { + private Receiver receiverMidiSystem; + private Receiver receiverDevice; + + public ReceiverTestHelper(MidiDevice device) { + super(device); + } + + public void fetchObjectMidiSystem() throws MidiUnavailableException { + receiverMidiSystem = MidiSystem.getReceiver(); + } + + + public void fetchObjectDevice() throws MidiUnavailableException { + receiverDevice = getDevice().getReceiver(); + } + + + public void closeObjectMidiSystem() { + receiverMidiSystem.close(); + } + + + public void closeObjectDevice() { + receiverDevice.close(); + } + } + + private static class TransmitterTestHelper extends TestHelper { + private Transmitter transmitterMidiSystem; + private Transmitter transmitterDevice; + + public TransmitterTestHelper(MidiDevice device) { + super(device); + } + + public void fetchObjectMidiSystem() throws MidiUnavailableException { + transmitterMidiSystem = MidiSystem.getTransmitter(); + } + + + public void fetchObjectDevice() throws MidiUnavailableException { + transmitterDevice = getDevice().getTransmitter(); + } + + + public void closeObjectMidiSystem() { + transmitterMidiSystem.close(); + } + + + public void closeObjectDevice() { + transmitterDevice.close(); + } + } + + /** + * Returns true if at least one MIDI (port) device is correctly installed on + * the system. + */ + public static boolean isMidiInstalled() { + boolean result = false; + MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < devices.length; i++) { + try { + MidiDevice device = MidiSystem.getMidiDevice(devices[i]); + result = ! (device instanceof Sequencer) && ! (device instanceof Synthesizer); + } catch (Exception e1) { + System.err.println(e1); + } + if (result) + break; + } + return result; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/Devices/ReceiverTransmitterAvailable.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2003, 2016, 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 javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Transmitter; + +/** + * @test + * @bug 4616517 + * @summary Receiver.send() does not work properly + */ +public class ReceiverTransmitterAvailable { + + private static boolean isTestExecuted; + private static boolean isTestPassed; + + public static void main(String[] args) throws Exception { + out("#4616517: Receiver.send() does not work properly"); + doAllTests(); + if (isTestExecuted) { + if (isTestPassed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } else { + out("Test NOT FAILED"); + } + } + + private static void doAllTests() { + boolean problemOccured = false; + boolean succeeded = true; + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < infos.length; i++) { + MidiDevice device = null; + try { + device = MidiSystem.getMidiDevice(infos[i]); + succeeded &= doTest(device); + } catch (MidiUnavailableException e) { + out("exception occured; cannot test"); + problemOccured = true; + } + } + if (infos.length == 0) { + out("Soundcard does not exist or sound drivers not installed!"); + out("This test requires sound drivers for execution."); + } + isTestExecuted = !problemOccured; + isTestPassed = succeeded; + } + + private static boolean doTest(MidiDevice device) { + boolean succeeded = true; + out("Testing: " + device); + boolean expectingReceivers = (device.getMaxReceivers() != 0); + boolean expectingTransmitters = (device.getMaxTransmitters() != 0); + try { + Receiver rec = device.getReceiver(); + rec.close(); + if (! expectingReceivers) { + out("no exception on getting Receiver"); + succeeded = false; + } + } catch (MidiUnavailableException e) { + if (expectingReceivers) { + out("Exception on getting Receiver: " + e); + succeeded = false; + } + } + try { + Transmitter trans = device.getTransmitter(); + trans.close(); + if (! expectingTransmitters) { + out("no exception on getting Transmitter"); + succeeded = false; + } + } catch (MidiUnavailableException e) { + if (expectingTransmitters) { + out("Exception on getting Transmitter: " + e); + succeeded = false; + } + } + return succeeded; + } + + private static void out(String message) { + System.out.println(message); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/Devices/Reopen.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2003, 2016, 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 javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; + +/** + * @test + * @bug 4914667 + * @summary Closing and reopening MIDI IN device on Linux throws + * MidiUnavailableException + */ +public class Reopen { + + private static boolean isTestExecuted; + private static boolean isTestPassed; + + /* + * run manually: + * java Reopen 100 in for 100 iterations on the MIDI IN device + * java Reopen 16 out for 16 iterations on the MIDI OUT device + */ + public static void main(String[] args) throws Exception { + if (args.length == 0) { + doAllTests(); + } else if (args.length == 2) { + int numIterations = Integer.parseInt(args[0]); + if (args[1].equals("in")) { + doTest(numIterations, true); + } else { + doTest(numIterations, false); + } + } else { + out("usage: java Reopen <iterations> in|out"); + } + } + + private static void doAllTests() throws Exception { + out("#4914667: Closing and reopening MIDI IN device on Linux throws MidiUnavailableException"); + boolean success = true; + try { + success &= doTest(20, true); // MIDI IN + success &= doTest(20, false); // MIDI OUT + isTestExecuted = true; + } catch (Exception e) { + out(e); + isTestExecuted = false; + } + isTestPassed = success; + if (isTestExecuted) { + if (isTestPassed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } else { + out("Test NOT FAILED"); + } + } + + private static boolean doTest(int numIterations, boolean input) throws Exception { + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + MidiDevice outDevice = null; + MidiDevice inDevice = null; + for (int i = 0; i < infos.length; i++) { + MidiDevice device = MidiSystem.getMidiDevice(infos[i]); + if (! (device instanceof Sequencer) && + ! (device instanceof Synthesizer)) { + if (device.getMaxReceivers() != 0) { + outDevice = device; + } + if (device.getMaxTransmitters() != 0) { + inDevice = device; + } + } + } + MidiDevice testDevice = null; + if (input) { + testDevice = inDevice; + } else { + testDevice = outDevice; + } + if (testDevice == null) { + out("Cannot test: device not available."); + return true; + } + out("Using Device: " + testDevice); + + for (int i = 0; i < numIterations; i++) { + out("@@@ ITERATION: " + i); + testDevice.open(); + // This sleep ensures that the thread of MidiInDevice is started. + sleep(50); + testDevice.close(); + } + return true; + } + + private static void sleep(int milliseconds) { + try { + Thread.sleep(milliseconds); + } catch (InterruptedException e) { + } + } + + private static void out(Throwable t) { + t.printStackTrace(System.out); + } + + private static void out(String message) { + System.out.println(message); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/File/SMFCp037.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2002, 2016, 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.io.ByteArrayInputStream; + +import javax.sound.midi.MidiSystem; + +/** + * @test + * @bug 4303933 + * @summary MidiSystem fails to load MIDI file on systems with EBCDIC simulation + */ +public class SMFCp037 { + + public static void main(String args[]) throws Exception { + // Test to read MIDI files with Cp037 character set - close enough + // for EBCDIC simulation + System.setProperty("file.encoding", "Cp037"); + // try to read this file with Cp037 encoding + MidiSystem.getSequence(new ByteArrayInputStream(SHORT_SMF)); + System.out.println(" test passed."); + } + +public static byte[] SHORT_SMF = { + 77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 2, 0, 120, 77, 84, 114, 107, 0, 0, + 0, 27, 0, -1, 3, 19, 77, 73, 68, 73, 32, 116, 101, 115, 116, 32, 45, 32, + 116, 114, 97, 99, 107, 32, 48, 0, -1, 47, 0, 77, 84, 114, 107, 0, 0, 0, -44, + 0, -1, 3, 19, 77, 73, 68, 73, 32, 116, 101, 115, 116, 32, 45, 32, 116, 114, + 97, 99, 107, 32, 49, 0, -64, 30, 0, -112, 68, 126, 0, -32, 6, 67, 0, 14, + 71, 0, 20, 74, 0, 26, 77, 0, 32, 80, 0, 42, 85, 6, 50, 89, 6, 56, 92, 5, + 66, 97, 6, 74, 101, 6, 80, 104, 11, 84, 106, 20, 76, 102, 6, 70, 99, 5, 60, + 94, 6, 52, 90, 5, 44, 86, 4, 34, 81, 5, 26, 77, 5, 20, 74, 6, 10, 69, 5, + 2, 65, 7, 0, 64, 42, -112, 66, 123, 11, 68, 0, 72, 63, 126, 4, 66, 0, 43, + -32, 0, 63, 6, 0, 60, 7, 0, 56, 6, 0, 53, 5, 0, 49, 5, 0, 43, 4, 0, 37, 3, + 0, 30, 3, 0, 25, 3, 0, 19, 3, 0, 13, 4, 0, 8, 4, 0, 2, 4, 0, 0, 70, 0, 3, + 5, 0, 9, 3, 0, 14, 7, 0, 16, 25, 0, 21, 5, 0, 25, 7, 0, 28, 5, 0, 32, 5, + 0, 36, 5, 0, 41, 6, 0, 46, 5, 0, 50, 5, 0, 53, 4, 0, 58, 7, 0, 61, 7, 0, + 64, 117, -112, 63, 0, 0, -1, 47, 0 + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/File/SMFParserBreak.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2002, 2016, 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.io.ByteArrayInputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; + +/** + * @test + * @bug 4910986 + * @summary MIDI file parser breaks up on http connection + */ +public class SMFParserBreak { + + public static void main(String[] args) throws Exception { + + InputStream is = new ByteArrayInputStream(midifile); + // create a buffered input stream that seems + // to be on an unfortunate boundary for the + // 1.4.2 SMF parser implementation + is = new ChunkInputStream(is, 32); + Sequence sequence = MidiSystem.getSequence(is); + + long duration = sequence.getMicrosecondLength() / 10000; + System.out.println("Duration: "+duration+" deciseconds "); + + // the test is passed if no exception thrown + System.out.println("Test passed"); + } + + // A MIDI file + static byte[] midifile = { + 77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 3, -30, 120, 77, 84, 114, 107, 0, + 0, 0, 123, 0, -112, 30, 100, -113, 49, -128, 50, 100, -114, 69, -112, 31, + 100, -114, 33, -128, 51, 100, -114, 55, -112, 32, 100, -114, 120, -128, 52, + 100, -114, 40, -112, 33, 100, -114, 26, -128, 53, 100, -114, 26, -112, 34, + 100, -114, 76, -128, 54, 100, -114, 12, -112, 35, 100, -114, 91, -128, 55, + 100, -114, 69, -112, 36, 100, -114, 33, -128, 56, 100, -114, 55, -112, 37, + 100, -114, 84, -128, 57, 100, -114, 40, -112, 38, 100, -114, 26, -128, 58, + 100, -114, 26, -112, 39, 100, -113, 24, -128, 59, 100, -113, 60, -112, 40, + 100, -113, 110, -128, 60, 100, -113, 96, -112, 41, 100, -113, 39, -128, 61, + 100, 0, -1, 47, 0, 77, 84, 114, 107, 0, 0, 0, 4, 0, -1, 47, 0, 77, 84, 114, + 107, 0, 0, 0, 4, 0, -1, 47, 0 + }; +} + +/* an input stream that always returns data in chunks */ +class ChunkInputStream extends FilterInputStream { + int chunkSize; + int p = 0; // position + + public ChunkInputStream(InputStream is, int chunkSize) { + super(is); + this.chunkSize = chunkSize; + } + + // override to increase counter + public int read() throws IOException { + int ret = super.read(); + if (ret >= 0) { + p++; + } + return ret; + } + + // override to make sure that read(byte[], int, int) is used + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + // override to split the data in chunks + public int read(byte[] b, int off, int len) throws IOException { + // if we would pass a chunk boundary, + // only return up to the chunk boundary + if ( (p / chunkSize) < ( (p+len) / chunkSize)) { + // p+len is in the next chunk + len -= ((p+len) % chunkSize); + } + int ret = super.read(b, off, len); + if (ret >= 0) { + p += ret; + } + return ret; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/File/WriteRealTimeMessageNPE.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2004, 2016, 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.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 5048381 + * @summary NPE when writing a sequence with a realtime MIDI message + */ +public class WriteRealTimeMessageNPE { + + public static void main(String args[]) throws Exception { + System.out.println("5048381: NullPointerException when saving a MIDI sequence"); + boolean npeThrown = false; + boolean noEx = false; + + Sequence seq = new Sequence(Sequence.PPQ, 384, 1); + Track t = seq.getTracks()[0]; + ShortMessage msg = new ShortMessage(); + msg.setMessage(0xF8, 0, 0); + t.add(new MidiEvent(msg, 0)); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + MidiSystem.write(seq, 0, out); + noEx = true; + } catch (NullPointerException npe) { + npeThrown = true; + System.out.println("## Failed: Threw unexpected NPE: "+npe); + throw new Exception("Test FAILED!"); + } catch (Exception e) { + System.out.println("Threw unexpected Exception: "+e); + System.out.println("But at least did not throw NPE..."); + } + if (noEx) { + InputStream is = new ByteArrayInputStream(out.toByteArray()); + seq = MidiSystem.getSequence(is); + System.out.println("Sequence has "+seq.getTracks().length+" tracks."); + if (seq.getTracks().length > 0) { + System.out.println("Track 0 has "+seq.getTracks()[0].size()+" events."); + } + } + System.out.println("Test passed."); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/MetaMessage/MetaMessageClone.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2002, 2016, 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 javax.sound.midi.MetaMessage; + +/** + * @test + * @bug 4511796 + * @summary Check that MetaMessage.clone() works correctly + */ +public class MetaMessageClone { + + private static void printMsg(MetaMessage msg, byte[] data) { + System.out.println(""+msg.getLength()+" total bytes, type="+msg.getType()+", dataLength="+data.length); + } + + private static void checkClone(MetaMessage msg) throws Exception { + System.out.print("Original: "); + byte[] msgData=msg.getData(); + printMsg(msg, msgData); + MetaMessage msg2=(MetaMessage) msg.clone(); + byte[] msg2Data=msg2.getData(); + System.out.print("Clone: "); + printMsg(msg2, msg2Data); + + if (msg2.getLength()!=msg.getLength() + || msg.getType()!=msg2.getType() + || msgData.length!=msg2Data.length) { + throw new Exception("cloned MetaMessage is not equal."); + } + int max=Math.min(msgData.length, 10); + for (int i=0; i<max; i++) { + if (msgData[i]!=msg2Data[i]) { + throw new Exception("Cloned MetaMessage data is not equal."); + } + } + } + + public static void main(String[] args) throws Exception { + // let's create some MetaMessages and check them + MetaMessage msg=new MetaMessage(); + String text="a textmarker"; + msg.setMessage(1, text.getBytes(), text.length()); + checkClone(msg); + msg.setMessage(0x2E, new byte[0], 0); + checkClone(msg); + byte[] data=new byte[17000]; + for (int i=0; i<30; data[i]=(byte) (i++ & 0xFF)); + msg.setMessage(0x02, data, 80); checkClone(msg); + msg.setMessage(0x02, data, 160); checkClone(msg); + msg.setMessage(0x02, data, 400); checkClone(msg); + msg.setMessage(0x02, data, 1000); checkClone(msg); + msg.setMessage(0x02, data, 10000); checkClone(msg); + msg.setMessage(0x02, data, 17000); checkClone(msg); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/MidiSystem/6411624/Test6411624.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2006, 2016, 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.Button; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @test + * @bug 6411624 + * @summary Tests that MidiSystem.getReceiver() & MidiSystem.getTransmitter + * doesn't return sequencer + * @build bug6411624 + * @run main/manual Test6411624 + */ +public class Test6411624 { + + private static void init() throws Exception { + //*** Create instructions for the user here *** + + String[] instructions = + { + "This test should only be run on solaris or linux system", + "WITHOUT audio card installed (to test on SunRay set", + "incorrect $AUDIODEV value).", + "If you system does not meet this conditions, press PASS.", + "To run the test follow these instructions:", + "1. Open a terminal window.", + "2. Type \"cd " + System.getProperty("test.classes") + "\".", + "3. Type \"" + System.getProperty("java.home") + "/bin/java bug6411624\".", + "4. Follow the instructions shown in the terminal window.", + "If you see \"All tests sucessfully passed\", press PASS else press FAIL." + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + } + + /***************************************************** + Standard Test Machinery Section + DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws Exception + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + + }// class Orient + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + Orient.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + Orient.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //DialogOrient + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + Test6411624.pass(); + } + else + { + Test6411624.fail(); + } + } + + }// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/MidiSystem/6411624/bug6411624.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2006, 2016, 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.io.IOException; +import java.util.Iterator; +import java.util.List; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; +import javax.sound.midi.Transmitter; + +/** + * This test should be run on specific environment (solaris or linux w/o + * audio card installed). + */ +public class bug6411624 { + + public static void main(String args[]) throws Exception { + log("This test should only be run on solaris or linux system"); + log("without audio card installed (to test on SunRay set"); + log("incorrect $AUDIODEV value)."); + readln(); + + boolean testRecv = false; + boolean testTrans = false; + boolean testSeq = true; + + // print add info (midi device list) + try { + MidiDevice.Info[] midis = MidiSystem.getMidiDeviceInfo(); + log("MidiDevices (total " + midis.length + "):"); + for (int i=0; i<midis.length; i++) { + log("" + i + ": " + midis[i].toString()); +// MidiDevice dev = MidiSystem.getMidiDevice(midis[i]); +// log(" device: " + dev); + } + } catch (Exception ex) { + log("!!!EXCEPTION:"); + ex.printStackTrace(); + } + + log(""); + log("getting default receiver..."); + try { + Receiver rec = MidiSystem.getReceiver(); + log(" - OK: " + rec); + testRecv = checkDevice(rec); + rec.close(); + } catch (MidiUnavailableException e) { + log("MidiUnavailableException has been thrown - OK"); + testRecv = true; + } + + + log(""); + log("getting default transmitter..."); + try { + Transmitter trans = MidiSystem.getTransmitter(); + log(" - OK: " + trans); + testTrans = checkDevice(trans); + trans.close(); + } catch (MidiUnavailableException e) { + log("MidiUnavailableException has been thrown - OK"); + testTrans = true; + } + + + // print default synthesizer + log(""); + log("getting default synth..."); + try { + Synthesizer synth = MidiSystem.getSynthesizer(); + log(" - OK: " + synth); + synth.close(); + } catch (MidiUnavailableException e) { + log("MidiUnavailableException has been thrown - OK:"); + e.printStackTrace(); + } + + + log(""); + log("getting default sequencer (connected)..."); + try { + Sequencer seq = MidiSystem.getSequencer(); + log("OK: " + seq); + + // check that returned sequencer doesn't connected to another sequencer + log(" receivers:"); + log(" max=" + seq.getMaxReceivers()); + List<Receiver> recvList = seq.getReceivers(); + log(" count=" + recvList.size()); + Iterator<Receiver> recvIter = recvList.iterator(); + int i = 0; + while (recvIter.hasNext()) { + Receiver recv = recvIter.next(); + log(" " + (++i) + ": " + recv); + } + + log(" transmitters:"); + log(" max=" + seq.getMaxTransmitters()); + List<Transmitter> transList = seq.getTransmitters(); + log(" count=" + transList.size()); + Iterator<Transmitter> transIter = transList.iterator(); + i = 0; + while (transIter.hasNext()) { + Transmitter trans = transIter.next(); + log(" " + (++i) + ": " + trans); + Receiver recv = trans.getReceiver(); + log(" recv: " + recv); + if (!checkDevice(recv)) + testSeq = false; + } + + log("opening sequencer..."); + seq.open(); + log("OK."); + + log("closing..."); + seq.close(); + log("OK."); + } catch (MidiUnavailableException e) { + log("MidiUnavailableException has been thrown - OK:"); + e.printStackTrace(); + } + + + // debug testing - non-connected sequencer + log(""); + log("getting default sequencer (non-connected)..."); + try { + Sequencer seq = MidiSystem.getSequencer(false); + log("OK: " + seq); + + log(" receivers:"); + log(" max=" + seq.getMaxReceivers()); + List<Receiver> recvList = seq.getReceivers(); + log(" count=" + recvList.size()); + Iterator<Receiver> recvIter = recvList.iterator(); + int i = 0; + while (recvIter.hasNext()) { + Receiver recv = recvIter.next(); + log(" " + (++i) + ": " + recv); + } + + log(" transmitters:"); + log(" max=" + seq.getMaxTransmitters()); + List<Transmitter> transList = seq.getTransmitters(); + log(" count=" + transList.size()); + Iterator<Transmitter> transIter = transList.iterator(); + i = 0; + while (transIter.hasNext()) { + Transmitter trans = transIter.next(); + log(" " + (++i) + ": " + trans); + Receiver recv = trans.getReceiver(); + log(" recv: " + recv); + } + seq.close(); + } catch (MidiUnavailableException e) { + log("MidiUnavailableException has been thrown (shouln't?):"); + e.printStackTrace(); + } + + log(""); + log("Test result:"); + // print results + if (testRecv && testTrans && testSeq) { + log(" All tests sucessfully passed."); + } else { + log(" Some tests failed:"); + log(" receiver test: " + (testRecv ? "OK" : "FAILED")); + log(" transmitter test: " + (testTrans ? "OK" : "FAILED")); + log(" sequencer test: " + (testSeq ? "OK" : "FAILED")); + } + log("\n\n\n"); + } + + // check that device is not sequencer + static boolean checkDevice(Object dev) { + String className = dev.getClass().toString().toLowerCase(); + boolean result = (className.indexOf("sequencer") < 0); + if (!result) + log("ERROR: inapropriate device"); + return result; + } + + // helper routines + static long startTime = currentTimeMillis(); + static long currentTimeMillis() { + //return System.nanoTime() / 1000000L; + return System.currentTimeMillis(); + } + static void log(String s) { + long time = currentTimeMillis() - startTime; + long ms = time % 1000; + time /= 1000; + long sec = time % 60; + time /= 60; + long min = time % 60; + time /= 60; + System.out.println("" + + (time < 10 ? "0" : "") + time + + ":" + (min < 10 ? "0" : "") + min + + ":" + (sec < 10 ? "0" : "") + sec + + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms + + " (" + Thread.currentThread().getName() + ") " + s); + } + static void delay(int millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) {} + } + static void readln() { + log(""); + log("Press ENTER to continue..."); + try { + while (System.in.read() != 10) ; + } catch (IOException e) { } + log(""); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/MidiSystem/DefaultDevices.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; +import javax.sound.midi.Transmitter; +import javax.sound.midi.spi.MidiDeviceProvider; + +import com.sun.media.sound.JDK13Services; + +/** + * @test + * @bug 4776511 + * @bug 4934509 + * @bug 4938236 + * @modules java.desktop/com.sun.media.sound + * @run main/timeout=600 DefaultDevices + * @summary RFE: Setting the default MixerProvider + */ +/** Test the retrieving of MidiDevices with default device properties. + * This is a part of the test for 4776511. + * The test also functions as a unit test for 4934509: SPEC: Document + * explicitely MidiSystem.getReceiver's behavior + * and a regession test for 4938236: Crash when opening synthesizer implicitly + * The test has been updated to reflect a fix for 6411624: MidiSystem.getSequencer() + * doesn't throw MidiUnavaivableException if no audio card installed (see also + * 6422786: regression test javax/sound/midi/MidiSystem/DefaultDevices.java fails) + */ +public class DefaultDevices { + + private static final String ERROR_PROVIDER_CLASS_NAME = "abc"; + private static final String ERROR_INSTANCE_NAME = "def"; + + private static final Class RECEIVER_CLASS = javax.sound.midi.Receiver.class; + private static final Class TRANSMITTER_CLASS = javax.sound.midi.Transmitter.class; + private static final Class SEQUENCER_CLASS = javax.sound.midi.Sequencer.class; + private static final Class SYNTHESIZER_CLASS = javax.sound.midi.Synthesizer.class; + + public static void main(String[] args) throws Exception { + boolean allOk = true; + MidiDevice.Info[] infos; + + out("\nTesting MidiDevices retrieved via MidiSystem"); + infos = MidiSystem.getMidiDeviceInfo(); + allOk &= testDevices(infos, null); + + out("\nTesting MidiDevices retrieved from MidiDeviceProviders"); + List providers = JDK13Services.getProviders(MidiDeviceProvider.class); + for (int i = 0; i < providers.size(); i++) { + MidiDeviceProvider provider = (MidiDeviceProvider)providers.get(i); + infos = provider.getDeviceInfo(); + allOk &= testDevices(infos, provider.getClass().getName()); + } + + if (!allOk) { + throw new Exception("Test failed"); + } else { + out("Test passed"); + } + } + + private static boolean testDevices(MidiDevice.Info[] infos, + String providerClassName) { + boolean allOk = true; + + for (int i = 0; i < infos.length; i++) { + MidiDevice device = null; + try { + device = MidiSystem.getMidiDevice(infos[i]); + } catch (MidiUnavailableException e) { + out("Exception thrown; Test NOT failed."); + e.printStackTrace(System.out); + out(""); + } + out("\nTesting device: " + device); + if (device instanceof Sequencer) { + allOk &= testDevice(device, SEQUENCER_CLASS, providerClassName, true, true); + // incorrect cases + allOk &= testDevice(device, SYNTHESIZER_CLASS, providerClassName, false, false); + allOk &= testDevice(device, RECEIVER_CLASS, providerClassName, false, false); + allOk &= testDevice(device, TRANSMITTER_CLASS, providerClassName, false, false); + } + if (device instanceof Synthesizer) { + allOk &= testDevice(device, SYNTHESIZER_CLASS, providerClassName, true, true); + allOk &= testDevice(device, RECEIVER_CLASS, providerClassName, false, true); + // incorrect cases + allOk &= testDevice(device, TRANSMITTER_CLASS, providerClassName, false, false); + allOk &= testDevice(device, SEQUENCER_CLASS, providerClassName, false, false); + } + if (device instanceof Receiver) { + allOk &= testDevice(device, RECEIVER_CLASS, providerClassName, true, true); + // incorrect cases + allOk &= testDevice(device, TRANSMITTER_CLASS, providerClassName, false, false); + allOk &= testDevice(device, SYNTHESIZER_CLASS, providerClassName, false, false); + allOk &= testDevice(device, SEQUENCER_CLASS, providerClassName, false, false); + } + if (device instanceof Transmitter) { + allOk &= testDevice(device, TRANSMITTER_CLASS, providerClassName, true, true); + // incorrect cases + allOk &= testDevice(device, RECEIVER_CLASS, providerClassName, false, false); + allOk &= testDevice(device, SYNTHESIZER_CLASS, providerClassName, false, false); + allOk &= testDevice(device, SEQUENCER_CLASS, providerClassName, false, false); + } + } + return allOk; + } + + private static boolean testDevice(MidiDevice device, Class type, + String providerClassName, boolean testWrong, boolean expectedResult) { + boolean allOk = true; + String instanceName = device.getDeviceInfo().getName(); + + // no error + allOk &= testDevice(device, type, providerClassName, + instanceName, expectedResult); + + if (testWrong) { + // erroneous provider class name, correct instance name + allOk &= testDevice(device, type, ERROR_PROVIDER_CLASS_NAME, + instanceName, expectedResult); + + // correct provider class name, erroneous instance name + // we presume that provider provides only one class of requested type + allOk &= testDevice(device, type, providerClassName, + ERROR_INSTANCE_NAME, expectedResult); + } + + return allOk; + } + + private static boolean testDevice(MidiDevice device, Class type, + String providerClassName, String instanceName, + boolean expectedResult) { + boolean allOk = true; + + try { + String propertyName = type.getName(); + String propertyValue = (providerClassName != null) ? providerClassName: "" ; + propertyValue += "#" + instanceName; + out("property: " + propertyName + "="+ propertyValue); + System.setProperty(propertyName, propertyValue); + Object reference = null; + Object result = null; + if (type == SEQUENCER_CLASS) { + reference = device; + result = MidiSystem.getSequencer(); + } else if (type == SYNTHESIZER_CLASS) { + reference = device; + result = MidiSystem.getSynthesizer(); + } else if (type == RECEIVER_CLASS) { + reference = device.getReceiver(); + result = MidiSystem.getReceiver(); + } else if (type == TRANSMITTER_CLASS) { + reference = device.getTransmitter(); + result = MidiSystem.getTransmitter(); + } + out("result: " + result); + boolean rightDevice = (reference.getClass() == result.getClass()); + if (rightDevice != expectedResult) { + out("\nERROR: type " + type + " failed:" + + " class should" + (expectedResult ? "" : " NOT") + " be '" + + reference.getClass() + + "' but is '" + result.getClass() + "'!\n"); + allOk = false; + } + if (expectedResult + && reference instanceof MidiDevice + && result instanceof MidiDevice) { + MidiDevice referenceDevice = (MidiDevice)reference; + MidiDevice resultDevice = (MidiDevice)result; + if (!referenceDevice.getDeviceInfo().getName().equals( + resultDevice.getDeviceInfo().getName())) { + out("\nERROR: type " + type + " failed: name should be '" + + referenceDevice.getDeviceInfo().getName() + + "' but is '" + + resultDevice.getDeviceInfo().getName() + "'!\n"); + allOk = false; + } + } + if (result instanceof Receiver) { + ((Receiver)result).close(); + } else if (result instanceof Transmitter) { + ((Transmitter)result).close(); + } else if (result instanceof Synthesizer) { + ((Synthesizer)result).close(); + } else if (result instanceof Sequencer) { + ((Sequencer)result).close(); + } + } catch (Exception e) { + out("Exception thrown; Test NOT failed."); + e.printStackTrace(System.out); + out(""); + } + return allOk; + } + + private static void out(String message) { + System.out.println(message); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/MidiSystem/DefaultProperties.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2003, 2016, 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.io.File; + +import com.sun.media.sound.JDK13Services; + +/** + * @test + * @bug 4776511 + * @summary RFE: Setting the default MixerProvider. Test the retrieving and + * parsing of properties. This is a part of the test for 4776511. + * @run main/othervm DefaultProperties + * @modules java.desktop/com.sun.media.sound + */ +public class DefaultProperties { + + private static final Class[] lineTypeClasses = { + javax.sound.midi.Receiver.class, + javax.sound.midi.Transmitter.class, + javax.sound.midi.Sequencer.class, + javax.sound.midi.Synthesizer.class, + }; + + public static void main(String[] args) throws Exception { + boolean allOk = true; + File file = new File(System.getProperty("test.src", "."), "testdata"); + System.setProperty("java.home", file.getCanonicalPath()); + + for (int i = 0; i < lineTypeClasses.length; i++) { + Class cls = lineTypeClasses[i]; + String propertyName = cls.getName(); + String result; + String provClassName; + String instanceName; + + // properties file, both provider class name and instance name + provClassName = "xyz"; + instanceName = "123"; + result = JDK13Services.getDefaultProviderClassName(cls); + if (! provClassName.equals(result)) { + out("type " + cls + " failed: provider class should be '" + + provClassName + "' but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (! instanceName.equals(result)) { + out("type " + cls + " failed: instance name should be '" + + instanceName + "' but is '" + result + "'!"); + allOk = false; + } + + // system property, provider class name only, no trailing hash + provClassName = "abc"; + System.setProperty(propertyName, provClassName); + result = JDK13Services.getDefaultProviderClassName(cls); + if (! provClassName.equals(result)) { + out("type " + cls + " failed: provider class should be '" + + provClassName + "' but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (result != null) { + out("type " + cls + " failed: instance name should be " + + "null but is '" + result + "'!"); + allOk = false; + } + + // system property, provider class name only, trailing hash + provClassName = "def"; + System.setProperty(propertyName, provClassName + "#"); + result = JDK13Services.getDefaultProviderClassName(cls); + if (! provClassName.equals(result)) { + out("type " + cls + " failed: provider class should be '" + + provClassName + "' but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (result != null) { + out("type " + cls + " failed: instance name should be " + + "null but is '" + result + "'!"); + allOk = false; + } + + // system property, instance name only + instanceName = "ghi"; + System.setProperty(propertyName, "#" + instanceName); + result = JDK13Services.getDefaultProviderClassName(cls); + if (result != null) { + out("type " + cls + " failed: provider class should be " + + "null but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (! instanceName.equals(result)) { + out("type " + cls + " failed: instance name should be '" + + instanceName + "' but is '" + result + "'!"); + allOk = false; + } + + // system property, both provider class and instance name + provClassName = "jkl"; + instanceName = "mno"; + System.setProperty(propertyName, provClassName + "#" + instanceName); + result = JDK13Services.getDefaultProviderClassName(cls); + if (! provClassName.equals(result)) { + out("type " + cls + "failed: provider class should be '" + + provClassName + "' but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (! instanceName.equals(result)) { + out("type " + cls + "failed: instance name should be '" + + instanceName + "' but is '" + result + "'!"); + allOk = false; + } + + // system property, empty + System.setProperty(propertyName, ""); + result = JDK13Services.getDefaultProviderClassName(cls); + if (result != null) { + out("type " + cls + " failed: provider class should be " + + "null but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (result != null) { + out("type " + cls + "failed: instance name should be " + + "null but is '" + result + "'!"); + allOk = false; + } + } + if (! allOk) { + throw new Exception("Test failed"); + } else { + out("Test passed"); + } + } + + private static void out(String message) { + System.out.println(message); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/MidiSystem/GetSequencer.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; + +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Transmitter; + +/** + * @test + * @bug 4931400 + * @summary Clarify default connections in default sequencer + */ +public class GetSequencer { + + static boolean failed = false; + + public static void main(String args[]) throws Exception { + doTest(1); + doTest(2); + doTest(3); + + if (failed) throw new Exception("Test FAILED!"); + out("test OK"); + } + + public static void doTest(int mode) { + Sequencer seq = null; + boolean connected = false; + + try { + switch (mode) { + case 1: + seq = MidiSystem.getSequencer(); + connected = true; + break; + case 2: + seq = MidiSystem.getSequencer(false); + connected = false; + break; + case 3: + seq = MidiSystem.getSequencer(true); + connected = true; + break; + } + out("Testing Sequencer "+seq); + if (connected) { + out(" opened in connected mode."); + } else { + out(" opened in non-connected mode."); + } + System.out.println(" opening..."); + seq.open(); + } catch (MidiUnavailableException mue) { + System.err.println("MidiUnavailableException was thrown: " + mue); + System.err.println(" could not test this sequencer."); + return; + } + + try { + List<Transmitter> transmitters = seq.getTransmitters(); + int size = transmitters.size(); + out(" transmitters.size()="+size); + if (size != 1 && connected) { + out(" should have 1 connection! Failed."); + failed = true; + } + if (size != 0 && !connected) { + out(" should have 0 connections! Failed."); + failed = true; + } + out(" closing..."); + seq.close(); + transmitters = seq.getTransmitters(); + size = transmitters.size(); + out(" transmitters.size()="+size); + if (size != 0) { + out(" should have 0 connections! Failed."); + failed = true; + } + + out(" opening again..."); + seq.open(); + transmitters = seq.getTransmitters(); + size = transmitters.size(); + out(" transmitters.size()="+size); + if (size != 1 && connected) { + out(" should have 1 connection! Failed."); + failed = true; + } + if (size != 0 && !connected) { + out(" should have 0 connections! Failed."); + failed = true; + } + } catch (Exception e) { + System.err.println(" unexpectedException was thrown: " + e); + System.err.println(" causes this test to FAIL."); + failed = true; + } + seq.close(); + } + + static void out(String s) { + System.out.println(s); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/MidiSystem/MidiFileTypeUniqueness.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003, 2016, 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 javax.sound.midi.MidiSystem; + +/** + * @test + * @bug 4883060 + * @summary AudioSystem.getAudioFileTypes returns duplicates + */ +public class MidiFileTypeUniqueness { + + public static void main(String[] args) throws Exception { + boolean foundDuplicates = false; + int[] aTypes = MidiSystem.getMidiFileTypes(); + for (int i = 0; i < aTypes.length; i++) + { + for (int j = 0; j < aTypes.length; j++) + { + if (aTypes[i] == aTypes[j] && i != j) { + foundDuplicates = true; + } + } + } + if (foundDuplicates) { + throw new Exception("Test failed"); + } else { + System.out.println("Test passed"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/MidiSystem/ProviderCacheing.java Fri Nov 04 17:52:55 2016 +0000 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2003, 2016, 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 i