--- a/.hgtags-top-repo Mon Nov 07 16:08:18 2016 +0000
+++ b/.hgtags-top-repo Wed Jul 05 22:25:59 2017 +0200
@@ -385,3 +385,4 @@
a5815c6098a241d3a1df64d22b84b3524e4a77df jdk-9+140
f64afae7f1a5608e438585bbf0bc23785e69cba0 jdk-9+141
2b3e5caafe3594ea507c37675c4d3086f415dc64 jdk-9+142
+1fc62b1c629fb80fdaa639d3b59452a184f0d705 jdk-9+143
--- a/common/autoconf/flags.m4 Mon Nov 07 16:08:18 2016 +0000
+++ b/common/autoconf/flags.m4 Wed Jul 05 22:25:59 2017 +0200
@@ -280,7 +280,7 @@
else
# Default works for linux, might work on other platforms as well.
SHARED_LIBRARY_FLAGS='-shared'
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$$$ORIGIN[$]1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1'
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1'
@@ -305,7 +305,7 @@
# Default works for linux, might work on other platforms as well.
PICFLAG='-fPIC'
SHARED_LIBRARY_FLAGS='-shared'
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$$$ORIGIN[$]1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1'
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1'
@@ -315,7 +315,7 @@
C_FLAG_REORDER='-xF'
CXX_FLAG_REORDER='-xF'
SHARED_LIBRARY_FLAGS="-G"
- SET_EXECUTABLE_ORIGIN='-R\$$$$ORIGIN[$]1'
+ SET_EXECUTABLE_ORIGIN='-R\$$ORIGIN[$]1'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-h [$]1'
SET_SHARED_LIBRARY_MAPFILE='-M[$]1'
--- a/common/autoconf/generated-configure.sh Mon Nov 07 16:08:18 2016 +0000
+++ b/common/autoconf/generated-configure.sh Wed Jul 05 22:25:59 2017 +0200
@@ -5093,7 +5093,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1478079760
+DATE_WHEN_GENERATED=1478524503
###############################################################################
#
@@ -49070,7 +49070,7 @@
else
# Default works for linux, might work on other platforms as well.
SHARED_LIBRARY_FLAGS='-shared'
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$$$ORIGIN$1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN$1'
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-soname=$1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=$1'
@@ -49095,7 +49095,7 @@
# Default works for linux, might work on other platforms as well.
PICFLAG='-fPIC'
SHARED_LIBRARY_FLAGS='-shared'
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$$$ORIGIN$1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN$1'
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-soname=$1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=$1'
@@ -49105,7 +49105,7 @@
C_FLAG_REORDER='-xF'
CXX_FLAG_REORDER='-xF'
SHARED_LIBRARY_FLAGS="-G"
- SET_EXECUTABLE_ORIGIN='-R\$$$$ORIGIN$1'
+ SET_EXECUTABLE_ORIGIN='-R\$$ORIGIN$1'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-h $1'
SET_SHARED_LIBRARY_MAPFILE='-M$1'
--- a/common/autoconf/spec.gmk.in Mon Nov 07 16:08:18 2016 +0000
+++ b/common/autoconf/spec.gmk.in Wed Jul 05 22:25:59 2017 +0200
@@ -788,6 +788,7 @@
SYMBOLS_IMAGE_DIR=$(IMAGES_OUTPUTDIR)/$(SYMBOLS_IMAGE_SUBDIR)
# Interim image
+INTERIM_JMODS_DIR := $(SUPPORT_OUTPUTDIR)/interim-jmods
INTERIM_IMAGE_DIR := $(SUPPORT_OUTPUTDIR)/interim-image
# Docs image
--- a/corba/.hgtags Mon Nov 07 16:08:18 2016 +0000
+++ b/corba/.hgtags Wed Jul 05 22:25:59 2017 +0200
@@ -385,3 +385,4 @@
9f3fc931bc230f44f2a58d75f7f6360af98bb113 jdk-9+140
b32f998da32b488ec7c4e9dbb3c750841b48e74d jdk-9+141
408c9c621938ca028e20bced0459f815de47eba8 jdk-9+142
+6211236ef15ec796806357608b1dd1b70c258ece jdk-9+143
--- a/hotspot/.hgtags Mon Nov 07 16:08:18 2016 +0000
+++ b/hotspot/.hgtags Wed Jul 05 22:25:59 2017 +0200
@@ -545,3 +545,4 @@
fec31089c2ef5a12dd64f401b0bf2e00f56ee0d0 jdk-9+140
160a00bc6ed0af1fdf8418fc65e6bddbbc0c536d jdk-9+141
7b48d63dfd6b8e2657288de3d7b1f153dee02d7e jdk-9+142
+d87d5d430c42342f0320ca7f5cbe0cbd1f9d62ba jdk-9+143
--- a/hotspot/make/symbols/symbols-unix Mon Nov 07 16:08:18 2016 +0000
+++ b/hotspot/make/symbols/symbols-unix Wed Jul 05 22:25:59 2017 +0200
@@ -125,7 +125,6 @@
JVM_GetProtectionDomain
JVM_GetSimpleBinaryName
JVM_GetStackAccessControlContext
-JVM_GetStackTraceElements
JVM_GetSystemPackage
JVM_GetSystemPackages
JVM_GetTemporaryDirectory
@@ -135,6 +134,8 @@
JVM_HoldsLock
JVM_IHashCode
JVM_InitProperties
+JVM_InitStackTraceElement
+JVM_InitStackTraceElementArray
JVM_InternString
JVM_Interrupt
JVM_InvokeMethod
@@ -178,7 +179,6 @@
JVM_StopThread
JVM_SupportsCX8
JVM_SuspendThread
-JVM_ToStackTraceElement
JVM_TotalMemory
JVM_UnloadLibrary
JVM_WaitForReferencePendingList
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Mon Nov 07 16:08:18 2016 +0000
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jul 05 22:25:59 2017 +0200
@@ -2175,6 +2175,14 @@
const char* str = holder->external_name();
oop classname = StringTable::intern((char*) str, CHECK);
java_lang_StackTraceElement::set_declaringClass(element(), classname);
+ java_lang_StackTraceElement::set_declaringClassObject(element(), holder->java_mirror());
+
+ oop loader = holder->class_loader();
+ if (loader != NULL) {
+ oop loader_name = java_lang_ClassLoader::name(loader);
+ if (loader_name != NULL)
+ java_lang_StackTraceElement::set_classLoaderName(element(), loader_name);
+ }
// The method can be NULL if the requested class version is gone
Symbol* sym = !method.is_null() ? method->name() : holder->constants()->symbol_at(cpref);
@@ -3433,6 +3441,7 @@
bool java_lang_ClassLoader::offsets_computed = false;
int java_lang_ClassLoader::_loader_data_offset = -1;
int java_lang_ClassLoader::parallelCapable_offset = -1;
+int java_lang_ClassLoader::name_offset = -1;
int java_lang_ClassLoader::unnamedModule_offset = -1;
ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) {
@@ -3453,6 +3462,9 @@
compute_optional_offset(parallelCapable_offset,
k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature());
+ compute_offset(name_offset,
+ k1, vmSymbols::name_name(), vmSymbols::string_signature());
+
compute_offset(unnamedModule_offset,
k1, vmSymbols::unnamedModule_name(), vmSymbols::module_signature());
@@ -3464,6 +3476,11 @@
return loader->obj_field(parent_offset);
}
+oop java_lang_ClassLoader::name(oop loader) {
+ assert(is_instance(loader), "loader must be oop");
+ return loader->obj_field(name_offset);
+}
+
bool java_lang_ClassLoader::isAncestor(oop loader, oop cl) {
assert(is_instance(loader), "loader must be oop");
assert(cl == NULL || is_instance(cl), "cl argument must be oop");
@@ -3619,12 +3636,14 @@
int java_lang_System::static_out_offset;
int java_lang_System::static_err_offset;
int java_lang_System::static_security_offset;
-int java_lang_StackTraceElement::declaringClass_offset;
int java_lang_StackTraceElement::methodName_offset;
int java_lang_StackTraceElement::fileName_offset;
int java_lang_StackTraceElement::lineNumber_offset;
int java_lang_StackTraceElement::moduleName_offset;
int java_lang_StackTraceElement::moduleVersion_offset;
+int java_lang_StackTraceElement::classLoaderName_offset;
+int java_lang_StackTraceElement::declaringClass_offset;
+int java_lang_StackTraceElement::classOrLoaderModuleClassName_offset;
int java_lang_StackFrameInfo::_declaringClass_offset;
int java_lang_StackFrameInfo::_memberName_offset;
int java_lang_StackFrameInfo::_bci_offset;
@@ -3669,6 +3688,14 @@
element->obj_field_put(moduleVersion_offset, value);
}
+void java_lang_StackTraceElement::set_classLoaderName(oop element, oop value) {
+ element->obj_field_put(classLoaderName_offset, value);
+}
+
+void java_lang_StackTraceElement::set_declaringClassObject(oop element, oop value) {
+ element->obj_field_put(classOrLoaderModuleClassName_offset, value);
+}
+
// Support for java_lang_StackFrameInfo
void java_lang_StackFrameInfo::set_declaringClass(oop element, oop value) {
element->obj_field_put(_declaringClass_offset, value);
@@ -3784,6 +3811,8 @@
java_lang_System::static_security_offset = java_lang_System::hc_static_security_offset * x;
// java_lang_StackTraceElement
+ java_lang_StackTraceElement::classOrLoaderModuleClassName_offset= java_lang_StackTraceElement::hc_classOrLoaderModuleClassName_offset* x + header;
+ java_lang_StackTraceElement::classLoaderName_offset = java_lang_StackTraceElement::hc_classLoaderName_offset * x + header;
java_lang_StackTraceElement::moduleName_offset = java_lang_StackTraceElement::hc_moduleName_offset * x + header;
java_lang_StackTraceElement::moduleVersion_offset = java_lang_StackTraceElement::hc_moduleVersion_offset * x + header;
java_lang_StackTraceElement::declaringClass_offset = java_lang_StackTraceElement::hc_declaringClass_offset * x + header;
@@ -3985,10 +4014,14 @@
// java.lang.StackTraceElement
- CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, declaringClass, "Ljava/lang/String;");
- CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, methodName, "Ljava/lang/String;");
- CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, fileName, "Ljava/lang/String;");
- CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, lineNumber, "I");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, classOrLoaderModuleClassName, "Ljava/lang/Object;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, classLoaderName, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, moduleName, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, moduleVersion, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, declaringClass, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, methodName, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, fileName, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, lineNumber, "I");
// java.lang.ref.Reference
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Mon Nov 07 16:08:18 2016 +0000
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jul 05 22:25:59 2017 +0200
@@ -1225,6 +1225,7 @@
static bool offsets_computed;
static int parent_offset;
static int parallelCapable_offset;
+ static int name_offset;
static int unnamedModule_offset;
public:
@@ -1234,6 +1235,7 @@
static ClassLoaderData* loader_data(oop loader);
static oop parent(oop loader);
+ static oop name(oop loader);
static bool isAncestor(oop loader, oop cl);
// Support for parallelCapable field
@@ -1291,14 +1293,18 @@
class java_lang_StackTraceElement: AllStatic {
private:
enum {
- hc_moduleName_offset = 0,
- hc_moduleVersion_offset = 1,
- hc_declaringClass_offset = 2,
- hc_methodName_offset = 3,
- hc_fileName_offset = 4,
- hc_lineNumber_offset = 5
+ hc_classOrLoaderModuleClassName_offset = 0,
+ hc_classLoaderName_offset = 1,
+ hc_moduleName_offset = 2,
+ hc_moduleVersion_offset = 3,
+ hc_declaringClass_offset = 4,
+ hc_methodName_offset = 5,
+ hc_fileName_offset = 6,
+ hc_lineNumber_offset = 7
};
+ static int classOrLoaderModuleClassName_offset;
+ static int classLoaderName_offset;
static int moduleName_offset;
static int moduleVersion_offset;
static int declaringClass_offset;
@@ -1307,12 +1313,14 @@
static int lineNumber_offset;
// Setters
+ static void set_classLoaderName(oop element, oop value);
static void set_moduleName(oop element, oop value);
static void set_moduleVersion(oop element, oop value);
static void set_declaringClass(oop element, oop value);
static void set_methodName(oop element, oop value);
static void set_fileName(oop element, oop value);
static void set_lineNumber(oop element, int value);
+ static void set_declaringClassObject(oop element, oop value);
public:
// Create an instance of StackTraceElement
--- a/hotspot/src/share/vm/prims/jvm.cpp Mon Nov 07 16:08:18 2016 +0000
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 22:25:59 2017 +0200
@@ -503,16 +503,27 @@
JVM_END
-JVM_ENTRY(void, JVM_GetStackTraceElements(JNIEnv *env, jobject throwable, jobjectArray stackTrace))
- JVMWrapper("JVM_GetStackTraceElements");
+// java.lang.StackTraceElement //////////////////////////////////////////////
+
+
+JVM_ENTRY(void, JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable))
+ JVMWrapper("JVM_InitStackTraceElementArray");
Handle exception(THREAD, JNIHandles::resolve(throwable));
- objArrayOop st = objArrayOop(JNIHandles::resolve(stackTrace));
+ objArrayOop st = objArrayOop(JNIHandles::resolve(elements));
objArrayHandle stack_trace(THREAD, st);
// Fill in the allocated stack trace
java_lang_Throwable::get_stack_trace_elements(exception, stack_trace, CHECK);
JVM_END
+JVM_ENTRY(void, JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo))
+ JVMWrapper("JVM_InitStackTraceElement");
+ Handle stack_frame_info(THREAD, JNIHandles::resolve_non_null(stackFrameInfo));
+ Handle stack_trace_element(THREAD, JNIHandles::resolve_non_null(element));
+ java_lang_StackFrameInfo::to_stack_trace_element(stack_frame_info, stack_trace_element, THREAD);
+JVM_END
+
+
// java.lang.StackWalker //////////////////////////////////////////////////////
@@ -566,13 +577,6 @@
start_index, frames_array_h, THREAD);
JVM_END
-JVM_ENTRY(void, JVM_ToStackTraceElement(JNIEnv *env, jobject frame, jobject stack))
- JVMWrapper("JVM_ToStackTraceElement");
- Handle stack_frame_info(THREAD, JNIHandles::resolve_non_null(frame));
- Handle stack_trace_element(THREAD, JNIHandles::resolve_non_null(stack));
- java_lang_StackFrameInfo::to_stack_trace_element(stack_frame_info, stack_trace_element, THREAD);
-JVM_END
-
// java.lang.Object ///////////////////////////////////////////////
--- a/hotspot/src/share/vm/prims/jvm.h Mon Nov 07 16:08:18 2016 +0000
+++ b/hotspot/src/share/vm/prims/jvm.h Wed Jul 05 22:25:59 2017 +0200
@@ -189,8 +189,14 @@
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
@@ -212,9 +218,6 @@
jint frame_count, jint start_index,
jobjectArray frames);
-JNIEXPORT void JNICALL
-JVM_ToStackTraceElement(JNIEnv* env, jobject frame, jobject stackElement);
-
/*
* java.lang.Thread
*/
--- a/jaxp/.hgtags Mon Nov 07 16:08:18 2016 +0000
+++ b/jaxp/.hgtags Wed Jul 05 22:25:59 2017 +0200
@@ -385,3 +385,4 @@
8d100cb9b04819b5bd09f33c7fd5b8628d1a456f jdk-9+140
037c095ba0c345edbeaaab52fda913a76c3930c0 jdk-9+141
bdafa0cc34a97a2f8db4847a4efd34b407943591 jdk-9+142
+ce81d03ad7320dca3d673374c1a33bc0efd9136a jdk-9+143
--- a/jaxws/.hgtags Mon Nov 07 16:08:18 2016 +0000
+++ b/jaxws/.hgtags Wed Jul 05 22:25:59 2017 +0200
@@ -388,3 +388,4 @@
9004617323fe99cbe4fad48f373cb2ed4fc50aa6 jdk-9+140
b2c18f755228d1d19a86cd7d5fa1abb6b1495dfb jdk-9+141
59101416d90160cfcb4f45dfbccaec15e2c27a29 jdk-9+142
+1c988e708a06257119d54d8a57e99e3b0f37ff18 jdk-9+143
--- a/jdk/.hgtags Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/.hgtags Wed Jul 05 22:25:59 2017 +0200
@@ -385,3 +385,4 @@
e93b7ea559759f036c9f69fd2ddaf47bb4e98385 jdk-9+140
8d752af5f61d41f226adf2cda72a20faa9ad620a jdk-9+141
6ce43dd8e954b452f330dd7a412df5107f7e1923 jdk-9+142
+8dbc8594f9d5149bf1c22221272284609408227a jdk-9+143
--- a/jdk/make/GenerateClasslist.gmk Mon Nov 07 16:08:18 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-#
-# 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.
-#
-
-################################################################################
-# Generate classlist
-################################################################################
-
-default: all
-
-include $(SPEC)
-include MakeBase.gmk
-include Tools.gmk
-include JarArchive.gmk
-
-################################################################################
-# Create a jar with our generator class. Using a jar is intentional since it
-# will load more classes
-
-$(eval $(call SetupJarArchive, CLASSLIST_JAR, \
- SRCS := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \
- INCLUDES := build/tools/classlist, \
- JAR := $(SUPPORT_OUTPUTDIR)/classlist.jar, \
-))
-
-TARGETS += $(CLASSLIST_JAR)
-
-################################################################################
-
-CLASSLIST_FILE := $(SUPPORT_OUTPUTDIR)/classlist/classlist
-
-JLI_TRACE_FILE := $(SUPPORT_OUTPUTDIR)/classlist/jli_trace.out
-
-# If an external buildjdk has been supplied, we don't build a separate interim
-# image, so just use the external build jdk instead.
-ifeq ($(EXTERNAL_BUILDJDK), true)
- INTERIM_IMAGE_DIR := $(BUILD_JDK)
-endif
-
-$(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXE_SUFFIX) $(CLASSLIST_JAR)
- $(call MakeDir, $(@D))
- $(call LogInfo, Generating lib/classlist)
- $(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java -XX:DumpLoadedClassList=$@ \
- -Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true \
- -cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
- build.tools.classlist.HelloClasslist \
- $(LOG_DEBUG) 2>&1 > $(JLI_TRACE_FILE)
-
-TARGETS += $(CLASSLIST_FILE)
-
-################################################################################
-
-all: $(TARGETS)
--- a/jdk/make/mapfiles/libjava/mapfile-vers Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/make/mapfiles/libjava/reorder-sparc Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/make/mapfiles/libjava/reorder-sparcv9 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/make/mapfiles/libjava/reorder-x86 Wed Jul 05 22:25:59 2017 +0200
@@ -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/make/rmic/Rmic-java.rmi.gmk Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/make/rmic/Rmic-java.rmi.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -33,7 +33,7 @@
#
$(eval $(call SetupRMICompilation,RMI_12, \
- CLASSES := sun.rmi.server.Activation$$$$ActivationSystemImpl \
+ CLASSES := sun.rmi.server.Activation$$ActivationSystemImpl \
java.rmi.activation.ActivationGroup, \
CLASSES_DIR := $(CLASSES_DIR)/java.rmi, \
STUB_CLASSES_DIR := $(STUB_CLASSES_DIR)/java.rmi, \
--- a/jdk/src/java.base/share/classes/java/io/File.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/File.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 com.foo.loader/foo@9.0/com.foo.Main.run(Main.java)}"
+ * - The line number is unavailable.
+ * </li>
+ * <li>
+ * "{@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 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(my.module@9.0/MyClass.java)"} - As above, but the
- * line number is unavailable.
- * <li>
- * {@code "MyClass.mash(my.module@9.0/Unknown Source)"} - As above, but
- * neither the file name nor the line number are available.
- * <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 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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Throwable.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java Wed Jul 05 22:25:59 2017 +0200
@@ -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/java/util/ImmutableCollections.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java Wed Jul 05 22:25:59 2017 +0200
@@ -53,7 +53,8 @@
*/
static final int SALT;
static {
- SALT = new Random().nextInt();
+ long nt = System.nanoTime();
+ SALT = (int)((nt >>> 32) ^ nt);
}
/** No instances. */
@@ -63,7 +64,7 @@
* The reciprocal of load factor. Given a number of elements
* to store, multiply by this factor to get the table size.
*/
- static final double EXPAND_FACTOR = 2.0;
+ static final int EXPAND_FACTOR = 2;
static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }
@@ -84,7 +85,14 @@
}
static final class List0<E> extends AbstractImmutableList<E> {
- List0() { }
+ private static final List0<?> INSTANCE = new List0<>();
+
+ @SuppressWarnings("unchecked")
+ static <T> List0<T> instance() {
+ return (List0<T>) INSTANCE;
+ }
+
+ private List0() { }
@Override
public int size() {
@@ -214,7 +222,14 @@
}
static final class Set0<E> extends AbstractImmutableSet<E> {
- Set0() { }
+ private static final Set0<?> INSTANCE = new Set0<>();
+
+ @SuppressWarnings("unchecked")
+ static <T> Set0<T> instance() {
+ return (Set0<T>) INSTANCE;
+ }
+
+ private Set0() { }
@Override
public int size() {
@@ -351,7 +366,7 @@
SetN(E... input) {
size = input.length; // implicit nullcheck of input
- elements = (E[])new Object[(int)Math.ceil(EXPAND_FACTOR * input.length)];
+ elements = (E[])new Object[EXPAND_FACTOR * input.length];
for (int i = 0; i < input.length; i++) {
E e = Objects.requireNonNull(input[i]);
int idx = probe(e);
@@ -450,7 +465,14 @@
}
static final class Map0<K,V> extends AbstractImmutableMap<K,V> {
- Map0() { }
+ private static final Map0<?,?> INSTANCE = new Map0<>();
+
+ @SuppressWarnings("unchecked")
+ static <K,V> Map0<K,V> instance() {
+ return (Map0<K,V>) INSTANCE;
+ }
+
+ private Map0() { }
@Override
public Set<Map.Entry<K,V>> entrySet() {
@@ -529,7 +551,7 @@
}
size = input.length >> 1;
- int len = (int)Math.ceil(EXPAND_FACTOR * input.length);
+ int len = EXPAND_FACTOR * input.length;
len = (len + 1) & ~1; // ensure table is even length
table = new Object[len];
@@ -789,7 +811,7 @@
return Set.of(array);
case IMM_MAP:
if (array.length == 0) {
- return new ImmutableCollections.Map0<>();
+ return ImmutableCollections.Map0.instance();
} else if (array.length == 2) {
return new ImmutableCollections.Map1<>(array[0], array[1]);
} else {
--- a/jdk/src/java.base/share/classes/java/util/List.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/List.java Wed Jul 05 22:25:59 2017 +0200
@@ -786,7 +786,7 @@
* @since 9
*/
static <E> List<E> of() {
- return new ImmutableCollections.List0<>();
+ return ImmutableCollections.List0.instance();
}
/**
@@ -1030,7 +1030,7 @@
Objects.requireNonNull(elements);
switch (elements.length) {
case 0:
- return new ImmutableCollections.List0<>();
+ return ImmutableCollections.List0.instance();
case 1:
return new ImmutableCollections.List1<>(elements[0]);
case 2:
--- a/jdk/src/java.base/share/classes/java/util/Map.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/Map.java Wed Jul 05 22:25:59 2017 +0200
@@ -1286,7 +1286,7 @@
* @since 9
*/
static <K, V> Map<K, V> of() {
- return new ImmutableCollections.Map0<>();
+ return ImmutableCollections.Map0.instance();
}
/**
@@ -1604,7 +1604,7 @@
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
Objects.requireNonNull(entries);
if (entries.length == 0) {
- return new ImmutableCollections.Map0<>();
+ return ImmutableCollections.Map0.instance();
} else if (entries.length == 1) {
return new ImmutableCollections.Map1<>(entries[0].getKey(),
entries[0].getValue());
--- a/jdk/src/java.base/share/classes/java/util/Set.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/Set.java Wed Jul 05 22:25:59 2017 +0200
@@ -448,7 +448,7 @@
* @since 9
*/
static <E> Set<E> of() {
- return new ImmutableCollections.Set0<>();
+ return ImmutableCollections.Set0.instance();
}
/**
@@ -692,7 +692,7 @@
Objects.requireNonNull(elements);
switch (elements.length) {
case 0:
- return new ImmutableCollections.Set0<>();
+ return ImmutableCollections.Set0.instance();
case 1:
return new ImmutableCollections.Set1<>(elements[0]);
case 2:
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/native/include/jvm.h Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.base/share/native/libjava/Throwable.c Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXSurfaceData.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/QuartzSurfaceData.h Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/QuartzSurfaceData.m Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/package.html Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/ExifGPSTagSet.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/ExifTIFFTagSet.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFField.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFImageReadParam.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JRootPane.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalScrollBarUI.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/font/NullFontScaler.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/swing/plaf/GTKKeybindings.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.management/share/classes/sun/management/StackTraceElementCompositeData.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/CallableStatement.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/Date.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/DriverManager.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/PreparedStatement.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/ResultSet.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/Time.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/Timestamp.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java Wed Jul 05 22:25:59 2017 +0200
@@ -359,9 +359,9 @@
if (name.endsWith(".class") && !name.endsWith("module-info.class")) {
try {
byte[] bytes = reader.getResource(location);
- ClassReader cr =new ClassReader(bytes);
+ ClassReader cr = new ClassReader(bytes);
ClassNode cn = new ClassNode();
- cr.accept(cn, ClassReader.EXPAND_FRAMES);
+ cr.accept(cn, 0);
} catch (Exception ex) {
log.println("Error(s) in Class: " + name);
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Wed Jul 05 22:25:59 2017 +0200
@@ -33,7 +33,6 @@
import java.lang.module.ModuleReference;
import java.lang.module.ResolutionException;
import java.lang.module.ResolvedModule;
-import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.nio.ByteOrder;
import java.nio.file.Files;
@@ -41,6 +40,7 @@
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import jdk.tools.jlink.internal.TaskHelper.BadArgs;
import static jdk.tools.jlink.internal.TaskHelper.JLINK_BUNDLE;
@@ -62,20 +62,8 @@
public class JlinkTask {
static final boolean DEBUG = Boolean.getBoolean("jlink.debug");
- private static <T extends Throwable> void fail(Class<T> type,
- String format,
- Object... args) throws T {
- String msg = new Formatter().format(format, args).toString();
- try {
- T t = type.getConstructor(String.class).newInstance(msg);
- throw t;
- } catch (InstantiationException |
- InvocationTargetException |
- NoSuchMethodException |
- IllegalAccessException e) {
- throw new InternalError("Unable to create an instance of " + type, e);
- }
- }
+ // jlink API ignores by default. Remove when signing is implemented.
+ static final boolean IGNORE_SIGNING_DEFAULT = true;
private static final TaskHelper taskHelper
= new TaskHelper(JLINK_BUNDLE);
@@ -143,7 +131,10 @@
}, "--save-opts"),
new Option<JlinkTask>(false, (task, opt, arg) -> {
task.options.fullVersion = true;
- }, true, "--full-version"),};
+ }, true, "--full-version"),
+ new Option<JlinkTask>(false, (task, opt, arg) -> {
+ task.options.ignoreSigning = true;
+ }, true, "--ignore-signing-information"),};
private static final String PROGNAME = "jlink";
private final OptionsValues options = new OptionsValues();
@@ -160,7 +151,8 @@
/**
* Result codes.
*/
- static final int EXIT_OK = 0, // Completed with no errors.
+ static final int
+ EXIT_OK = 0, // Completed with no errors.
EXIT_ERROR = 1, // Completed but reported errors.
EXIT_CMDERR = 2, // Bad command-line arguments
EXIT_SYSERR = 3, // System error or resource exhaustion.
@@ -171,12 +163,13 @@
String saveoptsfile;
boolean version;
boolean fullVersion;
- List<Path> modulePath = new ArrayList<>();
- Set<String> limitMods = new HashSet<>();
- Set<String> addMods = new HashSet<>();
+ final List<Path> modulePath = new ArrayList<>();
+ final Set<String> limitMods = new HashSet<>();
+ final Set<String> addMods = new HashSet<>();
Path output;
Path packagedModulesPath;
ByteOrder endian = ByteOrder.nativeOrder();
+ boolean ignoreSigning = false;
}
int run(String[] args) {
@@ -199,7 +192,7 @@
return EXIT_OK;
}
if (taskHelper.getExistingImage() == null) {
- if (options.modulePath == null || options.modulePath.isEmpty()) {
+ if (options.modulePath.isEmpty()) {
throw taskHelper.newBadArgs("err.modulepath.must.be.specified").showUsage(true);
}
createImage();
@@ -248,20 +241,25 @@
plugins = plugins == null ? new PluginsConfiguration() : plugins;
if (config.getModulepaths().isEmpty()) {
- throw new Exception("Empty module paths");
+ throw new IllegalArgumentException("Empty module paths");
}
ModuleFinder finder = newModuleFinder(config.getModulepaths(),
config.getLimitmods(),
config.getModules());
+ if (config.getModules().isEmpty()) {
+ throw new IllegalArgumentException("No modules to add");
+ }
+
// First create the image provider
- ImageProvider imageProvider
- = createImageProvider(finder,
- checkAddMods(config.getModules()),
- config.getLimitmods(),
- config.getByteOrder(),
- null);
+ ImageProvider imageProvider =
+ createImageProvider(finder,
+ config.getModules(),
+ config.getLimitmods(),
+ config.getByteOrder(),
+ null,
+ IGNORE_SIGNING_DEFAULT);
// Then create the Plugin Stack
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(plugins);
@@ -299,19 +297,17 @@
}
ModuleFinder finder
= newModuleFinder(options.modulePath, options.limitMods, options.addMods);
- try {
- options.addMods = checkAddMods(options.addMods);
- } catch (IllegalArgumentException ex) {
+ if (options.addMods.isEmpty()) {
throw taskHelper.newBadArgs("err.mods.must.be.specified", "--add-modules")
.showUsage(true);
}
// First create the image provider
- ImageProvider imageProvider
- = createImageProvider(finder,
+ ImageProvider imageProvider = createImageProvider(finder,
options.addMods,
options.limitMods,
options.endian,
- options.packagedModulesPath);
+ options.packagedModulesPath,
+ options.ignoreSigning);
// Then create the Plugin Stack
ImagePluginStack stack = ImagePluginConfiguration.
@@ -321,13 +317,6 @@
stack.operate(imageProvider);
}
- private static Set<String> checkAddMods(Set<String> addMods) {
- if (addMods.isEmpty()) {
- throw new IllegalArgumentException("no modules to add");
- }
- return addMods;
- }
-
/**
* Returns a module finder to find the observable modules specified in
* the --module-path and --limit-modules options
@@ -343,7 +332,7 @@
return finder;
}
- /**
+ /*
* Returns a module finder of the given module path that limits
* the observable modules to those in the transitive closure of
* the modules specified in {@code limitMods} plus other modules
@@ -376,7 +365,8 @@
Set<String> addMods,
Set<String> limitMods,
ByteOrder order,
- Path retainModulesPath)
+ Path retainModulesPath,
+ boolean ignoreSigning)
throws IOException
{
if (addMods.isEmpty()) {
@@ -390,10 +380,10 @@
Map<String, Path> mods = cf.modules().stream()
.collect(Collectors.toMap(ResolvedModule::name, JlinkTask::toPathLocation));
- return new ImageHelper(cf, mods, order, retainModulesPath);
+ return new ImageHelper(cf, mods, order, retainModulesPath, ignoreSigning);
}
- /**
+ /*
* Returns a ModuleFinder that limits observability to the given root
* modules, their transitive dependences, plus a set of other modules.
*/
@@ -477,36 +467,57 @@
}
private static class ImageHelper implements ImageProvider {
-
- final Set<Archive> archives;
final ByteOrder order;
final Path packagedModulesPath;
+ final boolean ignoreSigning;
+ final Set<Archive> archives;
ImageHelper(Configuration cf,
Map<String, Path> modsPaths,
ByteOrder order,
- Path packagedModulesPath) throws IOException {
- archives = modsPaths.entrySet().stream()
+ Path packagedModulesPath,
+ boolean ignoreSigning) throws IOException {
+ this.order = order;
+ this.packagedModulesPath = packagedModulesPath;
+ this.ignoreSigning = ignoreSigning;
+ this.archives = modsPaths.entrySet().stream()
.map(e -> newArchive(e.getKey(), e.getValue()))
.collect(Collectors.toSet());
- this.order = order;
- this.packagedModulesPath = packagedModulesPath;
}
private Archive newArchive(String module, Path path) {
if (path.toString().endsWith(".jmod")) {
return new JmodArchive(module, path);
} else if (path.toString().endsWith(".jar")) {
- return new ModularJarArchive(module, path);
+ ModularJarArchive modularJarArchive = new ModularJarArchive(module, path);
+
+ Stream<Archive.Entry> signatures = modularJarArchive.entries().filter((entry) -> {
+ String name = entry.name().toUpperCase(Locale.ENGLISH);
+
+ return name.startsWith("META-INF/") && name.indexOf('/', 9) == -1 && (
+ name.endsWith(".SF") ||
+ name.endsWith(".DSA") ||
+ name.endsWith(".RSA") ||
+ name.endsWith(".EC") ||
+ name.startsWith("META-INF/SIG-")
+ );
+ });
+
+ if (signatures.count() != 0) {
+ if (ignoreSigning) {
+ System.err.println(taskHelper.getMessage("warn.signing", path));
+ } else {
+ throw new IllegalArgumentException(taskHelper.getMessage("err.signing", path));
+ }
+ }
+
+ return modularJarArchive;
} else if (Files.isDirectory(path)) {
return new DirArchive(path);
} else {
- fail(RuntimeException.class,
- "Selected module %s (%s) not in jmod or modular jar format",
- module,
- path);
+ throw new IllegalArgumentException(
+ taskHelper.getMessage("err.not.modular.format", module, path));
}
- return null;
}
@Override
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Wed Jul 05 22:25:59 2017 +0200
@@ -212,7 +212,7 @@
mainOptions.add(new PlugOption(true, (task, opt, arg) -> {
Path path = Paths.get(arg);
if (!Files.exists(path) || !Files.isDirectory(path)) {
- throw newBadArgs("err.existing.image.must.exist");
+ throw newBadArgs("err.image.must.exist");
}
existingImage = path.toAbsolutePath();
}, true, POST_PROCESS));
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties Wed Jul 05 22:25:59 2017 +0200
@@ -62,6 +62,9 @@
main.opt.save-opts=\
\ --save-opts <filename> Save jlink options in the given file
+main.opt.ignore-signing-information=\
+\ --ignore-signing-information Ignore signing information in modular JARs
+
main.msg.bug=\
An exception has occurred in jlink. \
Please file a bug at the Java Bug Database (http://bugreport.java.com/bugreport/) \
@@ -88,7 +91,7 @@
err.mods.must.be.specified:no modules specified to {0}
err.path.not.found=path not found: {0}
err.path.not.valid=invalid path: {0}
-err.existing.image.must.exist=existing image doesn't exists or is not a directory
+err.image.must.exist=image does not exist or is not a directory
err.existing.image.invalid=existing image is not valid
err.file.not.found=cannot find file: {0}
err.file.error=cannot access file: {0}
@@ -104,5 +107,9 @@
err.config.defaults=property {0} is missing from configuration
err.config.defaults.value=wrong value in defaults property: {0}
err.bom.generation=bom file generation failed: {0}
-warn.invalid.arg=Invalid classname or pathname not exist: {0}
+err.not.modular.format=selected module {0} ({1}) not in jmod or modular JAR format
+err.signing=signed modular JAR {0} is currently not supported,\
+\ use --ignore-signing-information to suppress error
+warn.signing=signed modular JAR {0} is currently not supported
+warn.invalid.arg=invalid classname or pathname not exist: {0}
warn.split.package=package {0} defined in {1} {2}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Wed Jul 05 22:25:59 2017 +0200
@@ -47,6 +47,7 @@
import java.lang.module.ResolvedModule;
import java.net.URI;
import java.nio.file.FileSystems;
+import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
@@ -633,7 +634,8 @@
void processSection(JmodOutputStream out, Section section, Path top)
throws IOException
{
- Files.walkFileTree(top, new SimpleFileVisitor<Path>() {
+ Files.walkFileTree(top, Set.of(FileVisitOption.FOLLOW_LINKS),
+ Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException
--- a/jdk/test/ProblemList.txt Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/ProblemList.txt Wed Jul 05 22:25:59 2017 +0200
@@ -184,6 +184,8 @@
java/nio/file/WatchService/MayFlies.java 7158947 solaris-all Solaris 11
java/nio/file/WatchService/LotsOfEvents.java 7158947 solaris-all Solaris 11
+sun/nio/cs/OLD/TestIBMDB.java 8167525 generic-all
+
############################################################################
# jdk_rmi
@@ -217,6 +219,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/com/sun/jndi/dns/Parser.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/com/sun/jndi/dns/Parser.java Wed Jul 05 22:25:59 2017 +0200
@@ -26,6 +26,7 @@
* @bug 8035105
* @summary DNS resource record parsing
* @modules jdk.naming.dns/com.sun.jndi.dns
+ * @compile --add-modules jdk.naming.dns Parser.java
*/
import com.sun.jndi.dns.ResourceRecord;
--- a/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java Wed Jul 05 22:25:59 2017 +0200
@@ -28,7 +28,7 @@
* @modules jdk.naming.rmi/com.sun.jndi.rmi.registry java.rmi/sun.rmi.registry
* java.rmi/sun.rmi.server java.rmi/sun.rmi.transport java.rmi/sun.rmi.transport.tcp
* @library ../../../../../../java/rmi/testlibrary
- * @build TestLibrary
+ * @compile --add-modules jdk.naming.rmi ContextWithNullProperties.java
* @run main ContextWithNullProperties
*/
--- a/jdk/test/java/awt/FileDialog/8017487/bug8017487.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/awt/FileDialog/8017487/bug8017487.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/awt/TrayIcon/DragEventSource/DragEventSource.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/awt/Window/ChangeWindowResizabilty/ChangeWindowResizabiltyTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/SerialFilterTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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/ClassLoader/platformClassLoader/DefinePlatformClass.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/lang/ClassLoader/platformClassLoader/DefinePlatformClass.java Wed Jul 05 22:25:59 2017 +0200
@@ -24,8 +24,9 @@
/*
* @test
* @summary Test java.* class defined by the platform class loader
- * @build jdk.zipfs/java.fake.Fake
* @modules jdk.zipfs/java.fake
+ * @build jdk.zipfs/java.fake.Fake
+ * @compile --add-modules jdk.zipfs DefinePlatformClass.java
* @run main DefinePlatformClass
*/
--- a/jdk/test/java/lang/StackTraceElement/PublicConstructor.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/lang/StackTraceElement/PublicConstructor.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/lang/annotation/AnnotationToStringTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/lang/management/CompositeData/ThreadInfoCompositeData.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/net/URLClassLoader/NullURLTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/net/URLPermission/nstest/LookupTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 e) {
+ if (!throwsIOException) {
+ System.err.println("Unexpected IOException:" + e.getMessage());
+ throw new RuntimeException(e);
}
return;
- } catch (IOException ioe) {
- if (!throwsIOException) {
- throw new RuntimeException ("(2) was not expecting ", ioe);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ System.err.println("Unexpected IOException:" + e.getMessage());
+ throw new RuntimeException(e);
+ }
}
- return;
}
+
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' };
- static void startServer() {
- try {
- serverSocket = new ServerSocket(port);
- server = new Server();
- server.start();
- } catch (Exception e) {
- throw new RuntimeException ("Test failed to initialize", e);
+ // 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;
+ }
+ }
}
}
- 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 Mon Nov 07 16:08:18 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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/net/httpclient/APIErrors.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/net/httpclient/ManyRequests.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/net/httpclient/RequestBodyTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/net/httpclient/SmokeTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/net/httpclient/security/Driver.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/net/httpclient/security/Security.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/net/ipv6tests/Tests.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/net/ipv6tests/UdpTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectionAndMapModifyStreamTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IterateTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 Wed Jul 05 22:25:59 2017 +0200
@@ -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 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 com.sun.media.sound.JDK13Services;
+
+/**
+ * @test
+ * @bug 4776511
+ * @summary RFE: Setting the default MixerProvider. Test the cacheing of
+ * providers. This is a part of the test for 4776511.
+ * @modules java.desktop/com.sun.media.sound
+ */
+public class ProviderCacheing {
+
+ private static final Class[] providerClasses = {
+ javax.sound.midi.spi.MidiDeviceProvider.class,
+ javax.sound.midi.spi.MidiFileReader.class,
+ javax.sound.midi.spi.MidiFileWriter.class,
+ javax.sound.midi.spi.SoundbankReader.class,
+ };
+
+ public static void main(String[] args) throws Exception {
+ boolean allCached = true;
+ for (int i = 0; i < providerClasses.length; i++) {
+ List list0 = JDK13Services.getProviders(providerClasses[i]);
+ List list1 = JDK13Services.getProviders(providerClasses[i]);
+ if (list0 == list1) {
+ out("Providers should not be cached for " + providerClasses[i]);
+ allCached = false;
+ }
+ }
+
+ if (! allCached) {
+ 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/testdata/conf/sound.properties Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+
+javax.sound.midi.Receiver=xyz#123
+javax.sound.midi.Transmitter=xyz#123
+javax.sound.midi.Sequencer=xyz#123
+javax.sound.midi.Synthesizer=xyz#123
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequence/GetMicrosecondLength.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,151 @@
+/*
+ * 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.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4929955
+ * @summary Sequence.getMicrosecondLength() returns wrong value
+ */
+public class GetMicrosecondLength {
+
+ public static boolean failed = false;
+ //private static Sequencer seq = null;
+
+ public static void main(String[] args) throws Exception {
+ /*
+ try {
+ seq = MidiSystem.getSequencer();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ */
+ for (int sec = 1; sec < 10; sec += 4) {
+ for (int tempo=0; tempo < 1000; tempo+=120) {
+ for (int resolution=1; resolution < 480; ) {
+ testSequence(sec, tempo, resolution);
+ if (resolution == 1) {
+ resolution = 120;
+ } else {
+ resolution += 120;
+ }
+ }
+ }
+ }
+ if (failed) throw new Exception("Test FAILED!");
+ out("Test Passed.");
+ }
+
+ /**
+ * Create a new Sequence for testing.
+ */
+ private static void testSequence(int lengthInSeconds, int tempoInBPM, int resolution) {
+ Sequence sequence = null;
+ long lengthInMicroseconds = lengthInSeconds * 1000000;
+ boolean createTempoEvent = true;
+ if (tempoInBPM == 0) {
+ tempoInBPM = 120;
+ createTempoEvent = false;
+ System.out.print("Creating sequence: "+lengthInSeconds+"sec, "
+ +"resolution="+resolution+" ticks/beat...");
+ } else {
+ System.out.print("Creating sequence: "+lengthInSeconds+"sec, "
+ +tempoInBPM+" beats/min, "
+ +"resolution="+resolution+" ticks/beat...");
+ }
+ //long lengthInTicks = (lengthInMicroseconds * resolution) / tempoInBPM;
+ long lengthInTicks = (lengthInMicroseconds * tempoInBPM * resolution) / 60000000l;
+ //out("expected length in ticks: " + lengthInTicks);
+ try {
+ sequence = new Sequence(Sequence.PPQ, resolution);
+ Track track = sequence.createTrack();
+ if (createTempoEvent) {
+ int tempoInMPQ = (int) (60000000l / tempoInBPM);
+ MetaMessage tm = new MetaMessage();
+ byte[] msg = new byte[3];
+ msg[0] = (byte) (tempoInMPQ >> 16);
+ msg[1] = (byte) ((tempoInMPQ >> 8) & 0xFF);
+ msg[2] = (byte) (tempoInMPQ & 0xFF);
+
+ tm.setMessage(0x51 /* Meta Tempo */, msg, msg.length);
+ track.add(new MidiEvent(tm, 0));
+ //out("regtest: tempoInMPQ="+tempoInMPQ);
+ //out("Added tempo event: new size="+track.size());
+ }
+ ShortMessage mm = new ShortMessage();
+ mm.setMessage(0xF6, 0, 0);
+ MidiEvent me = new MidiEvent(mm, lengthInTicks);
+ track.add(me);
+ //out("Added realtime event: new size="+track.size());
+ } catch (InvalidMidiDataException e) {
+ out(e);
+ }
+ boolean thisFailed = false;
+ long actualLengthInTicks = sequence.getTickLength();
+ // allow +/- 5%
+ if (Math.abs(actualLengthInTicks - lengthInTicks) > lengthInTicks / 20) {
+ out("FAILED:");
+ out(" expected length in ticks: " + lengthInTicks);
+ out(" actual length in ticks : " + actualLengthInTicks);
+ thisFailed = true;
+ }
+ long actualLengthInUs = sequence.getMicrosecondLength();
+ // allow +/- 5%
+ if (Math.abs(actualLengthInUs - lengthInMicroseconds) > lengthInMicroseconds / 20) {
+ if (!thisFailed) {
+ out("FAILED:");
+ }
+ out(" expected length in microsecs: " + lengthInMicroseconds);
+ out(" actual length in microsecs : " + actualLengthInUs);
+ thisFailed = true;
+ }
+ if (!thisFailed) {
+ out("OK");
+ }
+ /*if (seq != null) {
+ try {
+ seq.setSequence(sequence);
+ out("Sequencer tempo="+seq.getTempoInBPM());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ */
+ failed |= thisFailed;
+ }
+
+
+ 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/Sequence/MidiSMPTE.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * 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.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+
+/**
+ * @test
+ * @bug 4291250
+ * @summary Midi files with SMPTE time do not play properly
+ */
+public class MidiSMPTE {
+
+ public static void main(String[] args) throws Exception {
+ Sequence s = null;
+ //File midiFile = new File("outsmpte.mid");
+ //InputStream is = new FileInputStream(midiFile);
+ //is = new BufferedInputStream(is);
+ InputStream is = new ByteArrayInputStream(smptemidifile);
+ s = MidiSystem.getSequence(is);
+ long duration = s.getMicrosecondLength() / 1000000;
+ System.out.println("Duration: "+duration+" seconds ");
+ if (duration > 14) {
+ throw new Exception("SMPTE time reader is broken! Test FAILED");
+ }
+ System.out.println("Test passed");
+ }
+
+ public static void printFile(String filename) throws Exception {
+ File file = new File(filename);
+ FileInputStream fis = new FileInputStream(file);
+ byte[] data = new byte[(int) file.length()];
+ fis.read(data);
+ String s = "";
+ for (int i=0; i<data.length; i++) {
+ s+=String.valueOf(data[i])+", ";
+ if (s.length()>72) {
+ System.out.println(s);
+ s="";
+ }
+ }
+ System.out.println(s);
+ }
+
+ // A MIDI file with SMPTE timing
+ static byte[] smptemidifile = {
+ 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
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequence/SMPTEDuration.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,94 @@
+/*
+ * 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.InvalidMidiDataException;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4702328
+ * @summary Wrong time in sequence for SMPTE based types
+ */
+public class SMPTEDuration {
+
+ public static void main(String args[]) throws Exception {
+ int[][] dataMes = { {ShortMessage.NOTE_ON, 10, 0x24, 0x50} ,
+ { ShortMessage.NOTE_OFF, 10, 0x24, 0x44 },
+ { ShortMessage.NOTE_ON, 10, 0x24, 0x50 },
+ { ShortMessage.NOTE_ON, 10, 0x26, 0x50 },
+ { ShortMessage.NOTE_OFF, 10, 0x26, 0x53 } };
+ long[] ticks = { 0, 68, 240, 240, 286};
+ int res = 240;
+ ShortMessage msg;
+ Sequence midiData = null;
+ Track track;
+ boolean failed = false;
+
+
+ try {
+ midiData = new Sequence(Sequence.SMPTE_24 , res);
+ } catch (InvalidMidiDataException invMidiEx) {
+ invMidiEx.printStackTrace(System.out);
+ System.out.println("Unexpected InvalidMidiDataException: "
+ + invMidiEx.getMessage());
+ failed = true;
+ }
+ track = midiData.createTrack();
+ for (int i = 0; i < dataMes.length; i++) {
+ msg = new ShortMessage();
+ try {
+ msg.setMessage(dataMes[i][0], dataMes[i][1], dataMes[i][2],
+ dataMes[i][3]);
+ } catch (InvalidMidiDataException invMidiEx) {
+ invMidiEx.printStackTrace(System.out);
+ System.out.println("Unexpected InvalidMidiDataException: "
+ + invMidiEx.getMessage());
+ failed = true;
+ }
+ track.add(new MidiEvent(msg, ticks[i]));
+ }
+ // lengthInMs = (tickLength*1000000)/(divType*Res)
+ long micros = (long) ((midiData.getTickLength() * 1000000) / (res * Sequence.SMPTE_24));
+ if (midiData.getMicrosecondLength() != micros) {
+ failed = true;
+ System.out.println("getMicrosecondLength() returns wrong length: "
+ + midiData.getMicrosecondLength());
+ System.out.println("getMicrosecondLength() must return length: "
+ + micros);
+ }
+ if (midiData.getTickLength() != 286) {
+ failed = true;
+ System.out.println("getTickLength() returns wrong length: "
+ + midiData.getTickLength());
+ }
+
+ if( failed == true ) {
+ throw new Exception("test failed");
+ } else {
+ System.out.println("Passed.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequencer/LoopIAE.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * 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 javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 5025549
+ * @summary Verify that setLoopEndPoint throws IAE
+ */
+public class LoopIAE {
+
+ static ShortMessage MidiMsg3(int a, int b, int c) {
+ try {
+ ShortMessage msg = new ShortMessage();
+ msg.setMessage((byte)a,(byte)b,(byte)c);
+ return msg;
+ } catch(InvalidMidiDataException ex) {
+ throw new RuntimeException();
+ }
+ }
+
+ static boolean failed = false;
+
+ public static void main(String[] argv) throws Exception {
+ if (!hasSequencer()) {
+ return;
+ }
+ Sequencer sequencer = MidiSystem.getSequencer();
+ Sequence sequence = new Sequence(Sequence.PPQ, 240);
+ Track track = sequence.createTrack();
+
+ track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,100),0));
+ track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,0),0 + 240));
+ track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,100),10*20));
+ track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,0),10*20 + 10));
+
+ try {
+ sequencer.open();
+ sequencer.setSequence(sequence);
+ sequencer.setTempoInBPM(100);
+
+ System.out.println("Setting loop end point to 1");
+ sequencer.setLoopEndPoint(1);
+ System.out.println(" -> effectively: "+sequencer.getLoopEndPoint());
+ System.out.println("Setting loop start point to 2 -- should throw IAE");
+ sequencer.setLoopStartPoint(2);
+ System.out.println(" -> effectively: "+sequencer.getLoopStartPoint());
+ System.out.println("No IllegalArgumentException was thrown!");
+ failed = true;
+ } catch (IllegalArgumentException iae) {
+ System.out.println("IAE was thrown correctly.");
+ } catch (MidiUnavailableException mue) {
+ System.out.println("MidiUnavailableException was thrown: " + mue);
+ System.out.println("Cannot execute test.");
+ } catch (InvalidMidiDataException imEx) {
+ System.out.println("InvalidMidiDataException was thrown.");
+ imEx.printStackTrace();
+ System.out.println("Cannot execute test.");
+ } finally {
+ if (sequencer != null && sequencer.isOpen()) {
+ sequencer.close();
+ }
+ }
+ if (failed) {
+ throw new Exception("Test FAILED!");
+ }
+ System.out.println("test passed.");
+ }
+
+ static boolean hasSequencer() {
+ try {
+ Sequencer seq = MidiSystem.getSequencer();
+ if (seq != null) {
+ if (seq.isOpen()) {
+ seq.close();
+ }
+ return true;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ System.out.println("No sequencer available! Cannot execute test.");
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequencer/Looping.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,315 @@
+/*
+ * 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.MetaEventListener;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4204105
+ * @summary RFE: add loop() method(s) to Sequencer
+ * @key intermittent
+ */
+public class Looping {
+
+ public static void main(String[] args) throws Exception {
+ out("4204105: RFE: add loop() method(s) to Sequencer");
+ boolean passed = testAll();
+ if (passed) {
+ out("Test PASSED.");
+ } else {
+ throw new Exception("Test FAILED.");
+ }
+ }
+
+ /**
+ * Execute the test on all available Sequencers.
+ *
+ * @return true if the test passed for all Sequencers, false otherwise
+ */
+ private static boolean testAll() throws Exception {
+ boolean result = true;
+ MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
+ for (int i = 0; i < devices.length; i++) {
+ MidiDevice device = MidiSystem.getMidiDevice(devices[i]);
+ if (device instanceof Sequencer) {
+ result &= testSequencer((Sequencer) device);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Execute the test on the passed Sequencer.
+ *
+ * @return true if the test is passed this Sequencer, false otherwise
+ */
+ private static boolean testSequencer(Sequencer seq) throws Exception{
+ boolean result = true;
+ out("testing: " + seq);
+
+ result &= testGetSet(seq);
+
+ seq.setSequence(createSequence());
+
+ result &= testGetSet(seq);
+
+ result &= testPlay(seq);
+
+ return result;
+ }
+
+ private static boolean testGetSet(Sequencer seq) {
+ boolean result = true;
+ Sequence sequence = seq.getSequence();
+ boolean isSequenceLoaded = (sequence != null);
+
+ out("TestGetSet");
+
+ try {
+ if (seq.getLoopStartPoint() != 0) {
+ out("start point", isSequenceLoaded,
+ "isn't 0!");
+ result = false;
+ }
+ } catch (IllegalArgumentException iae) {
+ if (!isSequenceLoaded) {
+ out("Caught permissable IllegalArgumentException:");
+ } else {
+ out("Threw unacceptable IllegalArgumentException! FAILED");
+ result = false;
+ }
+ out(iae.toString());
+ }
+
+ if (seq.getLoopEndPoint() != -1) {
+ out("end point", isSequenceLoaded,
+ "isn't -1!");
+ result = false;
+ }
+
+ try {
+ seq.setLoopStartPoint(25);
+ if (seq.getLoopStartPoint() != 25) {
+ out("setLoopStartPoint()", isSequenceLoaded,
+ "doesn't set the start point correctly!");
+ result = false;
+ }
+ } catch (IllegalArgumentException iae) {
+ if (!isSequenceLoaded) {
+ out("Caught permissable IllegalArgumentException:");
+ } else {
+ out("Threw unacceptable IllegalArgumentException! FAILED");
+ result = false;
+ }
+ out(iae.toString());
+ }
+
+ try {
+ seq.setLoopEndPoint(26);
+ if (seq.getLoopEndPoint() != 26) {
+ out("setLoopEndPoint()", isSequenceLoaded,
+ "doesn't set the end point correctly!");
+ result = false;
+ }
+ } catch (IllegalArgumentException iae) {
+ if (!isSequenceLoaded) {
+ out("Caught permissable IllegalArgumentException:");
+ } else {
+ out("Threw unacceptable IllegalArgumentException! FAILED");
+ result = false;
+ }
+ out(iae.toString());
+ }
+
+ try {
+ seq.setLoopStartPoint(0);
+ if (seq.getLoopStartPoint() != 0) {
+ out("setLoopStartPoint()", isSequenceLoaded,
+ "doesn't set the start point correctly!");
+ result = false;
+ }
+ } catch (IllegalArgumentException iae) {
+ if (!isSequenceLoaded) {
+ out("Caught permissable IllegalArgumentException:");
+ } else {
+ out("Threw unacceptable IllegalArgumentException! FAILED");
+ result = false;
+ }
+ out(iae.toString());
+ }
+
+ if (isSequenceLoaded) {
+ seq.setLoopEndPoint(sequence.getTickLength());
+ if (seq.getLoopEndPoint() != sequence.getTickLength()) {
+ out("setLoopEndPoint()", isSequenceLoaded,
+ "doesn't set the end point correctly!");
+ result = false;
+ }
+ } else {
+ // fails
+ seq.setLoopEndPoint(-1);
+ if (seq.getLoopEndPoint() != -1) {
+ out("setLoopEndPoint()", isSequenceLoaded,
+ "doesn't set the end point correctly!");
+ result = false;
+ }
+ }
+
+ if (seq.getLoopCount() != 0) {
+ out("loop count", isSequenceLoaded,
+ "isn't 0!");
+ result = false;
+ }
+
+ seq.setLoopCount(1001);
+ if (seq.getLoopCount() != 1001) {
+ out("setLoopCount()", isSequenceLoaded,
+ "doesn't set the loop count correctly!");
+ result = false;
+ }
+
+ seq.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
+ if (seq.getLoopCount() != Sequencer.LOOP_CONTINUOUSLY) {
+ out("setLoopCount(Sequencer.LOOP_CONTINUOUSLY)", isSequenceLoaded,
+ "doesn't set the loop count correctly!");
+ result = false;
+ }
+
+ try {
+ seq.setLoopCount(-55);
+ out("setLoopCount()", isSequenceLoaded,
+ "doesn't throw IllegalArgumentException on illegal value!");
+ result = false;
+ } catch (IllegalArgumentException e) {
+ // EXCEPTION IS EXPECTED
+ out("Caught permissable IAE");
+ }
+
+ seq.setLoopCount(0);
+ if (seq.getLoopCount() != 0) {
+ out("setLoopCount()", isSequenceLoaded,
+ "doesn't set the loop count correctly!");
+ result = false;
+ }
+
+ return result;
+ }
+
+ private static boolean testPlay(Sequencer seq) {
+ boolean result = true;
+ long stopTime;
+
+ out("TestPlay");
+
+ TestMetaEventListener listener = new TestMetaEventListener();
+ seq.addMetaEventListener(listener);
+ long startTime = System.currentTimeMillis();
+ try {
+ seq.open();
+ out("Playing sequence, length="+(seq.getMicrosecondLength()/1000)+"millis");
+ seq.start();
+ while (true) {
+ stopTime = listener.getStopTime();
+ if (stopTime != 0) {
+ break;
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ long measuredDuration = stopTime - startTime;
+ out("play duration (us): " + measuredDuration);
+ } catch (Exception e) {
+ out("test not executed; exception:");
+ e.printStackTrace();
+ }
+ seq.close();
+ return result;
+ }
+
+ /**
+ * Create a new Sequence for testing.
+ *
+ * @return a dummy Sequence, or null, if a problem occured while creating
+ * the Sequence
+ */
+ private static Sequence createSequence() {
+ Sequence sequence = null;
+ int lengthInSeconds = 2;
+ long lengthInMicroseconds = lengthInSeconds * 1000000;
+ int resolution = 480;
+ long lengthInTicks = (lengthInMicroseconds * 120 * resolution) / 60000000l;
+ out("length in ticks: " + lengthInTicks);
+ try {
+ sequence = new Sequence(Sequence.PPQ, resolution, 1);
+ Track track = sequence.createTrack();
+ ShortMessage mm = new ShortMessage();
+ mm.setMessage(0xF6, 0, 0);
+ MidiEvent me = new MidiEvent(mm, lengthInTicks);
+ track.add(me);
+ } catch (InvalidMidiDataException e) {
+ // DO NOTHING
+ }
+ out("sequence length (ticks): " + sequence.getTickLength());
+ out("sequence length (us): " + sequence.getMicrosecondLength());
+ return sequence;
+ }
+
+
+ private static void out(String m1, boolean isSequenceLoaded, String m2) {
+ out(m1 + (isSequenceLoaded ? " with Sequence " : " without Sequence ") + m2);
+ }
+
+ private static void out(String message) {
+ System.out.println(message);
+ }
+
+ private static class TestMetaEventListener implements MetaEventListener {
+ private long stopTime;
+
+
+ public void meta(MetaMessage m) {
+ System.out.print(" Got MetaMessage: ");
+ if (m.getType() == 47) {
+ stopTime = System.currentTimeMillis();
+ System.out.println(" End Of Track -- OK");
+ } else {
+ System.out.println(" unknown. Ignored.");
+ }
+ }
+
+ public long getStopTime() {
+ return stopTime;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequencer/MetaCallback.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,133 @@
+/*
+ * 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.Instrument;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaEventListener;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4347135
+ * @summary MIDI MetaMessage callback inconsistent
+ * @run main/othervm MetaCallback
+ */
+public class MetaCallback implements MetaEventListener {
+
+ static ShortMessage MidiMsg3(int a, int b, int c) {
+ try {
+ ShortMessage msg = new ShortMessage();
+ msg.setMessage((byte)a,(byte)b,(byte)c);
+ return msg;
+ } catch(InvalidMidiDataException ex) {
+ throw new RuntimeException();
+ }
+ }
+
+ //Synthesizer synth;
+ Instrument[] instruments;
+ Sequencer sequencer;
+ Sequence sequence;
+ Track track;
+
+ public static int TOTAL_COUNT = 100;
+
+ int metaCount = 0;
+ boolean finished = false;
+
+ MetaCallback() throws Exception {
+
+ sequencer=MidiSystem.getSequencer();
+ sequence=new Sequence(Sequence.PPQ,240);
+ track=sequence.createTrack();
+ sequencer.addMetaEventListener(this);
+
+ byte[] data = new byte[1];
+
+ track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,100),0));
+ track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,0),0 + 240));
+ int c;
+ for(c=0; c < TOTAL_COUNT; c++) {
+ data[0]=(byte)(c+1);
+ MetaMessage meta = new MetaMessage();
+ meta.setMessage(1, data, 1); // type, data, length
+ track.add(new MidiEvent(meta,c*20));
+ }
+ track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,100),c*20));
+ track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,0),c*20 + 10));
+
+ sequencer.setSlaveSyncMode(Sequencer.SyncMode.INTERNAL_CLOCK);
+ sequencer.setMasterSyncMode(Sequencer.SyncMode.INTERNAL_CLOCK);
+ sequencer.open();
+ sequencer.setSequence(sequence);
+ sequencer.setTempoInBPM(100);
+ System.out.println("Starting playback...");
+ this.start();
+ while (!finished && sequencer.getTickPosition() < sequencer.getTickLength()) {
+ System.out.println("Tick "+sequencer.getTickPosition()+"...");
+ Thread.sleep(1000);
+ }
+ System.out.println("Stopping playback...");
+ this.stop();
+ if (metaCount != TOTAL_COUNT) {
+ throw new Exception("Expected "+TOTAL_COUNT+" callbacks, but got "+metaCount+"!");
+ }
+ }
+ void start() {sequencer.start();}
+ void stop() {sequencer.stop();}
+
+ public void meta(MetaMessage msg) {
+ System.out.println(""+metaCount+": got "+msg);
+ if (msg.getType() == 0x2F) {
+ finished = true;
+ } else if (msg.getData().length > 0 && msg.getType() == 1) {
+ metaCount++;
+ }
+ }
+
+ public static void main(String[] argv) throws Exception {
+ if (hasSequencer()) {
+ new MetaCallback();
+ System.out.println("Test passed");
+ }
+ }
+
+ static boolean hasSequencer() {
+ try {
+ Sequencer seq = MidiSystem.getSequencer();
+ if (seq != null) {
+ seq.open();
+ seq.close();
+ return true;
+ }
+ } catch (Exception e) {}
+ System.out.println("No sequencer available! Cannot execute test.");
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequencer/Recording.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,213 @@
+/*
+ * 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.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4932841
+ * @key intermittent
+ * @summary Sequencer's recording feature does not work
+ */
+public class Recording {
+
+ public static boolean failed = false;
+ public static boolean passed = false;
+ private static Sequencer seq = null;
+
+ public static void main(String[] args) throws Exception {
+ try {
+ seq = MidiSystem.getSequencer();
+
+ // create an arbitrary sequence which lasts 10 seconds
+ Sequence sequence = createSequence(10, 120, 240);
+
+ seq.setSequence(sequence);
+ out("Set Sequence to Sequencer. Tempo="+seq.getTempoInBPM());
+
+ Track track = sequence.createTrack();
+ int oldSize = track.size();
+ seq.recordEnable(track, -1);
+
+ seq.open();
+
+ // if getReceiver throws Exception, failed!
+ failed = true;
+ Receiver rec = seq.getReceiver();
+
+ // start recording and add various events
+ seq.startRecording();
+
+ // is exception from here on, not failed
+ failed = false;
+
+ if (!seq.isRecording()) {
+ failed = true;
+ throw new Exception("Sequencer did not start recording!");
+ }
+ if (!seq.isRunning()) {
+ failed = true;
+ throw new Exception("Sequencer started recording, but is not running!");
+ }
+
+ // first: add an event to the middle of the sequence
+ ShortMessage msg = new ShortMessage();
+ msg.setMessage(0xC0, 80, 00);
+ rec.send(msg, 5l * 1000l * 1000l);
+
+ Thread.sleep(1000);
+
+ // then add a real-time event
+ msg = new ShortMessage();
+ msg.setMessage(0xC0, 81, 00);
+ long secondEventTick = seq.getTickPosition();
+ rec.send(msg, -1);
+
+ seq.stopRecording();
+ if (seq.isRecording()) {
+ failed = true;
+ throw new Exception("Stopped recording, but Sequencer is still recording!");
+ }
+ if (!seq.isRunning()) {
+ failed = true;
+ throw new Exception("Stopped recording, but Sequencer but is not running anymore!");
+ }
+
+ seq.stop();
+ if (seq.isRunning()) {
+ failed = true;
+ throw new Exception("Stopped Sequencer, but it is still running!");
+ }
+
+ // now examine the contents of the recorded track:
+ // 1) number of events: should be 2 more
+ int newSize = track.size();
+ int addedEventCount = newSize - oldSize;
+
+ out("Added "+addedEventCount+" events to recording track.");
+ if (addedEventCount != 2) {
+ failed = true;
+ throw new Exception("Did not add 2 events!");
+ }
+
+ // 2) the first event should be at roughly "secondEventTick"
+ MidiEvent ev = track.get(0);
+ msg = (ShortMessage) ev.getMessage();
+ out("The first recorded event is at tick position: "+ev.getTick());
+ if (Math.abs(ev.getTick() - secondEventTick) > 1000) {
+ out(" -> but expected something like: "+secondEventTick+"! FAILED.");
+ failed = true;
+ }
+
+ ev = track.get(1);
+ msg = (ShortMessage) ev.getMessage();
+ out("The 2nd recorded event is at tick position: "+ev.getTick());
+ out(" -> sequence's tick length is "+seq.getTickLength());
+ if (Math.abs(ev.getTick() - (sequence.getTickLength() / 2)) > 1000) {
+ out(" -> but expected something like: "+(seq.getTickLength()/2)+"! FAILED.");
+ failed = true;
+ }
+
+ passed = true;
+ } catch (Exception e) {
+ out(e.toString());
+ if (!failed) out("Test not failed.");
+ }
+ if (seq != null) {
+ seq.close();
+ }
+
+ if (failed) {
+ throw new Exception("Test FAILED!");
+ }
+ else if (passed) {
+ out("Test Passed.");
+ }
+ }
+
+ /**
+ * Create a new Sequence for testing.
+ */
+ private static Sequence createSequence(int lengthInSeconds, int tempoInBPM,
+ int resolution) {
+ Sequence sequence = null;
+ long lengthInMicroseconds = lengthInSeconds * 1000000;
+ boolean createTempoEvent = true;
+ if (tempoInBPM == 0) {
+ tempoInBPM = 120;
+ createTempoEvent = false;
+ System.out.print("Creating sequence: "+lengthInSeconds+"sec, "
+ +"resolution="+resolution+" ticks/beat...");
+ } else {
+ System.out.print("Creating sequence: "+lengthInSeconds+"sec, "
+ +tempoInBPM+" beats/min, "
+ +"resolution="+resolution+" ticks/beat...");
+ }
+ //long lengthInTicks = (lengthInMicroseconds * resolution) / tempoInBPM;
+ long lengthInTicks = (lengthInMicroseconds * tempoInBPM * resolution) / 60000000l;
+ //out("expected length in ticks: " + lengthInTicks);
+ try {
+ sequence = new Sequence(Sequence.PPQ, resolution);
+ Track track = sequence.createTrack();
+ if (createTempoEvent) {
+ int tempoInMPQ = (int) (60000000l / tempoInBPM);
+ MetaMessage tm = new MetaMessage();
+ byte[] msg = new byte[3];
+ msg[0] = (byte) (tempoInMPQ >> 16);
+ msg[1] = (byte) ((tempoInMPQ >> 8) & 0xFF);
+ msg[2] = (byte) (tempoInMPQ & 0xFF);
+
+ tm.setMessage(0x51 /* Meta Tempo */, msg, msg.length);
+ track.add(new MidiEvent(tm, 0));
+ //out("regtest: tempoInMPQ="+tempoInMPQ);
+ //out("Added tempo event: new size="+track.size());
+ }
+ ShortMessage mm = new ShortMessage();
+ mm.setMessage(0xF6, 0, 0);
+ MidiEvent me = new MidiEvent(mm, lengthInTicks);
+ track.add(me);
+ //out("Added realtime event: new size="+track.size());
+ } catch (InvalidMidiDataException e) {
+ out(e);
+ }
+ out("OK");
+
+ return sequence;
+ }
+
+ 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/Sequencer/SeqRecordDoesNotCopy.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,117 @@
+/*
+ * 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 javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 5048381
+ * @summary Sequencer doesn't create distinct messages when recording events.
+ * @key headful
+ */
+public class SeqRecordDoesNotCopy {
+ public static void main(String argv[]) throws Exception {
+ Sequencer s = MidiSystem.getSequencer();
+ s.open();
+ try {
+ Sequence seq = new Sequence(Sequence.PPQ, 384, 2);
+ s.setSequence(seq);
+ Track t = seq.getTracks()[0];
+ ShortMessage msg = new ShortMessage();
+ msg.setMessage(0x90, 0x40, 0x7F);
+ t.add(new MidiEvent(msg, 11000));
+ msg.setMessage(0x90, 0x40, 0x00);
+ t.add(new MidiEvent(msg, 12000));
+ t = seq.getTracks()[1];
+ s.recordEnable(t, -1);
+ System.out.println("Started recording...");
+ s.startRecording();
+ Receiver r = s.getReceiver();
+ Thread.sleep(100);
+ // send a normal message
+ System.out.println("Recording a normal NOTE ON message...");
+ msg.setMessage(0x90, 0x40, 0x6F);
+ r.send(msg, -1);
+ Thread.sleep(100);
+ // send a normal message
+ System.out.println("Recording a normal NOTE OFF message...");
+ msg.setMessage(0x90, 0x40, 0x00);
+ r.send(msg, -1);
+ Thread.sleep(100);
+ s.stop();
+ // now see if the messages were recorded
+ System.out.println("Recorded messages:");
+ int sameMessage = 0;
+ for (int i = 0; i < t.size(); i++) {
+ System.out.print(" "+(i+1)+". ");
+ printEvent(t.get(i));
+ if (t.get(i).getMessage() == msg) {
+ System.out.println("## Failed: Same Message reference!");
+ sameMessage++;
+ }
+ }
+ if (sameMessage > 0) {
+ System.out.println("## Failed: The same instance was recorded!");
+ throw new Exception("Test FAILED!");
+ }
+ System.out.println("Did not detect any duplicate messages.");
+ System.out.println("Test passed.");
+ } catch (Exception e) {
+ System.out.println("Unexpected Exception: "+e);
+ //e.printStackTrace();
+ throw new Exception("Test FAILED!");
+ } finally {
+ s.close();
+ }
+ }
+ public static void printEvent(MidiEvent event)
+ {
+ MidiMessage message = event.getMessage();
+ long tick = event.getTick();
+ byte[] data = message.getMessage();
+
+ StringBuffer sb = new StringBuffer((data.length * 3) - 1);
+
+ for (int i = 0; i < data.length; i++)
+ {
+ sb.append(toHexByteString(data[i]));
+ if (i < data.length - 1) sb.append(' ');
+ }
+ System.out.printf("%5d: %s%n", tick, sb);
+ }
+
+ private static String toHexByteString(int n)
+ {
+ if (n < 0) n &= 0xFF;
+ String s = Integer.toHexString(n).toUpperCase();
+ if (s.length() == 1) s = '0' + s;
+ return s;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequencer/SeqRecordsRealTimeEvents.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,121 @@
+/*
+ * 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 javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 5048381
+ * @summary Sequencer records real time messages into the sequence
+ * @key headful
+ */
+public class SeqRecordsRealTimeEvents {
+ public static void main(String argv[]) throws Exception {
+ Sequencer s = MidiSystem.getSequencer();
+ s.open();
+ try {
+ Sequence seq = new Sequence(Sequence.PPQ, 384, 2);
+ s.setSequence(seq);
+ Track t = seq.getTracks()[0];
+ ShortMessage msg = new ShortMessage();
+ msg.setMessage(0x90, 0x40, 0x7F);
+ t.add(new MidiEvent(msg, 11000));
+ msg = new ShortMessage();
+ msg.setMessage(0x90, 0x40, 0x00);
+ t.add(new MidiEvent(msg, 12000));
+ t = seq.getTracks()[1];
+ s.recordEnable(t, -1);
+ System.out.println("Started recording...");
+ s.startRecording();
+ Receiver r = s.getReceiver();
+ Thread.sleep(100);
+ int oldTrackSize = t.size();
+ // send a realtime message to the track
+ System.out.println("Recording real time message...");
+ msg = new ShortMessage();
+ msg.setMessage(0xF8, 0, 0);
+ r.send(msg, -1);
+ Thread.sleep(100);
+ // send a normal message
+ msg = new ShortMessage();
+ System.out.println("Recording a normal NOTE ON message...");
+ msg.setMessage(0x90, 0x40, 0x6F);
+ r.send(msg, -1);
+ Thread.sleep(100);
+ s.stop();
+ // now see if the messages were recorded
+ int newMessages = t.size() - oldTrackSize;
+ System.out.println("Recorded messages:");
+ for (int i = 0; i < t.size(); i++) {
+ System.out.print(" "+(i+1)+". ");
+ printEvent(t.get(i));
+ }
+ if (newMessages == 0) {
+ System.out.println("## Failed: No messages were recorded!");
+ throw new Exception("Test FAILED!");
+ } else if (newMessages == 1) {
+ System.out.println("Only one message was recorded. Correct!");
+ } else if (newMessages > 1) {
+ System.out.println("## Failed: 2 or more messages were recorded!");
+ throw new Exception("Test FAILED!");
+ }
+ System.out.println("Test passed.");
+ } catch (Exception e) {
+ System.out.println("Unexpected Exception: "+e);
+ //e.printStackTrace();
+ throw new Exception("Test FAILED!");
+ } finally {
+ s.close();
+ }
+ }
+ public static void printEvent(MidiEvent event)
+ {
+ MidiMessage message = event.getMessage();
+ long tick = event.getTick();
+ byte[] data = message.getMessage();
+
+ StringBuffer sb = new StringBuffer((data.length * 3) - 1);
+
+ for (int i = 0; i < data.length; i++)
+ {
+ sb.append(toHexByteString(data[i]));
+ if (i < data.length - 1) sb.append(' ');
+ }
+ System.out.printf("%5d: %s%n", tick, sb);
+ }
+
+ private static String toHexByteString(int n)
+ {
+ if (n < 0) n &= 0xFF;
+ String s = Integer.toHexString(n).toUpperCase();
+ if (s.length() == 1) s = '0' + s;
+ return s;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequencer/SeqStartRecording.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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 javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequencer;
+
+/**
+ * @test
+ * @bug 5001943
+ * @summary Sequencer.startRecording throws unexpected NPE
+ * @key headful
+ */
+public class SeqStartRecording {
+ public static void main(String argv[]) throws Exception {
+ Sequencer seq = MidiSystem.getSequencer();
+ seq.open();
+ try {
+ seq.startRecording();
+ System.out.println("Test passed.");
+ } catch (NullPointerException npe) {
+ System.out.println("Caught NPE: "+npe);
+ npe.printStackTrace();
+ throw new Exception("Test FAILED!");
+ } catch (Exception e) {
+ System.out.println("Unexpected Exception: "+e);
+ e.printStackTrace();
+ System.out.println("Test NOT failed.");
+ } finally {
+ seq.close();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequencer/SequencerCacheValues.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,106 @@
+/*
+ * 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;
+import javax.sound.midi.Sequencer;
+
+/**
+ * @test
+ * @bug 4716740
+ * @summary default sequencer does not set the tempo factor
+ */
+public class SequencerCacheValues {
+
+ static boolean failed = false;
+
+ public static void main(String args[]) throws Exception {
+ Sequencer seq = null;
+ int totalNumberOfSequencers = 0;
+
+ MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+ for (int device=0; device<infos.length; device++) {
+ //seq = MidiSystem.getSequencer();
+ MidiDevice dev = MidiSystem.getMidiDevice(infos[device]);
+ if (dev instanceof Sequencer) {
+ seq = (Sequencer) dev;
+ totalNumberOfSequencers++;
+ System.out.println("Opening sequencer "+infos[device]);
+ try {
+ seq.open();
+ try {
+ doTest(seq);
+ } finally {
+ if (seq != null) {
+ seq.close();
+ seq = null;
+ }
+ }
+ } catch (MidiUnavailableException mue) {
+ System.err.println("MidiUnavailableException was thrown: " + mue);
+ System.err.println("could not test this sequencer.");
+ }
+ }
+ }
+ if (totalNumberOfSequencers == 0) {
+ System.out.println("No sequencers installed!");
+ failed = true;
+ }
+ if (failed) {
+ throw new Exception("FAILED");
+ } else {
+ System.out.println("test OK");
+ }
+ }
+
+ public static boolean equalsFloat(float f1, float f2) {
+ return (f1-f2<0.0001) && (f2-f1<0.0001);
+ }
+
+ public static void doTest(Sequencer seq) throws Exception {
+ seq.setTempoInMPQ(3.0f);
+ System.out.println("Setting tempo in MPQ to "+3.0f);
+ if (!equalsFloat(seq.getTempoInMPQ(), 3.0f)) {
+ System.err.println("getTempoInMPQ() returns wrong value : "
+ + seq.getTempoInMPQ());
+ failed = true;
+ }
+
+ System.out.println("Setting tempo factor to "+2.0f);
+ seq.setTempoFactor(2.0f);
+ if (!equalsFloat(seq.getTempoFactor(), 2.0f)) {
+ System.err.println("getTempoFactor() returns: " + seq.getTempoFactor());
+ failed = true;
+ }
+
+ float bpmTempo = 120.0f;
+ System.out.println("Setting tempo to "+120.0f+"bpm");
+ seq.setTempoInBPM(bpmTempo);
+ if (!equalsFloat(seq.getTempoInMPQ(), (60000000.0f/seq.getTempoInBPM()))) {
+ System.err.println("getTempoInMPQ() returns: " + seq.getTempoInMPQ());
+ System.err.println("getTempoInBPM() returns: " + seq.getTempoInBPM());
+ failed = true;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequencer/SequencerSetMuteSolo.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,170 @@
+/*
+ * 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.File;
+import java.io.FileInputStream;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+
+/**
+ * @test
+ * @bug 4713900
+ * @summary default Sequencer allows to set Mute for invalid track
+ */
+public class SequencerSetMuteSolo {
+
+ public static void main(String args[]) throws Exception {
+ if (!hasSequencer()) {
+ return;
+ }
+
+ //printMidiFile(args[0]);
+
+ boolean failed = false;
+ Sequencer seq = null;
+ Sequence midiData = getSequence();
+ int numTracks = midiData.getTracks().length;
+ int totalNumberOfSequencers = 0;
+ int totalNumberOfTestedSequencers = 0;
+
+ MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+ for (int device=0; device<infos.length; device++) {
+ //seq = MidiSystem.getSequencer();
+ MidiDevice dev = MidiSystem.getMidiDevice(infos[device]);
+ if (dev instanceof Sequencer) {
+ seq = (Sequencer) dev;
+ totalNumberOfSequencers++;
+ System.out.println("Opening sequencer "+infos[device]);
+ try {
+ seq.open();
+ try {
+ seq.setSequence(midiData);
+ System.err.println("Number of tracks: " + numTracks);
+ System.err.println("TrackMute["+numTracks+"] state was: " + seq.getTrackMute(numTracks));
+ System.err.println(" setting to muted.");
+ seq.setTrackMute(numTracks, true);
+ System.err.println(" TrackMute["+numTracks+"] is now: " + seq.getTrackMute(numTracks));
+ if (seq.getTrackMute(numTracks)) {
+ failed = true;
+ }
+ System.err.println("TrackSolo["+numTracks+"] state was: " + seq.getTrackSolo(numTracks));
+ System.err.println(" setting to solo.");
+ seq.setTrackSolo(numTracks, true);
+ System.err.println(" TrackSolo["+numTracks+"] is now: " + seq.getTrackSolo(numTracks));
+ if (seq.getTrackSolo(numTracks)) {
+ failed = true;
+ }
+ totalNumberOfTestedSequencers++;
+ } finally {
+ if (seq != null) {
+ seq.close();
+ seq = null;
+ }
+ }
+ } catch (MidiUnavailableException mue) {
+ System.err.println("MidiUnavailableException was thrown: " + mue);
+ System.err.println("could not test this sequencer.");
+ return;
+ }
+ }
+ }
+ if (totalNumberOfSequencers == 0) {
+ System.out.println("No sequencers installed!");
+ failed = true;
+ }
+ if (totalNumberOfTestedSequencers == 0) {
+ System.out.println("Could not test any sequencers!");
+ failed = true;
+ }
+ if( failed ) {
+ throw new Exception("FAILED");
+ } else {
+ System.out.println("test OK");
+ }
+ }
+
+ public static String getString(byte b) {
+ //String res = Integer.toHexString(b & 0xFF).toUpperCase();
+ //while (res.length()<2) res="0"+res;
+ //return res;
+ return String.valueOf(b);
+ }
+
+
+ public static void printMidiFile(String filename) throws Exception {
+ File file = new File(filename);
+ FileInputStream fis = new FileInputStream(file);
+ byte[] data = new byte[(int) file.length()];
+ fis.read(data);
+ String s = "";
+ for (int i=0; i<data.length; i++) {
+ s+=getString(data[i])+", ";
+ if (s.length()>72) {
+ System.out.println(s);
+ s="";
+ }
+ }
+ System.out.println(s);
+ }
+
+ public static Sequence getSequence() throws Exception {
+ ByteArrayInputStream bais = new ByteArrayInputStream(pitchbend);
+ Sequence seq = MidiSystem.getSequence(bais);
+ return seq;
+ }
+
+ public static byte[] pitchbend = {
+ 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
+ };
+
+ static boolean hasSequencer() {
+ try {
+ Sequencer seq = MidiSystem.getSequencer();
+ if (seq != null) {
+ seq.open();
+ seq.close();
+ return true;
+ }
+ } catch (Exception e) {}
+ System.out.println("No sequencer available! Cannot execute test.");
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequencer/SequencerState.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,272 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+
+/**
+ * @test
+ * @bug 4913027
+ * @summary several Sequencer methods should specify behaviour on closed Sequencer
+ */
+public class SequencerState {
+
+ private static boolean hasSequencer() {
+ try {
+ Sequencer seq = MidiSystem.getSequencer();
+ if (seq != null) {
+ seq.open();
+ seq.close();
+ return true;
+ }
+ } catch (Exception e) {}
+ System.out.println("No sequencer available! Cannot execute test.");
+ return false;
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ out("4913027: several Sequencer methods should should specify behaviour on closed Sequencer");
+ if (hasSequencer()) {
+ boolean passed = testAll();
+ if (passed) {
+ out("Test PASSED.");
+ } else {
+ throw new Exception("Test FAILED.");
+ }
+ }
+ }
+
+ /**
+ * Execute the test on all available Sequencers.
+ *
+ * @return true if the test passed for all Sequencers, false otherwise
+ */
+ private static boolean testAll() throws Exception {
+ boolean result = true;
+ MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
+ for (int i = 0; i < devices.length; i++) {
+ MidiDevice device = MidiSystem.getMidiDevice(devices[i]);
+ if (device instanceof Sequencer) {
+ result &= testSequencer((Sequencer) device);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Execute the test on the passed Sequencer.
+ *
+ * @return true if the test is passed this Sequencer, false otherwise
+ */
+ private static boolean testSequencer(Sequencer seq) throws Exception {
+ boolean result = true;
+
+ out("testing: " + seq);
+ /* test calls in closed state.
+ */
+ if (seq.isOpen()) {
+ out("Sequencer is already open, cannot test!");
+ return result;
+ }
+
+ try {
+ seq.start();
+ out("closed state: start() does not throw IllegalStateException!");
+ result = false;
+ } catch (IllegalStateException e) {
+ }
+
+ try {
+ seq.stop();
+ out("closed state: stop() does not throw IllegalStateException!");
+ result = false;
+ } catch (IllegalStateException e) {
+ }
+
+ try {
+ seq.startRecording();
+ out("closed state: startRecording() does not throw IllegalStateException!");
+ result = false;
+ } catch (IllegalStateException e) {
+ }
+
+ try {
+ seq.stopRecording();
+ out("closed state: stopRecording() does not throw IllegalStateException!");
+ result = false;
+ } catch (IllegalStateException e) {
+ }
+
+ Sequence sequence = createSequence();
+ if (sequence == null) {
+ out("created Sequence is null, cannot test!");
+ return result;
+ }
+ try {
+ seq.setSequence(sequence);
+ } catch (IllegalStateException e) {
+ out("closed state: setSequence(Sequence) throws IllegalStateException!");
+ result = false;
+ }
+
+ InputStream inputStream = createSequenceInputStream();
+ if (inputStream == null) {
+ out("created InputStream is null, cannot test!");
+ return result;
+ }
+ try {
+ seq.setSequence(inputStream);
+ } catch (IllegalStateException e) {
+ out("closed state: setSequence(InputStream) throws IllegalStateException!");
+ result = false;
+ }
+
+ try {
+ seq.getSequence();
+ } catch (IllegalStateException e) {
+ out("closed state: getSequence() throws IllegalStateException!");
+ result = false;
+ }
+
+ /* test calls in open state.
+ */
+ seq.open();
+ if (! seq.isOpen()) {
+ out("Sequencer is not open, cannot test!");
+ return result;
+ }
+
+ try {
+ seq.start();
+ } catch (IllegalStateException e) {
+ out("open state: start() throws IllegalStateException!");
+ result = false;
+ }
+
+ try {
+ seq.stop();
+ } catch (IllegalStateException e) {
+ out("open state: stop() throws IllegalStateException!");
+ result = false;
+ }
+
+ try {
+ seq.startRecording();
+ } catch (IllegalStateException e) {
+ out("open state: startRecording() throws IllegalStateException!");
+ result = false;
+ }
+
+ try {
+ seq.stopRecording();
+ } catch (IllegalStateException e) {
+ out("open state: stopRecording() throws IllegalStateException!");
+ result = false;
+ }
+
+ sequence = createSequence();
+ if (sequence == null) {
+ out("created Sequence is null, cannot test!");
+ return result;
+ }
+ try {
+ seq.setSequence(sequence);
+ } catch (IllegalStateException e) {
+ out("open state: setSequence(Sequence) throws IllegalStateException!");
+ result = false;
+ }
+
+ inputStream = createSequenceInputStream();
+ if (inputStream == null) {
+ out("created InputStream is null, cannot test!");
+ return result;
+ }
+ try {
+ seq.setSequence(inputStream);
+ } catch (IllegalStateException e) {
+ out("open state: setSequence(InputStream) throws IllegalStateException!");
+ result = false;
+ }
+
+ try {
+ seq.getSequence();
+ } catch (IllegalStateException e) {
+ out("open state: getSequence() throws IllegalStateException!");
+ result = false;
+ }
+
+ seq.close();
+ return result;
+ }
+
+ /**
+ * Create a new Sequence for testing.
+ *
+ * @return a dummy Sequence, or null, if a problem occured while creating
+ * the Sequence
+ */
+ private static Sequence createSequence() {
+ Sequence sequence = null;
+ try {
+ sequence = new Sequence(Sequence.PPQ, 480, 1);
+ } catch (InvalidMidiDataException e) {
+ // DO NOTHING
+ }
+ return sequence;
+ }
+
+ /**
+ * Create a new InputStream containing a Sequence for testing.
+ *
+ * @return an InputStream containing a dummy Sequence, or null, if a problem
+ * occured while creating the InputStream
+ */
+ private static InputStream createSequenceInputStream() {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Sequence sequence = createSequence();
+ if (sequence == null) {
+ return null;
+ }
+ try {
+ MidiSystem.write(sequence, 0, baos);
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ return bais;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+
+ 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/Sequencer/SetTickPosition.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,139 @@
+/*
+ * 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.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4493775
+ * @summary Sequncer method, setTickPosition(long) doesnot set the Tick position
+ */
+public class SetTickPosition {
+ private static boolean testPassed = true;
+
+ public void runTest()
+ {
+ Sequencer theSequencer = null;
+ try
+ {
+ System.out.print("Getting Sequencer...");
+ theSequencer = MidiSystem.getSequencer();
+ System.out.println("got "+theSequencer);
+
+ if(!(theSequencer.isOpen()))
+ {
+ System.out.println("Opening Sequencer...");
+ theSequencer.open();
+
+ if(!(theSequencer.isOpen()))
+ {
+ System.out.println("Unable to open the Sequencer. Test NOT FAILED.");
+ return;
+ }
+ }
+
+ System.out.println("theSequencer is open!\n");
+
+ System.out.println("Creating New Sequence...");
+ Sequence theSequence = new Sequence(Sequence.PPQ, 120);
+
+ System.out.println("Adding Track To Sequence...");
+ Track theTrack = theSequence.createTrack();
+
+ int theChannel = 0;
+
+ int theNote = 60;
+ int theVelocity = 100;
+ ShortMessage theShortMessage = new ShortMessage();
+
+ for (int tick=0; tick<2000; tick+=120) {
+ //System.out.println("Adding NOTE_ON To Track At Tick: " + tick + "...\n");
+ theShortMessage.setMessage(ShortMessage.NOTE_ON, theChannel, theNote, theVelocity);
+ MidiEvent theMidiEvent = new MidiEvent(theShortMessage, tick);
+ theTrack.add(theMidiEvent);
+
+ //System.out.println("Adding NOTE_OFF To Track At Tick: " + (tick+60) + "...\n");
+ theShortMessage.setMessage(ShortMessage.NOTE_OFF, theChannel, theNote, theVelocity);
+ theMidiEvent = new MidiEvent(theShortMessage, tick+60);
+ theTrack.add(theMidiEvent);
+ }
+ theSequencer.setSequence(theSequence);
+
+ float theTempoInBPM = 120;
+ theSequencer.setTempoInBPM(theTempoInBPM);
+ long theTickLengthOfSequence = theSequencer.getTickLength();
+ System.out.println("Length Of Sequence In Ticks: " + theTickLengthOfSequence);
+ System.out.println("Sequence resolution: " + theSequencer.getSequence().getResolution());
+
+ theSequencer.start();
+ for(long theTickPosition = 0; theTickPosition < theTickLengthOfSequence; theTickPosition += (theTickLengthOfSequence / 10))
+ {
+ System.out.println("Now Setting Tick Position To: " + theTickPosition);
+ theSequencer.setTickPosition(theTickPosition);
+
+ long theCurrentTickPosition = theSequencer.getTickPosition();
+ long theCurrentMsPosition = (long) (theSequencer.getMicrosecondPosition()/1000);
+ System.out.println("IsRunning()=" + theSequencer.isRunning());
+ System.out.println("Now Current Tick Position Is: " + theCurrentTickPosition);
+ //System.out.println("Now Current micro Position Is: " + theCurrentMsPosition);
+ System.out.println("");
+
+ try {
+ Thread.sleep(800);
+ } catch (InterruptedException ie) {}
+
+ // last time, set tick pos to 0
+ if (theTickPosition>0 && theTickPosition<(theTickLengthOfSequence / 10)) {
+ theTickPosition=(theTickLengthOfSequence / 10);
+ }
+
+ // 30 = 1/4 * 120, the resolution of the sequence
+ if(Math.abs(theCurrentTickPosition - theTickPosition) > 30) {
+ System.out.println("theCurrentTickPosition != theTickPosition!");
+ testPassed = false;
+ }
+ }
+
+ }
+ catch (Exception ex) { ex.printStackTrace(); }
+ if (theSequencer != null) {
+ theSequencer.close();
+ }
+ if (testPassed) {
+ System.out.println("Test Passed.");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ SetTickPosition thisTest = new SetTickPosition();
+ thisTest.runTest();
+ if (!testPassed) {
+ throw new Exception("Test FAILED");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Sequencer/TickLength.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,211 @@
+/*
+ * 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.InvalidMidiDataException;
+import javax.sound.midi.MetaEventListener;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4427890
+ * @run main/othervm TickLength
+ * @summary Sequencer.getTickLength() and Sequence.getTickLength() report the
+ * wrong length
+ */
+public class TickLength implements MetaEventListener {
+ private Sequence theSequence;
+ private Sequencer theSequencer;
+
+ public TickLength() {
+ this.initMidiCompoments();
+ System.out.println("Got Sequencer "+theSequencer);
+ theSequence = this.generateSequence();
+ try {
+ theSequencer.setSequence(theSequence);
+ }
+ catch(Exception e) {
+ System.out.println(this.getClass()+"\tCannot set sequence to sequencer ("+e+")");
+ return;
+ }
+ }
+
+ public void start() {
+ theSequencer.start();
+ }
+
+ /*
+ instantiate the necessary midi components
+ */
+ private boolean initMidiCompoments() {
+
+
+ try {
+ theSequencer = MidiSystem.getSequencer();
+ }
+ catch(Exception e) {
+ System.out.println(this.getClass()+"\tSequencer Device not supported"+e+")");
+ return false;
+ }
+
+ try {
+ theSequencer.open();
+ }
+ catch(Exception e) {
+ System.out.println(this.getClass()+"Cannot open Sequencer Device");
+ return false;
+ }
+ if(!theSequencer.addMetaEventListener(this)) {
+ System.out.println(this.getClass()+"\tCould not register MetaEventListener - there will be problems with scrolling! ");
+ return false;
+ }
+ return true;
+ }
+
+ static int lastTick = 0;
+
+ private Sequence generateSequence() {
+ MidiEvent dummyMidiEvent;
+ ShortMessage dummyShortMessage;
+ Sequence dummySequence = null;
+ Track[] allTracks ;
+ Track theTrack;
+
+ try {
+ dummySequence = new Sequence(Sequence.PPQ,1500);
+ }
+ catch(InvalidMidiDataException e) {
+ System.out.println("O o "+e);
+ }
+
+ dummySequence.createTrack();
+ allTracks = dummySequence.getTracks();
+ theTrack = allTracks[0];
+ lastTick = 0;
+ for(int i=0;i<20; i++) {
+ theTrack.add(this.createShortMidiEvent(ShortMessage.NOTE_ON, 2, 30+i, 100,100+1000*i));
+ theTrack.add(this.createMetaMidiEvent(1,"start",100+1000*i));
+ lastTick = (1000*i)+600;
+ theTrack.add(this.createShortMidiEvent(ShortMessage.NOTE_OFF, 2, 30+i, 100, lastTick));
+ theTrack.add(this.createMetaMidiEvent(1,"end",lastTick));
+ }
+
+ return dummySequence;
+ }
+
+ /*
+ A method to create a short midi event (sound)
+ */
+
+ public MidiEvent createShortMidiEvent(int theCommand, int theChannel, int theData1, int theData2, long theTime) {
+ ShortMessage dummyShortMessage;
+ MidiEvent dummyMidiEvent;
+
+ try {
+ dummyShortMessage = new ShortMessage();
+ dummyShortMessage.setMessage(theCommand, theChannel, theData1, theData2);
+ dummyMidiEvent = new MidiEvent(dummyShortMessage,theTime);
+ }
+ catch (Exception e) {
+ System.out.println(this.getClass()+"\t"+e);
+ return null;
+ }
+
+ return dummyMidiEvent;
+ }
+
+ /*
+ A method to create a meta midi event (used in meta() method)
+ */
+ public MidiEvent createMetaMidiEvent(int theType, String theData1, long theTime) {
+ MetaMessage dummyMetaMessage;
+ MidiEvent dummyMidiEvent;
+
+ try {
+ dummyMetaMessage = new MetaMessage();
+ dummyMetaMessage.setMessage(theType, theData1.getBytes(), theData1.length());
+ dummyMidiEvent = new MidiEvent(dummyMetaMessage,theTime);
+ }
+ catch (Exception e) {
+ System.out.println(e);
+ return null;
+ }
+
+ return dummyMidiEvent;
+ }
+
+ /*
+ the method is activated by each meta midi event
+ it puts out the actual tick position, as well as the WRONG total tick length and the RIGHT
+ tick length using the work around by dividing the total length by 64
+ */
+ public void meta(MetaMessage p1) {
+ if(p1.getType() ==47) {
+ return;
+ }
+ System.out.println("getTickPosition:\t"+theSequencer.getTickPosition()
+ +"\t Sequencer.getTickLength:\t"+theSequencer.getTickLength()
+ +"\tReal Length:\t"+lastTick
+ +"\t Sequence.getTickLength:\t"+theSequence.getTickLength()
+ //(theSequencer.getTickLength()/64));
+ );
+ }
+
+ public void checkLengths() throws Exception {
+ System.out.println("Sequencer.getTickLength() = "+theSequencer.getTickLength());
+ System.out.println("Sequence.getTickLength() = "+theSequence.getTickLength());
+ long diff = theSequencer.getTickLength() - theSequence.getTickLength();
+ if (diff > 100 || diff < -100) {
+ throw new Exception("Difference too large! Failed.");
+ }
+ System.out.println("Passed");
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (!hasSequencer()) {
+ return;
+ }
+ TickLength tlt = new TickLength();
+ //tlt.start();
+ tlt.checkLengths();
+ }
+
+ static boolean hasSequencer() {
+ try {
+ Sequencer seq = MidiSystem.getSequencer();
+ if (seq != null) {
+ seq.open();
+ seq.close();
+ return true;
+ }
+ } catch (Exception e) {}
+ System.out.println("No sequencer available! Cannot execute test.");
+ return false;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/ShortMessage/FastShortMessage.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * 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.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 4851018
+ * @summary MidiMessage.getLength and .getData return wrong values.
+ * also: 4890405: Reading MidiMessage byte array fails in 1.4.2
+ */
+public class FastShortMessage {
+ public static void main(String args[]) throws Exception {
+ int[] dataMes = {ShortMessage.NOTE_ON | 9, 0x24, 0x50};
+ int res = 240;
+ Sequence midiData = new Sequence(Sequence.PPQ, res);
+
+ Track track = midiData.createTrack();
+ ShortMessage msg = new ShortMessage();
+ msg.setMessage(dataMes[0], dataMes[1], dataMes[2]);
+ track.add(new MidiEvent(msg, 0));
+
+ // save sequence to outputstream
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ MidiSystem.write(midiData, 0, baos);
+
+ // reload that sequence
+ InputStream is = new ByteArrayInputStream(baos.toByteArray());
+ Sequence seq = MidiSystem.getSequence(is);
+
+ track = seq.getTracks()[0];
+ msg = (ShortMessage) (track.get(0).getMessage());
+ byte[] msgData = msg.getMessage();
+
+ if (msgData.length != dataMes.length
+ || (msgData[0] & 0xFF) != dataMes[0]
+ || (msgData[1] & 0xFF) != dataMes[1]
+ || (msgData[2] & 0xFF) != dataMes[2]) {
+ throw new Exception("test failed. read length="+msgData.length);
+ }
+ System.out.println("Test Passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/ShortMessage/FastShortMessage2.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * 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 5011306
+ * @summary FastShortMessage.setMessage does not use the data2 parameter
+ */
+public class FastShortMessage2 {
+
+ public static void main(String args[]) throws Exception {
+ int[] dataMes = {ShortMessage.NOTE_ON | 9, 0x24, 0x50};
+
+ Sequence midiData = new Sequence(Sequence.PPQ, 240);
+ Track track = midiData.createTrack();
+ ShortMessage msg = new ShortMessage();
+ msg.setMessage(dataMes[0], dataMes[1], dataMes[2]);
+ track.add(new MidiEvent(msg, 0));
+ // save sequence to outputstream
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ MidiSystem.write(midiData, 0, baos);
+ // reload that sequence
+ InputStream is = new ByteArrayInputStream(baos.toByteArray());
+ Sequence seq = MidiSystem.getSequence(is);
+ track = seq.getTracks()[0];
+ msg = (ShortMessage) (track.get(0).getMessage());
+ if (!msg.getClass().toString().contains("FastShortMessage")) {
+ System.out.println("msg is not FastShortMessage, this test is useless then..."+msg.getClass());
+ }
+
+ msg.setMessage(dataMes[0], dataMes[1], dataMes[2]);
+ byte[] msgData = msg.getMessage();
+
+ if (msgData.length != dataMes.length
+ || (msgData[0] & 0xFF) != dataMes[0]
+ || (msgData[1] & 0xFF) != dataMes[1]
+ || (msgData[2] & 0xFF) != dataMes[2]) {
+ System.out.println("status="+(msgData[0] & 0xFF)+" and expected "+dataMes[0]);
+ System.out.println("data1="+(msgData[1] & 0xFF)+" and expected "+dataMes[1]);
+ System.out.println("data2="+(msgData[2] & 0xFF)+" and expected "+dataMes[2]);
+ throw new Exception("Test FAILED!");
+ }
+ System.out.println("Test Passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Soundbanks/ExtraCharInSoundbank.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,123 @@
+/*
+ * 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.Instrument;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.Synthesizer;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4429762
+ * @summary Some instrument names in some soundbanks include bad extra characters
+ */
+public class ExtraCharInSoundbank {
+
+ private static void printName(String loadedName)
+ {
+ System.out.println("Loaded Name: " + loadedName);
+ byte[] theLoadedNameByteArray = loadedName.getBytes();
+
+ System.out.print("Name Bytes: ");
+ for(int i = 0; i < theLoadedNameByteArray.length; i++)
+ System.out.print((Integer.toHexString((int)theLoadedNameByteArray[i]).toUpperCase()) + " ");
+ System.out.println("");
+ System.out.println("");
+ }
+
+ private static boolean containsControlChar(String name) {
+ byte[] bytes = name.getBytes();
+ for (int i = 0; i < bytes.length; i++) {
+ if (bytes[i] < 32) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean checkInstrumentNames(Synthesizer theSynthesizer)
+ {
+ boolean containsControlCharacters = false;
+
+ Instrument[] theLoadedInstruments = theSynthesizer.getLoadedInstruments();
+
+ System.out.println("Checking soundbank...");
+ for(int theInstrumentIndex = 0; theInstrumentIndex < theLoadedInstruments.length; theInstrumentIndex++) {
+ String name = theLoadedInstruments[theInstrumentIndex].getName();
+ if (containsControlChar(name)) {
+ containsControlCharacters = true;
+ System.out.print("Instrument[" + theInstrumentIndex + "] contains unexpected control characters: ");
+ printName(name);
+ }
+ }
+ return !containsControlCharacters;
+ }
+
+ public static void main(String[] args) throws Exception {
+ // the internal synthesizer needs a soundcard to work properly
+ if (!isSoundcardInstalled()) {
+ return;
+ }
+ Synthesizer theSynth = MidiSystem.getSynthesizer();
+ System.out.println("Got synth: "+theSynth);
+ theSynth.open();
+ try {
+ Soundbank theSoundbank = theSynth.getDefaultSoundbank();
+ System.out.println("Got soundbank: "+theSoundbank);
+ theSynth.loadAllInstruments(theSoundbank);
+ try {
+ if (!checkInstrumentNames(theSynth)) {
+ throw new Exception("Test failed");
+ }
+ } finally {
+ theSynth.unloadAllInstruments(theSoundbank);
+ }
+ } finally {
+ theSynth.close();
+ }
+ System.out.println("Test passed.");
+ }
+
+ /**
+ * Returns true if at least one soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: "+e);
+ }
+ 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/Soundbanks/GetSoundBankIOException.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MidiSystem;
+
+/**
+ * @test
+ * @bug 4629810
+ * @summary MidiSystem.getSoundbank() throws unexpected IOException
+ */
+public class GetSoundBankIOException {
+
+ public static void main(String args[]) throws Exception {
+ boolean failed = false;
+ try {
+ String filename = "GetSoundBankIOException.java";
+ System.out.println("Opening "+filename+" as soundbank...");
+ File midiFile = new File(System.getProperty("test.src", "."), filename);
+ MidiSystem.getSoundbank(midiFile);
+ //Soundbank sBank = MidiSystem.getSoundbank(new NonMarkableIS());
+ System.err.println("InvalidMidiDataException was not thrown!");
+ failed = true;
+ } catch (InvalidMidiDataException invMidiEx) {
+ System.err.println("InvalidMidiDataException was thrown. OK.");
+ } catch (IOException ioEx) {
+ System.err.println("Unexpected IOException was caught!");
+ System.err.println(ioEx.getMessage());
+ ioEx.printStackTrace();
+ failed = true;
+ }
+
+ if (failed) throw new Exception("Test FAILED!");
+ System.out.println("Test passed.");
+ }
+
+ private static class NonMarkableIS extends InputStream {
+ int counter = 0;
+
+ public NonMarkableIS() {
+ }
+
+ public int read() throws IOException {
+ if (counter > 1000) return -1;
+ return (++counter) % 256;
+ }
+
+ public synchronized void mark(int readlimit) {
+ System.out.println("Called mark with readlimit= "+readlimit);
+ }
+
+ public synchronized void reset() throws IOException {
+ throw new IOException("mark/reset not supported");
+ }
+
+ public boolean markSupported() {
+ return false;
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Synthesizer/AsynchronousMidiChannel.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,147 @@
+/*
+ * 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.PrintStream;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.Synthesizer;
+
+/**
+ * @test
+ * @bug 4987585
+ * @summary Some MidiChannel methods are asynchronous
+ */
+public class AsynchronousMidiChannel {
+ static PrintStream log = System.err;
+ static PrintStream ref = System.out;
+
+ public static void main(String args[]) {
+ doIt(args);
+ }
+
+ public static void doIt(String args[]) {
+ Synthesizer synth = null;
+ MidiChannel mChanArr[];
+ MidiChannel chan = null;
+ boolean failed = false;
+ int i = 0;
+ int chanNum = 0;
+
+ int val = 1;
+ int contr = 0;
+ Soundbank sBank;
+ Instrument[] insArr;
+ Instrument instr = null;
+ Object ev = new Object();
+
+ try {
+ synth = MidiSystem.getSynthesizer();
+ System.out.println("Got synth: "+synth);
+ synth.open();
+
+ int latency = (int) synth.getLatency();
+ System.out.println(" -> latency: "
+ +latency
+ +" microseconds");
+
+ mChanArr = synth.getChannels();
+ while ((i < mChanArr.length) && (chan == null)) {
+ chanNum = i;
+ chan = mChanArr[i++];
+ }
+ if (chan == null) {
+ System.out.println("No channels in "
+ +"this synthesizer!");
+ return;
+ }
+ System.out.println("Got MidiChannel: "+chan);
+
+
+ sBank = synth.getDefaultSoundbank();
+ if (sBank == null) {
+ System.out.println("No default sound bank!");
+ return;
+ }
+
+
+ insArr = sBank.getInstruments();
+ for (int j = 0; j < insArr.length; j++) {
+ if (insArr[j].getPatch().getBank() == val) {
+ instr = insArr[j];
+ synth.loadInstrument(instr);
+ }
+ }
+ if (instr == null) {
+ System.out.println("No instr. with this bank!");
+ return;
+ }
+
+ chan.controlChange(contr, val);
+
+ // need to respect the synthesizer's latency
+ if (latency > 0) {
+ try {
+ Thread.sleep(latency/1000);
+ } catch (InterruptedException inEx) {
+ }
+ }
+
+ if (chan.getController(contr) != val) {
+ failed = true;
+ System.err.println("getController() does not "
+ +"return proper value: "
+ + chan.getController(contr));
+ } else {
+ System.out.println("getController("
+ + contr + ") returns proper value: "
+ + chan.getController(contr));
+ }
+
+ } catch (MidiUnavailableException mue) {
+ System.err.println("MidiUnavailableException was "
+ +"thrown: " + mue);
+ System.out.println("could not test.");
+ return;
+ } catch(SecurityException se) {
+ se.printStackTrace();
+ System.err.println("Sound access is not denied but "
+ + "SecurityException was thrown!");
+ return;
+
+ } finally {
+ if (synth != null) synth.close();
+ }
+
+
+ if (failed == true) {
+ System.out.println("test failed");
+ } else {
+ System.out.println("OKAY");
+ }
+ return;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Synthesizer/Receiver/bug6186488.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2005, 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.MidiMessage;
+import javax.sound.midi.MidiSystem;
+
+/**
+ * @test
+ * @bug 6186488
+ * @summary Tests that software Java Syntesizer processed
+ * non-ShortMessage-derived messages
+ * @run main/manual=yesno bug6186488
+ */
+public class bug6186488 {
+ public static void main(String[] args) throws Exception {
+ MidiDevice/*Synthesizer*/ synth = null;
+
+ try {
+ synth = MidiSystem.getSynthesizer();
+ //synth = MidiSystem.getMidiDevice(infos[0]);
+
+ System.out.println("Synthesizer: " + synth.getDeviceInfo());
+ synth.open();
+ MidiMessage msg = new GenericMidiMessage(0x90, 0x3C, 0x40);
+ //ShortMessage msg = new ShortMessage();
+ //msg.setMessage(0x90, 0x3C, 0x40);
+
+ synth.getReceiver().send(msg, 0);
+ Thread.sleep(2000);
+
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw ex;
+ } finally {
+ if (synth != null && synth.isOpen())
+ synth.close();
+ }
+ System.out.print("Did you heard a note? (enter 'y' or 'n') ");
+ int result = System.in.read();
+ System.in.skip(1000);
+ if (result == 'y' || result == 'Y')
+ {
+ System.out.println("Test passed sucessfully.");
+ }
+ else
+ {
+ System.out.println("Test FAILED.");
+ throw new RuntimeException("Test failed.");
+ }
+ }
+
+ private static class GenericMidiMessage extends MidiMessage {
+ GenericMidiMessage(int... message) {
+ super(new byte[message.length]);
+ for (int i=0; i<data.length; i++) {
+ data[i] = (byte)(0xFF & message[i]);
+ }
+ }
+
+ GenericMidiMessage(byte... message) {
+ super(message);
+ }
+
+ public Object clone() {
+ return new GenericMidiMessage((byte[])data.clone());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Synthesizer/SynthesizerGetLatency.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,77 @@
+/*
+ * 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 javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Synthesizer;
+
+/**
+ * @test
+ * @bug 5029790
+ * @summary Synthesizer.getLatency returns wrong value
+ */
+public class SynthesizerGetLatency {
+
+ public static void main(String args[]) throws Exception {
+ Synthesizer synth = null;
+ boolean failed = false;
+ boolean notexec = false;
+ try {
+ synth = MidiSystem.getSynthesizer();
+ System.out.println("Got synth: "+synth);
+ synth.open();
+
+ int latency = (int) synth.getLatency();
+ System.out.println(" -> latency: "
+ +latency
+ +" microseconds");
+ if (latency < 5000 && latency > 0) {
+ System.out.println("## This latency is VERY small, probably due to this bug.");
+ System.out.println("## This causes failure of this test.");
+ failed = true;
+ }
+ } catch (MidiUnavailableException mue) {
+ System.err.println("MidiUnavailableException was "
+ +"thrown: " + mue);
+ System.out.println("could not test.");
+ notexec = true;
+ } catch(SecurityException se) {
+ se.printStackTrace();
+ System.err.println("Sound access is not denied but "
+ + "SecurityException was thrown!");
+ notexec = true;
+ } finally {
+ if (synth != null) synth.close();
+ }
+
+
+ if (failed) {
+ throw new Exception("Test FAILED!");
+ }
+ if (notexec) {
+ System.out.println("Test not failed.");
+ } else {
+ System.out.println("Test Passed.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Synthesizer/bug4685396.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,218 @@
+/*
+ * 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 javax.sound.midi.Instrument;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.Synthesizer;
+
+/**
+ * @test
+ * @bug 4685396
+ * @summary Tests that Synthesizer.remapInstrument works
+ * @run main bug4685396
+ * @key headful
+ */
+public class bug4685396 {
+
+ static Synthesizer synth = null;
+
+ public static boolean isInstrumentExist(Instrument inst, Instrument[] insts) {
+ for (int i = 0; i < insts.length; i++) {
+ if (inst.equals(insts[i]))
+ return true;
+ }
+ return false;
+ }
+
+ static boolean test(
+ boolean reloadInstr, // reload all instruments?
+ boolean unloadFrom, // unload "from" instrument?
+ boolean unloadTo // unload "to" instrument?
+ ) throws Exception
+ {
+ log("Starting test: reloadInstr=" + reloadInstr
+ + ", unloadFrom=" + unloadFrom
+ + ", unloadTo=" + unloadTo
+ + "");
+
+ log(" creating synthesizer...");
+ synth = MidiSystem.getSynthesizer();
+ log(" opening synthesizer...");
+ synth.open();
+
+ Soundbank sbank = synth.getDefaultSoundbank();
+ if (sbank == null)
+ throw new RuntimeException("ERROR: Could not get default soundbank");
+
+ if (reloadInstr) {
+ synth.unloadAllInstruments(sbank);
+ synth.loadAllInstruments(sbank);
+ }
+
+ Instrument[] instrs = synth.getLoadedInstruments();
+
+ log(" " + instrs.length + " instruments loaded.");
+
+ if (instrs.length < 2)
+ throw new RuntimeException("ERROR: need at least 2 loaded instruments");
+
+ Instrument from = instrs[0];
+ Instrument to = instrs[instrs.length - 1];
+
+ if (unloadFrom)
+ synth.unloadInstrument(from);
+ if (unloadTo)
+ synth.unloadInstrument(to);
+
+ log(" from instrument (" + (unloadFrom ? "UNLOADED" : "LOADED")
+ + "): " + from.toString());
+ log(" to instrument (" + (unloadTo ? "UNLOADED" : "LOADED")
+ + "): " + to.toString());
+
+ boolean result = false;
+ boolean excepted = false;
+ try {
+ result = synth.remapInstrument(from, to);
+ log(" remapInstrument(from, to) returns " + result);
+ } catch (IllegalArgumentException ex) {
+ excepted = true;
+ log(" EXCEPTION:");
+ ex.printStackTrace(System.out);
+ }
+
+ instrs = synth.getLoadedInstruments();
+ log(" " + instrs.length + " instruments remains loaded.");
+
+ boolean toUnloaded = !isInstrumentExist(to, instrs);
+ boolean fromUnloaded = !isInstrumentExist(from, instrs);
+
+ log(" from instrument is " + (fromUnloaded ? "UNLOADED" : "LOADED"));
+ log(" to instrument is " + (toUnloaded ? "UNLOADED" : "LOADED"));
+
+ boolean bOK = true;
+ if (result) {
+ if (unloadTo) {
+ bOK = false;
+ log("ERROR: unloaded to, but sucessfull remap");
+ }
+ if (!fromUnloaded) {
+ bOK = false;
+ log("ERROR: sucessfull remap, but from hasn't been unloaded");
+ }
+ if (toUnloaded) {
+ bOK = false;
+ log("ERROR: to has been unloaded!");
+ }
+ } else {
+ if (!excepted) {
+ bOK = false;
+ log("ERROR: remap returns false, exception hasn't been thrown");
+ }
+ if (!unloadTo) {
+ bOK = false;
+ log("ERROR: to is loaded, but remap returns false");
+ }
+ if (unloadFrom != fromUnloaded) {
+ bOK = false;
+ log("ERROR: remap returns false, but status of from has been changed");
+ }
+ }
+
+ if (bOK) {
+ log("Test result: OK\n");
+ } else {
+ log("Test result: FAIL\n");
+ }
+
+ return bOK;
+ }
+
+ static void cleanup() {
+ if (synth != null) {
+ synth.close();
+ synth = null;
+ }
+ }
+
+ static boolean runTest(
+ boolean reloadInstr, // reload all instruments?
+ boolean unloadTo, // unload "to" instrument?
+ boolean unloadFrom // unload "from" instrument?
+ )
+ {
+ boolean success = false;
+ try {
+ success = test(reloadInstr, unloadFrom, unloadTo);
+ } catch (Exception ex) {
+ log("Exception: " + ex.toString());
+ }
+ cleanup();
+ return success;
+ }
+
+ public static void main(String args[]) throws Exception {
+ boolean failed = false;
+ if (!runTest(true, false, false))
+ failed = true;
+ if (!runTest(true, false, true))
+ failed = true;
+ if (!runTest(true, true, false))
+ failed = true;
+ if (!runTest(true, true, true))
+ failed = true;
+
+ if (failed) {
+ throw new RuntimeException("Test FAILED.");
+ }
+ log("Test sucessfully passed.");
+ }
+
+
+ // 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) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Track/TrackAddSameTick.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * 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.MidiEvent;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4941944
+ * @summary Track may not have a determined order for inserting events at same
+ * tick time
+ */
+public class TrackAddSameTick {
+
+ static boolean failed = false;
+ static MidiEvent[] evs = new MidiEvent[10];
+
+ public static void main(String argv[]) throws Exception {
+ Sequence seq = new Sequence(Sequence.PPQ, 240);
+ Track t = seq.createTrack();
+
+ log("add 10 events in random order");
+ t.add(createEvent(10, 5));
+ t.add(createEvent(0, 0));
+ t.add(createEvent(10, 6));
+ t.add(createEvent(11, 8));
+ t.add(createEvent(10, 7));
+ t.add(createEvent(0, 1));
+ t.add(createEvent(0, 2));
+ t.add(createEvent(15, 9));
+ t.add(createEvent(0, 3));
+ t.add(createEvent(1, 4));
+
+ // now compare the events.
+ // The note param will tell us the
+ // the expected position
+ long lastTick = 0;
+ for (int i = 0; i < t.size(); i++) {
+ MidiEvent ev = t.get(i);
+ if (ev.getMessage() instanceof ShortMessage) {
+ ShortMessage msg = (ShortMessage) ev.getMessage();
+ log(""+i+": ShortMessage at tick "+ev.getTick()
+ +" with expected position "+msg.getData1());
+ if (ev.getTick() < lastTick) {
+ log(" FAILED: last tick is larger than this event's tick!");
+ failed = true;
+ }
+ if (i != msg.getData1()) {
+ log(" FAILED: Track did not order correctly.");
+ failed = true;
+ }
+ }
+ }
+
+ if (failed) throw new Exception("Test FAILED!");
+ log("Test passed.");
+ }
+
+ public static MidiEvent createEvent(long tick, int expectedPos)
+ throws Exception {
+ ShortMessage msg = new ShortMessage();
+ msg.setMessage(0x90, (int) expectedPos, 00);
+ MidiEvent ev = new MidiEvent(msg, tick);
+ return ev;
+ }
+
+ public static void log(String s) {
+ System.out.println(s);
+ }
+
+ public static void log(Exception e) {
+ //System.out.println(s);
+ e.printStackTrace();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Track/bug6416024.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * 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 javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 6416024
+ * @summary Tests that sequence correctly handle removing of EndOfTrack event
+ * @run main bug6416024
+ */
+public class bug6416024 {
+
+ boolean test() {
+ Sequence sequence = null;
+ Track track = null;
+ MidiEvent event = null;
+
+ log("creating sequence...");
+ try {
+ sequence = new Sequence(Sequence.PPQ, 10);
+ log(" - OK: " + sequence);
+ } catch(InvalidMidiDataException e ) {
+ log(" - FAILED: got exception");
+ e.printStackTrace(System.out);
+ return false;
+ }
+
+ log("creating track...");
+ track = sequence.createTrack();
+ log(" - OK: " + track);
+ log("initial track size=" + track.size());
+
+ log("removing all track events...");
+ while (track.size() > 0) {
+ try {
+ event = track.get(0);
+ log(" ..removing event " + event);
+ track.remove(event);
+ log(" - OK, track size=" + track.size());
+ } catch (Exception e) {
+ log(" - FAILED: got exception");
+ e.printStackTrace(System.out);
+ return false;
+ }
+ }
+
+ MetaMessage newMsg = new MetaMessage();
+ MidiEvent newEvent = new MidiEvent(newMsg, 10);
+ log("adding new event...");
+ try {
+ if (!track.add(newEvent)) {
+ log("event hasn't been added");
+ return false;
+ }
+ log(" - OK, track size=" + track.size());
+ } catch (Exception e) {
+ log(" - FAILED: got exception");
+ e.printStackTrace(System.out);
+ return false;
+ }
+
+ return true;
+ }
+
+ public static void main(String args[]) throws Exception {
+ bug6416024 This = new bug6416024();
+ if (This.test()) {
+ log("Test passed sucessfully.");
+ } else {
+ log("Test FAILED!");
+ delay(1000);
+ throw new RuntimeException("Test failed!");
+ }
+ }
+
+ // 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) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Transmitter/bug6415669.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,118 @@
+/*
+ * 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 javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Transmitter;
+
+/**
+ * @test
+ * @bug 6415669
+ * @summary Tests that terminating thread which got transmitter doesn't cause
+ * JVM crash (windows)
+ * @run main bug6415669
+ */
+public class bug6415669 {
+
+ public static void main(String args[]) throws Exception {
+ String osStr = System.getProperty("os.name");
+ boolean isWin = osStr.toLowerCase().startsWith("windows");
+ log("OS: " + osStr);
+ log("Arch: " + System.getProperty("os.arch"));
+ if (!isWin) {
+ log("The test is for Windows only");
+ return;
+ }
+
+ bug6415669 This = new bug6415669();
+ if (This.test()) {
+ log("Test sucessfully passed.");
+ } else {
+ log("Test FAILED!");
+ throw new RuntimeException("Test FAILED!");
+ }
+ }
+
+ volatile Transmitter transmitter = null;
+ Thread openThread = null;
+ boolean test() {
+ openThread = new Thread(new Runnable() {
+ public void run() {
+ try {
+ log("openThread: getting transmitter...");
+ transmitter = MidiSystem.getTransmitter();
+ log("openThread: - OK: " + transmitter);
+ } catch (MidiUnavailableException ex) {
+ log("openThread: - Exception: ");
+ ex.printStackTrace(System.out);
+ log("openThread: skipping...");
+ }
+ log("openThread: exiting...");
+ }
+ });
+ log("starting openThread...");
+ openThread.start();
+
+ while (openThread.isAlive())
+ delay(500);
+ // make additional delay
+ delay(500);
+
+ if (transmitter == null) {
+ return true; // midi is not available, just ignore
+ }
+
+ log("closing transmitter");
+ transmitter.close();
+ log(" - OK");
+
+ return true;
+ }
+
+ // 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) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/AudioFileFormat/AudioFileFormatToString.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,235 @@
+/*
+ * 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.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * @test
+ * @bug 4672864
+ * @summary AudioFileFormat.toString() throws unexpected NullPointerException
+ */
+public class AudioFileFormatToString {
+
+ static final int STATUS_PASSED = 0;
+ static final int STATUS_FAILED = 2;
+ static final int STATUS_TEMP = 95;
+
+ public static void main(String argv[]) throws Exception {
+ int testExitStatus = run(argv, System.out);
+ if (testExitStatus != STATUS_PASSED) {
+ throw new Exception("Test FAILED " + testExitStatus);
+ }
+ System.out.println("Test passed.");
+ }
+
+ public static int run(String argv[], java.io.PrintStream out) {
+ int testResult = STATUS_PASSED;
+
+ out.println("\n==> Test for AudioFileFormat class:");
+
+ AudioFormat testAudioFormat =
+ new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, // AudioFormat.Encoding
+ (float) 44100.0, // float SampleRate
+ (int) 8, // int sampleSizeInBits
+ (int) 2, // int channels
+ (int) 2, // int frameSize
+ (float) 110.0, // float frameRate
+ true // boolean bigEndian
+ );
+ AudioFormat nullAudioFormat = null;
+
+ AudioFileFormat.Type testAudioFileFormatType = AudioFileFormat.Type.WAVE;
+ AudioFileFormat.Type nullAudioFileFormatType = null;
+
+ AudioFileFormat testedAudioFileFormat = null;
+ out.println("\n>> public AudioFileFormat constructor for AudioFileFormat.Type = null: ");
+ try {
+ testedAudioFileFormat =
+ new AudioFileFormat(nullAudioFileFormatType, // AudioFileFormat.Type
+ testAudioFormat, // AudioFormat
+ (int) 1024 // int frameLength
+ );
+ out.println("> No any Exception was thrown!");
+ out.println("> testedAudioFileFormat.getType():");
+ try {
+ AudioFileFormat.Type producedType = testedAudioFileFormat.getType();
+ out.println("> PASSED: producedType = " + producedType);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ out.println("> testedAudioFileFormat.toString():");
+ try {
+ String producedString = testedAudioFileFormat.toString();
+ out.println("> PASSED: producedString = " + producedString);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ } catch (IllegalArgumentException illegArgExcept) {
+ out.println("> PASSED: expected IllegalArgumentException was thrown:");
+ illegArgExcept.printStackTrace(out);
+ } catch (NullPointerException nullPE) {
+ out.println("> PASSED: expected NullPointerException was thrown:");
+ nullPE.printStackTrace(out);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+
+ out.println("\n>> public AudioFileFormat constructor for AudioFormat = null: ");
+ try {
+ testedAudioFileFormat =
+ new AudioFileFormat(testAudioFileFormatType, // AudioFileFormat.Type
+ nullAudioFormat, // AudioFormat
+ (int) 1024 // int frameLength
+ );
+ out.println("> No any Exception was thrown!");
+ out.println("> testedAudioFileFormat.getFormat():");
+ try {
+ AudioFormat producedFormat = testedAudioFileFormat.getFormat();
+ out.println("> PASSED: producedFormat = " + producedFormat);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ out.println("> testedAudioFileFormat.toString():");
+ try {
+ String producedString = testedAudioFileFormat.toString();
+ out.println("> PASSED: producedString = " + producedString);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ } catch (IllegalArgumentException illegArgExcept) {
+ out.println("> PASSED: expected IllegalArgumentException was thrown:");
+ illegArgExcept.printStackTrace(out);
+ } catch (NullPointerException nullPE) {
+ out.println("> PASSED: expected NullPointerException was thrown:");
+ nullPE.printStackTrace(out);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+
+ out.println("\n>> protected AudioFileFormat constructor for AudioFileFormat.Type = null: ");
+ try {
+ testedAudioFileFormat =
+ new TestAudioFileFormat(nullAudioFileFormatType, // AudioFileFormat.Type
+ (int) 1024, // byteLength
+ testAudioFormat, // AudioFormat
+ (int) 1024 // int frameLength
+ );
+ out.println("> No any Exception was thrown!");
+ out.println("> testedAudioFileFormat.getType():");
+ try {
+ AudioFileFormat.Type producedType = testedAudioFileFormat.getType();
+ out.println("> PASSED: producedType = " + producedType);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ out.println("> testedAudioFileFormat.toString():");
+ try {
+ String producedString = testedAudioFileFormat.toString();
+ out.println("> PASSED: producedString = " + producedString);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ } catch (IllegalArgumentException illegArgExcept) {
+ out.println("> PASSED: expected IllegalArgumentException was thrown:");
+ illegArgExcept.printStackTrace(out);
+ } catch (NullPointerException nullPE) {
+ out.println("> PASSED: expected NullPointerException was thrown:");
+ nullPE.printStackTrace(out);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+
+ out.println("\n>> protected AudioFileFormat constructor for AudioFormat = null: ");
+ try {
+ testedAudioFileFormat =
+ new TestAudioFileFormat(testAudioFileFormatType, // AudioFileFormat.Type
+ (int) 1024, // byteLength
+ nullAudioFormat, // AudioFormat
+ (int) 1024 // int frameLength
+ );
+ out.println("> No any Exception was thrown!");
+ out.println("> testedAudioFileFormat.getFormat():");
+ try {
+ AudioFormat producedFormat = testedAudioFileFormat.getFormat();
+ out.println("> PASSED: producedFormat = " + producedFormat);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ out.println("> testedAudioFileFormat.toString():");
+ try {
+ String producedString = testedAudioFileFormat.toString();
+ out.println("> PASSED: producedString = " + producedString);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ } catch (IllegalArgumentException illegArgExcept) {
+ out.println("> PASSED: expected IllegalArgumentException was thrown:");
+ illegArgExcept.printStackTrace(out);
+ } catch (NullPointerException nullPE) {
+ out.println("> PASSED: expected NullPointerException was thrown:");
+ nullPE.printStackTrace(out);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+
+ if (testResult == STATUS_FAILED) {
+ out.println("\n==> test FAILED!");
+ } else {
+ out.println("\n==> test PASSED!");
+ }
+ return testResult;
+ }
+}
+
+class TestAudioFileFormat extends AudioFileFormat {
+
+ TestAudioFileFormat(AudioFileFormat.Type type, int byteLength,
+ AudioFormat format, int frameLength) {
+ super(type, byteLength, format, frameLength);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/AudioFileFormat/Properties.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,144 @@
+/*
+ * 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.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.sound.midi.MidiFileFormat;
+import javax.sound.midi.Sequence;
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * @test
+ * @bug 4666845
+ * @summary RFE: Add properties to AudioFileFormat and MidiFileFormat
+ */
+public class Properties {
+
+ static boolean g_failed = false;
+
+ // all of p1 need to be in p2
+ static boolean compare(Map p1, Map p2) {
+ boolean failed = false;
+ for(String key: (Set<String>) p1.keySet()) {
+ out(" testing key: "+key);
+ if (!p2.containsKey(key)) {
+ out(" missing property: '"+key+"'. Failed");
+ failed = true;
+ }
+ Object v1 = p1.get(key);
+ Object v2 = p2.get(key);
+ if (((v1 == null) && (v2 != null))
+ || ((v1 != null) && (v2 == null))
+ || !(v1.equals(v2))) {
+ out(" property '"+key+"' is different: "
+ +"expected='"+v1+"' "
+ +"actual='"+v2+"'. Failed");
+ failed = true;
+ }
+ }
+ // test if we can modify p2
+ try {
+ int oldSize = p2.size();
+ p2.clear();
+ if (oldSize > 0 && p2.size() == 0) {
+ out(" could clear the properties! Failed.");
+ failed = true;
+ }
+ } catch (Exception e) {
+ // correct
+ }
+ return failed;
+ }
+
+ public static void main(String argv[]) throws Exception {
+ // don't need to catch exceptions: any exception is a
+ // failure of this test
+
+ Map<String, Object> p = new HashMap<String,Object>();
+ p.put("author", "Florian");
+ p.put("duration", new Long(1000));
+ p.put("MyProp", "test");
+
+ out("Testing AudioFileFormat properties:");
+ // create an AudioFileFormat with properties
+ AudioFormat format = new AudioFormat( 44100.0f, 16, 2, true, false);
+ AudioFileFormat aff =
+ new AudioFileFormat(AudioFileFormat.Type.WAVE,
+ format, 1000, p);
+ // test that it has the properties
+ boolean failed = compare(p, aff.properties());
+ // test getProperty()
+ Object o = aff.getProperty("author");
+ if (o == null || !o.equals("Florian")) {
+ out(" getProperty did not report an existing property!");
+ failed = true;
+ }
+ o = aff.getProperty("does not exist");
+ if (o != null) {
+ out(" getProperty returned something for a non-existing property!");
+ failed = true;
+ }
+ if (!failed) {
+ out(" OK");
+ } else {
+ g_failed = true;
+ }
+
+
+
+ out("Testing MidiFileFormat properties:");
+ // create a MidiFileFormat with properties
+ MidiFileFormat mff =
+ new MidiFileFormat(0, Sequence.PPQ, 240,
+ 1000, 100, p);
+ // test that it has the properties
+ failed = compare(p, mff.properties());
+ // test getProperty()
+ o = mff.getProperty("author");
+ if (o == null || !o.equals("Florian")) {
+ out(" getProperty did not report an existing property!");
+ failed = true;
+ }
+ o = mff.getProperty("does not exist");
+ if (o != null) {
+ out(" getProperty returned something for a non-existing property!");
+ failed = true;
+ }
+ if (!failed) {
+ out(" OK");
+ } else {
+ g_failed = true;
+ }
+
+
+ if (g_failed) throw new Exception("Test FAILED!");
+ System.out.println("Test passed.");
+ }
+
+ static void out(String s) {
+ System.out.println(s);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/AudioFileFormat/TypeEquals.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.sampled.AudioFileFormat;
+
+/**
+ * @test
+ * @bug 4925483
+ * @summary RFE: equals() should compare string in Encoding and Type
+ */
+public class TypeEquals {
+
+ public static void main(String argv[]) throws Exception {
+ // first test that we can create our own type
+ // (the constructor was made public)
+ AudioFileFormat.Type myType = new AudioFileFormat.Type("WAVE", "wav");
+
+ // then check if this one equals this new one
+ // with the static instance in AudioFileFormat.Type
+ if (!myType.equals(AudioFileFormat.Type.WAVE)) {
+ throw new Exception("Types do not equal!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/AudioFormat/AudioFormatBitSize.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 4754759
+ * @summary AudioFormat does not handle uncommon bit sizes correctly
+ */
+
+import javax.sound.sampled.AudioFormat;
+
+public class AudioFormatBitSize {
+
+ public static void main(String[] args) throws Exception {
+ int bits = 18;
+ AudioFormat format = new AudioFormat(44100.0f, bits, 1, true, false);
+ if (format.getFrameSize() * 8 < bits) {
+ System.out.println("bits = "+bits+" do not fit into a "+format.getFrameSize()+" bytes sample!");
+ throw new Exception("Test failed");
+ } else
+ System.out.println("bits = "+bits+" fit OK into a "+format.getFrameSize()+" bytes sample!");
+ System.out.println("Test passed");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/AudioFormat/EncodingEquals.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.sampled.AudioFormat;
+
+/**
+ * @test
+ * @bug 4925483
+ * @summary RFE: equals() should compare string in Encoding and Type
+ */
+public class EncodingEquals {
+
+ public static void main(String argv[]) throws Exception {
+ // first test that we can create our own encoding
+ // (the constructor was made public)
+ AudioFormat.Encoding myType = new AudioFormat.Encoding("PCM_SIGNED");
+
+ // then check if this one equals this new one
+ // with the static instance in AudioFormat.Encoding
+ if (!myType.equals(AudioFormat.Encoding.PCM_SIGNED)) {
+ throw new Exception("Encodings do not equal!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/AudioFormat/Properties.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,115 @@
+/*
+ * 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.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * @test
+ * @bug 4925767
+ * @summary RFE: Add Properties to AudioFormat
+ */
+public class Properties {
+
+ static boolean g_failed = false;
+
+ // all of p1 need to be in p2
+ static boolean compare(Map p1, Map p2) {
+ boolean failed = false;
+ for(String key: (Set<String>) p1.keySet()) {
+ out(" testing key: "+key);
+ if (!p2.containsKey(key)) {
+ out(" missing property: '"+key+"'. Failed");
+ failed = true;
+ }
+ Object v1 = p1.get(key);
+ Object v2 = p2.get(key);
+ if (((v1 == null) && (v2 != null))
+ || ((v1 != null) && (v2 == null))
+ || !(v1.equals(v2))) {
+ out(" property '"+key+"' is different: "
+ +"expected='"+v1+"' "
+ +"actual='"+v2+"'. Failed");
+ failed = true;
+ }
+ }
+ // test if we can modify p2
+ try {
+ int oldSize = p2.size();
+ p2.clear();
+ if (oldSize > 0 && p2.size() == 0) {
+ out(" could clear the properties! Failed.");
+ failed = true;
+ }
+ } catch (Exception e) {
+ // correct
+ }
+ return failed;
+ }
+
+
+ public static void main(String argv[]) throws Exception {
+ // don't need to catch exceptions: any exception is a
+ // failure of this test
+
+ Map<String, Object> p = new HashMap<String,Object>();
+ p.put("bitrate", new Integer(128));
+ p.put("quality", new Integer(10));
+ p.put("MyProp", "test");
+
+ out("Testing AudioFileFormat properties:");
+ // create an AudioFileFormat with properties
+ AudioFormat format =
+ new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
+ 44100.0f, 16, 2, 4, 44100.0f, false, p);
+ // test that it has the properties
+ boolean failed = compare(p, format.properties());
+ // test getProperty()
+ Object o = format.getProperty("MyProp");
+ if (o == null || !o.equals("test")) {
+ out(" getProperty did not report an existing property!");
+ failed = true;
+ }
+ o = format.getProperty("does not exist");
+ if (o != null) {
+ out(" getProperty returned something for a non-existing property!");
+ failed = true;
+ }
+ if (!failed) {
+ out(" OK");
+ } else {
+ g_failed = true;
+ }
+
+ if (g_failed) throw new Exception("Test FAILED!");
+ System.out.println("Test passed.");
+ }
+
+ static void out(String s) {
+ System.out.println(s);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/AudioInputStream/AISReadFraction.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,237 @@
+/*
+ * 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.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4948663
+ * @summary AudioInputStream does not use the original stream passed to its constructor
+ */
+public class AISReadFraction {
+
+ static int failed = 0;
+ static byte[] testData = new byte[256];
+ static boolean DEBUG = false;
+
+ static AudioFormat[] formats = {
+ new AudioFormat(44100.0f, 8, 1, false, false), // frameSize = 1
+ new AudioFormat(44100.0f, 8, 2, false, false), // frameSize = 2
+ new AudioFormat(44100.0f, 16, 1, true, false), // frameSize = 2
+ new AudioFormat(44100.0f, 24, 1, true, false), // frameSize = 3
+ new AudioFormat(44100.0f, 16, 2, true, false), // frameSize = 4
+ new AudioFormat(44100.0f, 8, 5, false, false), // frameSize = 5
+ new AudioFormat(44100.0f, 16, 3, true, false), // frameSize = 6
+ new AudioFormat(44100.0f, 8, 7, false, false), // frameSize = 7
+ new AudioFormat(44100.0f, 32, 2, true, false) // frameSize = 8
+ };
+
+
+ public static void main(String args[]) throws Exception {
+ for (int i = 0; i<testData.length; i++) {
+ testData[i] = (byte) (i % 128);
+ }
+
+ for (int f = 0; f < formats.length; f++) {
+ // first test without marking
+ doTest(formats[f], false);
+ // then with marking
+ doTest(formats[f], true);
+ }
+
+ out(""+failed+" failures.");
+ if (failed>0) throw new Exception("Test FAILED!");
+ out("Test passed.");
+ }
+
+ static void doTest(AudioFormat format, boolean doMark) {
+ out("Test with"+(doMark?"":"out")+" marking. Audio format: "
+ +"sampleSize="+format.getSampleSizeInBits()+"bits "
+ +"channels="+format.getChannels()+" "
+ +"frameSize="+format.getFrameSize()+"byte(s)");
+ int maxReadBytes = (testData.length / format.getFrameSize()) * format.getFrameSize();
+ InputStream is = new FractionalIS(testData, doMark);
+ AudioInputStream ais = new AudioInputStream(is, format, AudioSystem.NOT_SPECIFIED);
+ // first some general tests
+ if (ais.markSupported() && !doMark) {
+ out(" #AIS reports markSupported, but underlying stream cannot! FAILED");
+ failed ++;
+ }
+ if (!ais.markSupported() && doMark) {
+ out(" #AIS does not report markSupported, but underlying stream can mark! FAILED");
+ failed++;
+ }
+ byte[] data = new byte[1000];
+ int frameSize = format.getFrameSize();
+ int counter = 5;
+ int totalReadBytes = 0;
+ boolean hasRead0 = false;
+ boolean hasMarked = false;
+ boolean hasReset = false;
+ int markPos = 0;
+ while (true) {
+ try {
+ int toBeRead = frameSize * counter;
+ counter += 3;
+ if (counter > 14) {
+ counter -= 14;
+ }
+ int read = ais.read(data, 0, toBeRead);
+ if (DEBUG) out(" -> ais.read(data, 0, "+toBeRead+"): "+read+" (frameSize="+frameSize+")");
+ if ((totalReadBytes == maxReadBytes) && (read != -1)
+ && ((read > 0) || hasRead0)) {
+ if (read == 0) {
+ out(" #stream was read to the end ("+maxReadBytes+"), but ais.read returned repeatedly 0 bytes. FAILED");
+ } else {
+ out(" #stream was read to the end ("+maxReadBytes+"), but ais.read returned "+read+" bytes... FAILED");
+ }
+ failed++;
+ break;
+ }
+ if (read > 0) {
+ verifyReadBytes(data, totalReadBytes, read);
+ if ((read % frameSize) != 0) {
+ out(" #Read non-integral number of frames: "+read+" bytes, frameSize="+frameSize+" bytes. FAILED");
+ failed++;
+ }
+ totalReadBytes += read;
+ hasRead0 = false;
+ }
+ else if (read == 0) {
+ //out(" wanted to read "+toBeRead+" at position "+totalReadBytes+", but got 0 bytes!");
+ if (hasRead0) {
+ out(" read 0 twice in a row! FAILED");
+ failed++;
+ break;
+ }
+ hasRead0 = true;
+ } else {
+ // end of stream
+ out(" End of stream reached. Total read bytes: "+totalReadBytes);
+ if (totalReadBytes != maxReadBytes) {
+ out(" #Failed: should have read "+maxReadBytes+" bytes! FAILED.");
+ failed++;
+ }
+ break;
+ }
+
+ // test marking
+ if (totalReadBytes > 50 && !hasMarked && !hasReset && doMark) {
+ out(" Marking at position "+totalReadBytes);
+ hasMarked = true;
+ ais.mark(0);
+ markPos = totalReadBytes;
+ }
+ if (totalReadBytes > 100 && hasMarked && !hasReset && doMark) {
+ out(" Resetting at position "+totalReadBytes+" back to "+markPos);
+ hasReset = true;
+ ais.reset();
+ totalReadBytes = markPos;
+ }
+
+ } catch (IOException e) {
+ out(" #caught unexpected exception:");
+ e.printStackTrace();
+ failed++;
+ }
+ }
+ }
+
+ static void verifyReadBytes(byte[] data, int offset, int len) {
+ int firstWrongByte = -1;
+ for (int i = 0; i < len; i++) {
+ int expected = ((offset + i) % 128);
+ if (data[i] != expected) {
+ out(" read data is not correct! offset="+offset+" expected="+expected+" actual="+data[i]);
+ failed++;
+ break;
+ }
+ }
+ }
+
+
+ public static void out(String s) {
+ System.out.println(s);
+ }
+
+
+ static class FractionalIS extends InputStream {
+ byte[] data;
+ int pos = 0;
+ boolean canMark;
+ // a counter how many bytes are not returned
+ int missingBytes = 0;
+ int markPos = -1;
+
+ FractionalIS(byte[] data, boolean canMark) {
+ this.data = data;
+ this.canMark = canMark;
+ }
+
+ public int read() throws IOException {
+ if (pos >= data.length) {
+ return -1;
+ }
+ return data[pos++] & 0xFF;
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (++missingBytes > 5) {
+ missingBytes = 0;
+ }
+ int reducedLen = len - missingBytes;
+ if (reducedLen <= 0) reducedLen = 1;
+ if (DEBUG) out(" FIS.read(data, 0, "+len+"): reducing len to "+reducedLen+" bytes.");
+ int ret = super.read(b, off, reducedLen);
+ if (DEBUG) out(" returning "+ret+" bytes. Now at pos="+pos);
+ return ret;
+ }
+
+ public void mark(int readlimit) {
+ markPos = pos;
+ if (DEBUG) out(" FIS.mark(): marking at "+pos);
+ }
+
+ public void reset() throws IOException {
+ if (!canMark) {
+ throw new IOException("reset not supported!");
+ }
+ if (markPos == -1) {
+ throw new IOException("Mark position not set!");
+ }
+ pos = markPos;
+ if (DEBUG) out(" FIS.reset(): now back at "+pos);
+ }
+
+ public boolean markSupported() {
+ return canMark;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/AudioInputStream/bug6188860.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2005, 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.io.InputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 6188860
+ * @summary Tests that method AudioInputStream.read() returns right value
+ */
+public class bug6188860 {
+
+ public static void main(String[] args) throws Exception {
+ byte[] testData = new byte[256];
+
+ // fill data
+ for (int i = 0; i < testData.length; i++)
+ testData[i] = (byte) (i % 128);
+
+ InputStream streamSrc = new TestInputStream(testData);
+ AudioFormat format = new AudioFormat(44100.0f, 8, 1, false, false); // frameSize = 1
+ AudioInputStream streamAudio = new AudioInputStream(streamSrc, format, AudioSystem.NOT_SPECIFIED);
+
+ int nErrCount = 0;
+ int nTotal = 0;
+
+ int dataSrc, dataRead;
+ while (nTotal < (testData.length - 1)) {
+ dataRead = streamAudio.read();
+ if (dataRead < 0) {
+ System.out.println("end of stream");
+ break;
+ }
+
+ dataSrc = testData[nTotal];
+
+ if (dataRead != dataSrc) {
+ System.out.println("" + nTotal + " - mismatch :" + dataRead + " <> " + dataSrc);
+ nErrCount++;
+ }
+ nTotal++;
+ }
+
+ System.out.println("Total: " + nTotal + "; Mismatches: " + nErrCount);
+
+ if (nErrCount > 0) {
+ throw new RuntimeException("test failed: " + nErrCount + " mismatches of total " + nTotal + " bytes.");
+ }
+ System.out.println("Test sucessfully passed.");
+ }
+
+
+ static class TestInputStream extends InputStream {
+ byte[] data;
+ int pos = 0;
+
+ TestInputStream(byte[] data) {
+ this.data = data;
+ }
+
+ public int read() throws IOException {
+ if (pos >= data.length) {
+ return -1;
+ }
+ return data[pos++] & 0xFF;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/AudioSystem/AudioFileTypes/AudioFileTypeUniqueness.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4883060
+ * @summary AudioSystem.getAudioFileTypes returns duplicates
+ */
+public class AudioFileTypeUniqueness {
+
+ public static void main(String[] args) throws Exception {
+ boolean foundDuplicates = false;
+ AudioFileFormat.Type[] aTypes = AudioSystem.getAudioFileTypes();
+ for (int i = 0; i < aTypes.length; i++)
+ {
+ for (int j = 0; j < aTypes.length; j++)
+ {
+ if (aTypes[i].equals(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/sampled/AudioSystem/AudioFileTypes/ShowAudioFileTypes.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2001, 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.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4303037
+ * @summary Shows the existing audio file types of AudioSystem and checks
+ * whether there are some at all
+ */
+public class ShowAudioFileTypes {
+
+ public static void main(String[] args) throws Exception {
+ AudioFileFormat.Type[] aTypes = AudioSystem.getAudioFileTypes();
+ System.out.println(aTypes.length+" supported target types:");
+ for (int i = 0; i < aTypes.length; i++)
+ {
+ System.out.println(" "+(i+1)+". " + aTypes[i]+" with ext. '"+aTypes[i].getExtension()+"'");
+ }
+ if (aTypes.length<3) {
+ 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/sampled/AudioSystem/DefaultMixers.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,198 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.Port;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+import javax.sound.sampled.spi.MixerProvider;
+
+import com.sun.media.sound.JDK13Services;
+
+/**
+ * @test
+ * @bug 4776511
+ * @summary RFE: Setting the default MixerProvider. Test the retrieving of lines
+ * with defaut mixer properties.
+ * @modules java.desktop/com.sun.media.sound
+ */
+public class DefaultMixers {
+
+ private static final String ERROR_PROVIDER_CLASS_NAME = "abc";
+ private static final String ERROR_INSTANCE_NAME = "def";
+
+ private static final Class[] lineClasses = {
+ SourceDataLine.class,
+ TargetDataLine.class,
+ Clip.class,
+ Port.class,
+ };
+
+ public static void main(String[] args) throws Exception {
+ boolean allOk = true;
+ Mixer.Info[] infos;
+
+ out("Testing Mixers retrieved via AudioSystem");
+ infos = AudioSystem.getMixerInfo();
+ allOk &= testMixers(infos, null);
+
+ out("Testing MixerProviders");
+ List providers = JDK13Services.getProviders(MixerProvider.class);
+ for (int i = 0; i < providers.size(); i++) {
+ MixerProvider provider = (MixerProvider) providers.get(i);
+ infos = provider.getMixerInfo();
+ allOk &= testMixers(infos, provider.getClass().getName());
+ }
+
+ if (! allOk) {
+ throw new Exception("Test failed");
+ } else {
+ out("Test passed");
+ }
+ }
+
+ private static boolean testMixers(Mixer.Info[] infos,
+ String providerClassName) {
+ boolean allOk = true;
+
+ for (int i = 0; i < infos.length; i++) {
+ Mixer mixer = null;
+ try {
+ mixer = AudioSystem.getMixer(infos[i]);
+ } catch (NullPointerException e) {
+ out("Exception thrown; Test NOT failed.");
+ e.printStackTrace();
+ }
+ for (int j = 0; j < lineClasses.length; j++) {
+ if (mixer.isLineSupported(new Line.Info(lineClasses[j]))) {
+ allOk &= testMixer(mixer, lineClasses[j],
+ providerClassName);
+ }
+ }
+ }
+ return allOk;
+ }
+
+ private static boolean testMixer(Mixer mixer, Class lineType,
+ String providerClassName) {
+ boolean allOk = true;
+ String instanceName = mixer.getMixerInfo().getName();
+
+ // no error
+ allOk &= testMixer(mixer, lineType,
+ providerClassName, instanceName);
+
+ // erroneous provider class name, correct instance name
+ allOk &= testMixer(mixer, lineType,
+ ERROR_PROVIDER_CLASS_NAME, instanceName);
+
+ // erroneous provider class name, no instance name
+ allOk &= testMixer(mixer, lineType,
+ ERROR_PROVIDER_CLASS_NAME, "");
+
+ // erroneous provider class name, erroneous instance name
+ allOk &= testMixer(mixer, lineType,
+ ERROR_PROVIDER_CLASS_NAME, ERROR_INSTANCE_NAME);
+
+ return allOk;
+ }
+
+ private static boolean testMixer(Mixer mixer, Class lineType,
+ String providerClassName,
+ String instanceName) {
+ boolean allOk = true;
+
+ try {
+ String propertyValue = (providerClassName != null) ? providerClassName: "" ;
+ propertyValue += "#" + instanceName;
+ out("property value: " + propertyValue);
+ System.setProperty(lineType.getName(), propertyValue);
+ Line line = null;
+ Line.Info info = null;
+ Line.Info[] infos;
+ AudioFormat format = null;
+ if (lineType == SourceDataLine.class || lineType == Clip.class) {
+ infos = mixer.getSourceLineInfo();
+ format = getFirstLinearFormat(infos);
+ info = new DataLine.Info(lineType, format);
+ } else if (lineType == TargetDataLine.class) {
+ infos = mixer.getTargetLineInfo();
+ format = getFirstLinearFormat(infos);
+ info = new DataLine.Info(lineType, format);
+ } else if (lineType == Port.class) {
+ /* Actually, a Ports Mixer commonly has source infos
+ as well as target infos. We ignore this here, since we
+ just need a random one. */
+ infos = mixer.getSourceLineInfo();
+ for (int i = 0; i < infos.length; i++) {
+ if (infos[i] instanceof Port.Info) {
+ info = infos[i];
+ break;
+ }
+ }
+ }
+ out("Line.Info: " + info);
+ line = AudioSystem.getLine(info);
+ out("line: " + line);
+ if (! lineType.isInstance(line)) {
+ out("type " + lineType + " failed: class should be '" +
+ lineType + "' but is '" + line.getClass() + "'!");
+ allOk = false;
+ }
+ } catch (Exception e) {
+ out("Exception thrown; Test NOT failed.");
+ e.printStackTrace();
+ }
+ return allOk;
+ }
+
+ private static AudioFormat getFirstLinearFormat(Line.Info[] infos) {
+ for (int i = 0; i < infos.length; i++) {
+ if (infos[i] instanceof DataLine.Info) {
+ AudioFormat[] formats = ((DataLine.Info) infos[i]).getFormats();
+ for (int j = 0; j < formats.length; j++) {
+ AudioFormat.Encoding encoding = formats[j].getEncoding();
+ int sampleSizeInBits = formats[j].getSampleSizeInBits();
+ if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED) &&
+ sampleSizeInBits == 16 ||
+ encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED) &&
+ sampleSizeInBits == 16) {
+ return formats[j];
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ 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/sampled/AudioSystem/DefaultProperties.java Wed Jul 05 22:25:59 2017 +0200
@@ -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
+ * @build DefaultProperties
+ * @run main/othervm DefaultProperties
+ * @summary RFE: Setting the default MixerProvider. Test the retrieving and
+ * parsing of properties.
+ * @modules java.desktop/com.sun.media.sound
+ */
+public class DefaultProperties {
+
+ private static final Class[] lineTypeClasses = {
+ javax.sound.sampled.SourceDataLine.class,
+ javax.sound.sampled.TargetDataLine.class,
+ javax.sound.sampled.Clip.class,
+ javax.sound.sampled.Port.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/sampled/AudioSystem/ProviderCacheing.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * 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 com.sun.media.sound.JDK13Services;
+
+/**
+ * @test
+ * @bug 4776511
+ * @summary RFE: Setting the default MixerProvider. Test the cacheing of
+ * providers.
+ * @modules java.desktop/com.sun.media.sound
+ */
+public class ProviderCacheing {
+
+ private static final Class[] providerClasses = {
+ javax.sound.sampled.spi.AudioFileReader.class,
+ javax.sound.sampled.spi.AudioFileWriter.class,
+ javax.sound.sampled.spi.FormatConversionProvider.class,
+ javax.sound.sampled.spi.MixerProvider.class,
+ };
+
+ public static void main(String[] args) throws Exception {
+ boolean allCached = true;
+ for (int i = 0; i < providerClasses.length; i++) {
+ List list0 = JDK13Services.getProviders(providerClasses[i]);
+ List list1 = JDK13Services.getProviders(providerClasses[i]);
+ if (list0 == list1) {
+ out("Providers should not be cached for " + providerClasses[i]);
+ allCached = false;
+ }
+ }
+
+ if (! allCached) {
+ 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/sampled/AudioSystem/testdata/conf/sound.properties Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+
+javax.sound.sampled.SourceDataLine=xyz#123
+javax.sound.sampled.TargetDataLine=xyz#123
+javax.sound.sampled.Clip=xyz#123
+javax.sound.sampled.Port=xyz#123
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Clip/ClipCloseLoss.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,163 @@
+/*
+ * 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.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4946913
+ * @summary DirectClip doesn't kill the thread correctly, sometimes
+ * @run main/othervm ClipCloseLoss
+ * @key headful
+ */
+public class ClipCloseLoss {
+ static int frameCount = 441000; // lets say 10 seconds
+ static AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false);
+ static ByteArrayInputStream bais =
+ new ByteArrayInputStream(new byte[frameCount * format.getFrameSize()]);
+
+ static int success = 0;
+ static boolean failed = false;
+
+ public static void run(Mixer m) {
+ Clip clip = null;
+ try {
+ if (m == null) {
+ out("Using default mixer");
+ clip = (Clip) AudioSystem.getClip();
+ } else {
+ out("Using mixer: "+m);
+ DataLine.Info info = new DataLine.Info(Clip.class, format, AudioSystem.NOT_SPECIFIED);
+ clip = (Clip) m.getLine(info);
+ }
+ out(" got clip: "+clip);
+ if (!clip.getClass().toString().contains("Direct")) {
+ out(" no direct audio clip -> do not test.");
+ return;
+ }
+
+ out(" open");
+ bais.reset();
+ clip.open(new AudioInputStream(bais, format, frameCount));
+
+ out(" clip.close()");
+ //long t = System.currentTimeMillis();
+ clip.close();
+ //if (System.currentTimeMillis() - t > 1950) {
+ // out(" clip.close needed more than 2 seconds! Causes failure of this test.");
+ // failed = true;
+ //}
+ out(" clip closed");
+ success++;
+ } catch (LineUnavailableException luae) {
+ // line not available, test not failed
+ System.err.println(luae);
+ } catch (IllegalArgumentException iae) {
+ // line not available, test not failed
+ System.err.println(iae);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ public static int getClipThreadCount() {
+ int ret = 0;
+ ThreadGroup tg = Thread.currentThread().getThreadGroup();
+ while (tg.getParent() != null) { tg = tg.getParent(); }
+ Thread[] threads = new Thread[500];
+ int count = tg.enumerate(threads, true);
+ for (int i = 0; i < count; i++) {
+ if (threads[i].getName().contains("Direct")
+ && threads[i].getName().contains("Clip")) {
+ out("Found Direct Clip thread object: "+threads[i]);
+ ret++;
+ }
+ }
+ return ret;
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (isSoundcardInstalled()) {
+ bais.mark(0);
+ run(null);
+ Mixer.Info[] infos = AudioSystem.getMixerInfo();
+ for (int i = 0; i<infos.length; i++) {
+ try {
+ Mixer m = AudioSystem.getMixer(infos[i]);
+ run(m);
+ } catch (Exception e) {
+ }
+ }
+ out("Waiting 1 second to dispose of all threads");
+ Thread.sleep(1000);
+ if (getClipThreadCount() > 0) {
+ out("Unused clip threads exist! Causes test failure");
+ failed = true;
+ }
+ if (failed) throw new Exception("Test FAILED!");
+ if (success > 0) {
+ out("Test passed.");
+ } else {
+ System.err.println("Test could not execute: please install an audio device");
+ }
+ }
+ }
+
+ /**
+ * Returns true if at least one soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: "+e);
+ }
+ 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;
+ }
+
+ public static void out(String s) {
+ /*long t = System.nanoTime() / 1000000l;
+ String ts = ""+(t % 1000);
+ while (ts.length() < 3) ts = "0"+ts;
+ System.out.println(""+(t/1000)+":"+ts+" "+s);
+ System.out.flush();*/
+ System.out.println(s);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Clip/ClipFlushCrash.java Wed Jul 05 22:25:59 2017 +0200
@@ -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.io.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4946945
+ * @summary Crash in javasound while running TicTacToe demo applet tiger b26
+ */
+public class ClipFlushCrash {
+ static int frameCount = 441000; // lets say 10 seconds
+ static AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false);
+ static ByteArrayInputStream bais =
+ new ByteArrayInputStream(new byte[frameCount * format.getFrameSize()]);
+
+ static int success = 0;
+
+ public static void run(Mixer m) {
+ Clip clip = null;
+ try {
+ if (m == null) {
+ out("Using default mixer");
+ clip = (Clip) AudioSystem.getClip();
+ } else {
+ out("Using mixer: "+m);
+ DataLine.Info info = new DataLine.Info(Clip.class, format, AudioSystem.NOT_SPECIFIED);
+ clip = (Clip) m.getLine(info);
+ }
+ out(" got clip: "+clip);
+ if (!clip.getClass().toString().contains("Direct")) {
+ out(" no direct audio clip -> do not test.");
+ return;
+ }
+
+ out(" open");
+ bais.reset();
+ clip.open(new AudioInputStream(bais, format, frameCount));
+
+ AT at1 = new AT(clip, "flush thread", 123) {
+ public void doAction() throws Exception {
+ log("flush");
+ clip.flush();
+ }
+ };
+ AT at2 = new AT(clip, "setFramePosition thread", 67) {
+ public void doAction() throws Exception {
+ int pos = (int) (Math.random() * clip.getFrameLength());
+ log("setPosition to frame "+pos);
+ clip.setFramePosition(pos);
+ }
+ };
+ AT at3 = new AT(clip, "start/stop thread", 300) {
+ public void doAction() throws Exception {
+ if (clip.isRunning()) {
+ log("stop");
+ clip.stop();
+ } else {
+ log("start");
+ clip.setFramePosition(0);
+ clip.start();
+ }
+ }
+ };
+ AT at4 = new AT(clip, "open/close thread", 600) {
+ public synchronized void doAction() throws Exception {
+ log("close");
+ clip.close();
+ wait(50);
+ if (!terminated) {
+ log("open");
+ bais.reset();
+ clip.open(new AudioInputStream(bais, format, frameCount));
+ }
+ }
+ };
+
+ out(" clip.start");
+ clip.start();
+ out(" for 10 seconds, call start/stop, setFramePosition, and flush from other threads");
+ at1.start();
+ at2.start();
+ at3.start();
+ at4.start();
+ try {
+ Thread.sleep(10000);
+ } catch (InterruptedException ie) {}
+ out(" finished.");
+ at1.terminate();
+ at2.terminate();
+ at3.terminate();
+ at4.terminate();
+ out(" clip.close()");
+ clip.close();
+ success++;
+ } catch (LineUnavailableException luae) {
+ // line not available, test not failed
+ System.err.println(luae);
+ } catch (IllegalArgumentException iae) {
+ // line not available, test not failed
+ System.err.println(iae);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (isSoundcardInstalled()) {
+ bais.mark(0);
+ run(null);
+ Mixer.Info[] infos = AudioSystem.getMixerInfo();
+ for (int i = 0; i<infos.length; i++) {
+ try {
+ Mixer m = AudioSystem.getMixer(infos[i]);
+ run(m);
+ } catch (Exception e) {
+ }
+ }
+ if (success > 0) {
+ out("No crash -> Test passed");
+ } else {
+ System.err.println("Test could not execute: please install an audio device");
+ }
+ }
+ }
+
+ /**
+ * Returns true if at least one soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: "+e);
+ }
+ 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;
+ }
+
+ public static void out(String s) {
+ /*long t = System.nanoTime() / 1000000l;
+ String ts = ""+(t % 1000);
+ while (ts.length() < 3) ts = "0"+ts;
+ System.out.println(""+(t/1000)+":"+ts+" "+s);
+ System.out.flush();*/
+ System.out.println(s);
+ }
+
+ private abstract static class AT extends Thread {
+ protected boolean terminated = false;
+ protected Clip clip;
+ private int waitTime;
+
+ public AT(Clip clip, String name, int waitTime) {
+ super(name);
+ this.clip = clip;
+ this.waitTime = waitTime;
+ }
+
+ public abstract void doAction() throws Exception;
+
+ public void run() {
+ log("start");
+ while (!terminated) {
+ try {
+ synchronized(this) {
+ wait(waitTime);
+ }
+ if (!terminated) {
+ doAction();
+ }
+ } catch(Exception e) {
+ log("exception: "+e);
+ }
+ }
+ log("exit");
+ }
+
+ public synchronized void terminate() {
+ log("terminate");
+ terminated = true;
+ notifyAll();
+ }
+
+ protected void log(String s) {
+ //out(" "+Thread.currentThread().getId()+" "+getName()+": "+s);
+ out(" "+getName()+": "+s);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Clip/Drain/ClipDrain.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,126 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4732218
+ * @summary Clip.drain does not actually block until all I/O is complete as
+ * documented.
+ */
+public class ClipDrain {
+ static int successfulTests = 0;
+ static AudioFormat format = new AudioFormat(8000, 16, 1, true, false);
+ // create a 10-second file
+ static byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * 10)];
+
+ static int TOLERANCE_MS = 2500; // how many milliseconds too short is tolerated...
+
+ private static void doMixerClip(Mixer mixer) throws Exception {
+ boolean waitedEnough=false;
+ try {
+ DataLine.Info info = new DataLine.Info(Clip.class, format);
+ Clip clip = (Clip) mixer.getLine(info);
+ clip.open(format, soundData, 0, soundData.length);
+
+ // sanity
+ if (clip.getMicrosecondLength()/1000 < 9900) {
+ throw new Exception("clip's microsecond length should be at least 9900000, but it is "+clip.getMicrosecondLength());
+ }
+ long start = System.currentTimeMillis();
+
+ System.out.println(" ---------- start --------");
+ clip.start();
+ // give time to actually start it. ALSA implementation needs that...
+ Thread.sleep(300);
+ System.out.println("drain ... ");
+ clip.drain();
+ long elapsedTime = System.currentTimeMillis() - start;
+ System.out.println("close ... ");
+ clip.close();
+ System.out.println("... done");
+ System.out.println("Playback duration: "+elapsedTime+" milliseconds.");
+ waitedEnough = elapsedTime >= ((clip.getMicrosecondLength() / 1000) - TOLERANCE_MS);
+ } catch (Throwable t) {
+ System.out.println(" - Caught exception. Not failed.");
+ System.out.println(" - "+t.toString());
+ return;
+ }
+ if (!waitedEnough) {
+ throw new Exception("Drain did not wait long enough to play entire clip.");
+ }
+ successfulTests++;
+ }
+
+
+ private static void doAll() throws Exception {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ for (int i=0; i<mixers.length; i++) {
+ Mixer mixer = AudioSystem.getMixer(mixers[i]);
+ System.out.println("--------------");
+ System.out.println("Testing mixer: "+mixers[i]);
+ doMixerClip(mixer);
+ }
+ if (mixers.length==0) {
+ System.out.println("No mixers available!");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (!isSoundcardInstalled()) {
+ 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 soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: "+e);
+ }
+ 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/sampled/Clip/Duration/ClipDuration.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001, 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4237703
+ * @summary Check that Clip.getMicrosecondLength() returns correct value.
+ */
+public class ClipDuration {
+
+ public static int run(Mixer m) {
+ int res=1; // failed
+ int frameCount = 441000; // lets say 10 seconds
+ AudioFormat f = new AudioFormat(44100.0f, 16, 2, true, false);
+ AudioInputStream audioInputStream =
+ new AudioInputStream(new ByteArrayInputStream(new byte[frameCount * f.getFrameSize()]),
+ f, frameCount);
+ AudioFormat format = audioInputStream.getFormat();
+ Clip m_clip = null;
+ try {
+ if (m == null) {
+ m_clip = (Clip) AudioSystem.getClip();
+ } else {
+ DataLine.Info info = new DataLine.Info(Clip.class, format, AudioSystem.NOT_SPECIFIED);
+ m_clip = (Clip) m.getLine(info);
+ }
+ System.out.println("Got clip: "+m_clip);
+ m_clip.open(audioInputStream);
+ long microseconds=m_clip.getMicrosecondLength();
+ System.out.println("getFrameLength()="+m_clip.getFrameLength()+" frames");
+ System.out.println("getMicrosecondLength()="+microseconds+" us");
+ if (Math.abs(microseconds-10000000)<50) {
+ System.out.println("->Clip OK");
+ res=0; // passes if less than 50us error
+ }
+ } catch (LineUnavailableException luae) {
+ System.err.println(luae);
+ res = 3; // line not available, test not failed
+ } catch (Throwable t) {
+ System.out.println("->Exception:"+t);
+ t.printStackTrace();
+ res=2; // exception
+ }
+ if (m_clip != null) {
+ m_clip.close();
+ }
+ return res;
+ }
+
+
+
+ public static void main(String[] args) throws Exception {
+ if (isSoundcardInstalled()) {
+ int res=3;
+ res = run(null);
+ Mixer.Info[] infos = AudioSystem.getMixerInfo();
+ for (int i = 0; i<infos.length; i++) {
+ try {
+ Mixer m = AudioSystem.getMixer(infos[i]);
+ int r = run(m);
+ if (r == 1) res = 1;
+ } catch (Exception e) {
+ }
+ }
+ if (res!=1) {
+ System.out.println("Test passed");
+ } else {
+ if (res==2) {
+ System.err.println("Test could not execute: test threw unexpected Exception.");
+ throw new Exception("Test threw exception");
+ }
+ else if (res==3) {
+ System.err.println("Test could not execute: please install an audio device");
+ return;
+ }
+ throw new Exception("Test returned wrong length");
+ }
+ }
+ }
+
+ /**
+ * Returns true if at least one soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: "+e);
+ }
+ 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/sampled/Clip/Endpoint/ClipSetEndPoint.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2005, 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4385928
+ * @summary Verify that an endpoint -1 in Clip does not throw an exception
+ */
+//public class test048 extends TRTest
+public class ClipSetEndPoint {
+
+ private Clip theClip;
+
+ boolean testPassed = true;
+
+ //_______________________________________________
+ // Method: runTest
+ //_______________________________________________
+ public boolean runTest() {
+ AudioInputStream theAudioInputStream = new AudioInputStream(
+ new ByteArrayInputStream(new byte[2000]),
+ new AudioFormat(8000.0f, 8, 1, false, false), 2000); //
+
+ AudioFormat theAudioFormat = theAudioInputStream.getFormat();
+
+ DataLine.Info info = new DataLine.Info(Clip.class, theAudioFormat,
+ AudioSystem.NOT_SPECIFIED);
+ try {
+ theClip = (Clip) AudioSystem.getLine(info);
+ theClip.open(theAudioInputStream);
+
+ int theStartLoopPoint = 0;
+ int theEndLoopPoint = -1; // -1 signifies the last frame
+
+ theClip.setLoopPoints(theStartLoopPoint, theEndLoopPoint);
+ //theClip.start();
+ } catch (LineUnavailableException e) {
+ e.printStackTrace();
+ testPassed = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ testPassed = false;
+ }
+ return testPassed;
+ }
+
+ //_______________________________________________
+ // Method: main
+ //_______________________________________________
+ public static void main(String[] args) throws Exception {
+ if (isSoundcardInstalled()) {
+ ClipSetEndPoint thisTest = new ClipSetEndPoint();
+ boolean testResult = thisTest.runTest();
+ if (testResult) {
+ System.out.println("Test passed");
+ } else {
+ System.out.println("Test failed");
+ throw new Exception("Test failed");
+ }
+ }
+ }
+
+ /**
+ * Returns true if at least one soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: " + e);
+ }
+ 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/sampled/Clip/Open/ClipOpenBug.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2001, 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.FloatControl;
+
+/**
+ * @test
+ * @bug 4479444
+ * @summary Verify that the error string of Clip.open() is meaningful
+ */
+public class ClipOpenBug {
+
+ public static void main(String args[]) throws Exception {
+ boolean res = true;
+ try {
+ AudioInputStream ais = new AudioInputStream(
+ new ByteArrayInputStream(new byte[2000]),
+ new AudioFormat(8000.0f, 8, 1, false, false), 2000); //
+ AudioFormat format = ais.getFormat();
+ DataLine.Info info = new DataLine.Info(Clip.class, format,
+ ((int) ais.getFrameLength()
+ * format
+ .getFrameSize()));
+ Clip clip = (Clip) AudioSystem.getLine(info);
+ clip.open();
+ FloatControl rateControl = (FloatControl) clip.getControl(
+ FloatControl.Type.SAMPLE_RATE);
+ int c = 0;
+ while (c++ < 10) {
+ clip.stop();
+ clip.setFramePosition(0);
+ clip.start();
+ for (float frq = 22000; frq < 44100; frq = frq + 100) {
+ try {
+ Thread.currentThread().sleep(20);
+ } catch (Exception e) {
+ break;
+ }
+ rateControl.setValue(frq);
+ }
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ res = ex.getMessage().indexOf(
+ "This method should not have been invoked!") < 0;
+ }
+ if (res) {
+ System.out.println("Test passed");
+ } else {
+ System.out.println("Test failed");
+ throw new Exception("Test failed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Clip/bug5070081.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2005, 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+
+/*
+ * @test
+ * @bug 5070081
+ * @summary Tests that javax.sound.sampled.Clip does not loses position through
+ * stop/start
+ * @key headful
+ */
+public class bug5070081 {
+
+ static AudioFormat format = new AudioFormat(22050, 8, 1, false, false);
+ // create a 3-second file
+ static byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * 3)];
+
+ static final int LOOP_COUNT = 5;
+
+ static boolean test() throws Exception {
+ DataLine.Info info = new DataLine.Info(Clip.class, format);
+ Clip clip = (Clip)AudioSystem.getLine(info);
+ clip.open(format, soundData, 0, soundData.length);
+
+ boolean bSuccess = true;
+
+ long nLengthMS = clip.getMicrosecondLength()/1000;
+
+ System.out.println(" Clip length:");
+ System.out.println(" frames: " + clip.getFrameLength());
+ System.out.println(" seconds: " + nLengthMS/1000.0);
+
+ clip.start(); // start playing
+ Thread.sleep(1000); // wait a sec
+ long time1 = System.currentTimeMillis();
+ long pos1 = clip.getFramePosition(); // store the position
+ System.out.println(" Position before stop: " + pos1);
+ clip.stop(); // and then stop
+ long pos2 = clip.getFramePosition(); // 2nd try
+ long time2 = System.currentTimeMillis();
+ System.out.println(" Position after stop: " + pos2);
+
+ System.out.println(" d(time): " + Math.abs(time2-time1) + " ms;"
+ + "d(clip pos): " + Math.abs(pos2 - pos1) + " ms.");
+
+ long nDerivation = Math.abs(pos2 - pos1) - Math.abs(time2-time1);
+ // add 50 ms for deviation (delay for stopping and errors due timer precision)
+ if (nDerivation > 50) {
+ System.out.println(" ERROR(1): The deviation is too much: " + nDerivation + " ms");
+ bSuccess = false;
+ }
+
+ Thread.sleep(1000);
+ clip.start(); // start again
+ Thread.sleep(100);
+ while(clip.isRunning()); // wait for the sound to finish
+
+ int nEndPos = clip.getFramePosition();
+ System.out.println(" Position at end: " + nEndPos);
+ if (nEndPos > clip.getFrameLength()) {
+ System.out.println(" ERROR(2): end position if out of range");
+ bSuccess = false;
+ }
+
+ clip.close();
+
+ return bSuccess;
+ }
+
+ public static void main(String[] args) throws Exception {
+ for (int count=1; count <= LOOP_COUNT; count++)
+ {
+ System.out.println("loop " + count + "/" + LOOP_COUNT);
+ if (!test())
+ {
+ System.out.println("Test FAILED");
+ throw new RuntimeException("Test FAILED.");
+ }
+ }
+
+ System.out.println("Test passed sucessfully");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Clip/bug6251460.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2005, 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+
+/**
+ * @test
+ * @bug 6251460 8047222
+ * @requires (os.family == "windows" | os.family == "mac")
+ * @summary Tests that JavaSound plays short sounds (less then 1 second)
+ */
+public class bug6251460 {
+ private static final class MutableBoolean {
+ public boolean value;
+
+ public MutableBoolean(boolean initialValue) {
+ value = initialValue;
+ }
+ }
+
+ // static helper routines
+ static long startTime = currentTimeMillis();
+ static long currentTimeMillis() {
+ return System.nanoTime() / 1000000L;
+ }
+ 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
+ + " " + s);
+ }
+
+
+ static private int countErrors = 0;
+ static private final int LOOP_COUNT = 30;
+
+ static AudioFormat format = new AudioFormat(8000, 16, 1, true, false);
+ // create a 250-ms clip
+ static byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * 0.25)];
+
+ static protected void test()
+ throws LineUnavailableException, InterruptedException {
+ DataLine.Info info = new DataLine.Info(Clip.class, format);
+ Clip clip = (Clip)AudioSystem.getLine(info);
+ final MutableBoolean clipStoppedEvent = new MutableBoolean(false);
+ clip.addLineListener(new LineListener() {
+ @Override
+ public void update(LineEvent event) {
+ if (event.getType() == LineEvent.Type.STOP) {
+ synchronized (clipStoppedEvent) {
+ clipStoppedEvent.value = true;
+ clipStoppedEvent.notifyAll();
+ }
+ }
+ }
+ });
+ clip.open(format, soundData, 0, soundData.length);
+
+ long lengthClip = clip.getMicrosecondLength() / 1000;
+ log("Clip length " + lengthClip + " ms");
+ log("Playing...");
+ for (int i=1; i<=LOOP_COUNT; i++) {
+ long startTime = currentTimeMillis();
+ log(" Loop " + i);
+ clip.start();
+
+ synchronized (clipStoppedEvent) {
+ while (!clipStoppedEvent.value) {
+ clipStoppedEvent.wait();
+ }
+ clipStoppedEvent.value = false;
+ }
+
+ long endTime = currentTimeMillis();
+ long lengthPlayed = endTime - startTime;
+
+ if (lengthClip > lengthPlayed + 20) {
+ log(" ERR: Looks like sound didn't play: played " + lengthPlayed + " ms instead " + lengthClip);
+ countErrors++;
+ } else {
+ log(" OK: played " + lengthPlayed + " ms");
+ }
+ clip.setFramePosition(0);
+
+ }
+ log("Played " + LOOP_COUNT + " times, " + countErrors + " errors detected.");
+ }
+
+ public static void main(String[] args) throws InterruptedException {
+ try {
+ test();
+ } catch (LineUnavailableException | IllegalArgumentException
+ | IllegalStateException ignored) {
+ System.out.println("Test is not applicable. Automatically passed");
+ return;
+ }
+ if (countErrors > 0) {
+ throw new RuntimeException(
+ "Test FAILED: " + countErrors + " error detected (total "
+ + LOOP_COUNT + ")");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Controls/CompoundControl/ToString.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * 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.sampled.CompoundControl;
+import javax.sound.sampled.Control;
+
+/**
+ * @test
+ * @bug 4629190
+ * @summary CompoundControl: getMemberControls() and toString() throw
+ * NullPointerException
+ */
+public class ToString {
+ public static void main(String args[]) throws Exception {
+ System.out.println();
+ System.out.println();
+ System.out.println("4629190: CompoundControl: getMemberControls() and toString() throw NullPointerException");
+
+ String firstControlTypeName = "first_Control_Type_Name";
+ String secondControlTypeName = "second_Control_Type_Name";
+ String thirdControlTypeName = "third_Control_Type_Name";
+
+ Control.Type firstControlType = new TestControlType(firstControlTypeName);
+ Control.Type secondControlType = new TestControlType(secondControlTypeName);
+ Control.Type thirdControlType = new TestControlType(thirdControlTypeName);
+
+ Control firstControl = new TestControl(firstControlType);
+ Control secondControl = new TestControl(secondControlType);
+ Control thirdControl = new TestControl(thirdControlType);
+
+ String testCompoundControlTypeName = "CompoundControl_Type_Name";
+ CompoundControl.Type testCompoundControlType
+ = new TestCompoundControlType(testCompoundControlTypeName);
+
+ Control[] setControls = { firstControl, secondControl, thirdControl };
+ CompoundControl testedCompoundControl
+ = new TestCompoundControl(testCompoundControlType, setControls);
+
+ // this may throw exception if bug applies
+ Control[] producedControls = testedCompoundControl.getMemberControls();
+ System.out.println("Got "+producedControls.length+" member controls.");
+
+ // this may throw exception if bug applies
+ String producedString = testedCompoundControl.toString();
+ System.out.println("toString() returned: "+producedString);
+
+ System.out.println("Test passed.");
+ }
+
+}
+
+class TestControl extends Control {
+
+ TestControl(Control.Type type) {
+ super(type);
+ }
+}
+
+class TestControlType extends Control.Type {
+
+ TestControlType(String name) {
+ super(name);
+ }
+}
+
+class TestCompoundControl extends CompoundControl {
+
+ TestCompoundControl(CompoundControl.Type type, Control[] memberControls) {
+ super(type, memberControls);
+ }
+}
+
+class TestCompoundControlType extends CompoundControl.Type {
+
+ TestCompoundControlType(String name) {
+ super(name);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Controls/FloatControl/FloatControlBug.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2001, 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.FloatControl;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4385654
+ * @summary Check that the MASTER_GAIN control has a valid precision
+ */
+//public class test047 extends TRTest
+public class FloatControlBug {
+
+ private Clip theClip;
+
+ boolean testPassed = true;
+
+ private AudioFormat.Encoding theEncoding = AudioFormat.Encoding.PCM_SIGNED;
+
+ private float theSampleRate = 44100;
+
+ private int theSampleSize = 16;
+
+ private int theNumberOfChannels = 1;
+
+ private int theFrameSize = 2;
+
+ private float theFrameRate = 44100;
+
+ private boolean isBigEndian = false;
+
+ //_______________________________________________
+ // Method: runTest
+ //_______________________________________________
+ public boolean runTest() {
+ AudioInputStream theAudioInputStream = new AudioInputStream(
+ new ByteArrayInputStream(new byte[0]),
+ new AudioFormat(44100.0f, 16, 2, true, false), 441000);
+
+ AudioFormat theAudioFormat = theAudioInputStream.getFormat();
+
+ DataLine.Info info = new DataLine.Info(Clip.class, theAudioFormat,
+ AudioSystem.NOT_SPECIFIED);
+ try {
+ theClip = (Clip) AudioSystem.getLine(info);
+ theClip.open(theAudioInputStream);
+ FloatControl theFloatControl = (FloatControl) (theClip.getControl(
+ FloatControl.Type.MASTER_GAIN));
+ float theFloatControlPrecision = theFloatControl.getPrecision();
+ System.out.println(
+ "theFloatControlPrecision: " + theFloatControlPrecision);
+ System.out.println("Minimum: " + theFloatControl.getMinimum());
+ System.out.println("Maximum: " + theFloatControl.getMaximum());
+ System.out.println("Value : " + theFloatControl.getValue());
+ testPassed = theFloatControlPrecision > 0;
+ } catch (LineUnavailableException e) {
+ e.printStackTrace();
+ testPassed = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ testPassed = false;
+ }
+ return testPassed;
+ }
+
+ //_______________________________________________
+ // Method: main
+ //_______________________________________________
+ public static void main(String[] args) throws Exception {
+ //test047 thisTest = new test047();
+ if (isSoundcardInstalled()) {
+ FloatControlBug thisTest = new FloatControlBug();
+ boolean testResult = thisTest.runTest();
+ if (testResult) {
+ System.out.println("Test passed");
+ } else {
+ System.out.println("Test failed");
+ throw new Exception("Test failed");
+ }
+ }
+ }
+
+ /**
+ * Returns true if at least one soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: " + e);
+ }
+ 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/sampled/DataLine/DataLineInfoNegBufferSize.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,135 @@
+/*
+ * 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 javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 5021234
+ * @summary Using -2 for buffer size will fail retrieval of lines
+ */
+public class DataLineInfoNegBufferSize {
+
+ /**
+ * returns:
+ * 0: OK
+ * 1: IAE
+ * 2: other exception
+ * 3: line not available
+ */
+ public static int run(Mixer m, int bufferSize) {
+ int res;
+ int frameCount = 441000; // lets say 10 seconds
+ AudioFormat f = new AudioFormat(44100.0f, 16, 2, true, false);
+ Clip clip = null;
+ try {
+ System.out.println("Requesting clip from Mixer "
+ +(m==null?"default":m.toString())
+ +" with bufferSize"+bufferSize);
+ DataLine.Info info = new DataLine.Info(Clip.class, f, bufferSize);
+ if (m==null) {
+ clip = (Clip) AudioSystem.getLine(info);
+ } else {
+ clip = (Clip) m.getLine(info);
+ }
+ System.out.println("Got clip: "+clip+" with Buffer size "+clip.getBufferSize());
+
+ res = 0;
+ } catch (LineUnavailableException luae) {
+ System.out.println(luae);
+ res = 3; // line not available
+ } catch (IllegalArgumentException iae) {
+ System.out.println(iae);
+ res = 1;
+ } catch (Throwable t) {
+ System.out.println("->Exception:"+t);
+ t.printStackTrace();
+ res=2; // other exception
+ }
+ return res;
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (isSoundcardInstalled()) {
+ int res=0;
+ int count = 0;
+ Mixer.Info[] infos = AudioSystem.getMixerInfo();
+ for (int i = -1; i<infos.length; i++) {
+ try {
+ Mixer m;
+ if (i == -1) {
+ m = null;
+ } else {
+ m = AudioSystem.getMixer(infos[i]);
+ }
+ int r = run(m, AudioSystem.NOT_SPECIFIED);
+ // only continue if successful
+ if (r == 0) {
+ count++;
+ r = run(m, -2);
+ if (r == 1) {
+ // only fail if IAE was thrown
+ System.out.println("#FAILED: using -2 for buffer size does not work!");
+ res = 1;
+ }
+ }
+ } catch (Exception e) {
+ }
+ }
+ if (res!=1) {
+ System.out.println("Test passed");
+ } else {
+ if (count == 0) {
+ System.err.println("Test could not execute -- no suitable mixers installed. NOT failed");
+ }
+ throw new Exception("Test FAILED!");
+ }
+ }
+ }
+
+ /**
+ * Returns true if at least one soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: "+e);
+ }
+ 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/sampled/DataLine/LineDefFormat.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,172 @@
+/*
+ * 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 javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 5053380
+ * @summary Verify that getting a line initializes it with the format in
+ * DataLine.Info
+ */
+public class LineDefFormat {
+
+ final static int samplerate = 22050;
+ static int passed = 0;
+ static int failed = 0;
+
+ private static void doLine1(DataLine line, AudioFormat format) {
+ try {
+ System.out.println(" - got line: "+line);
+ System.out.println(" - line has format: "+line.getFormat());
+ if (!line.getFormat().matches(format)) {
+ System.out.println(" ## Error: expected this format: "+format);
+ failed++;
+ } else {
+ passed++;
+ }
+ } catch (Throwable t) {
+ System.out.println(" - Caught exception. Not failed.");
+ System.out.println(" - "+t.toString());
+ }
+ }
+
+ private static void doLine2(DataLine line, AudioFormat format) {
+ try {
+ System.out.println(" - call to open()");
+ line.open();
+ try {
+ System.out.println(" - line has format: "+line.getFormat());
+ if (!line.getFormat().matches(format)) {
+ System.out.println("## Error: expected this format: "+format);
+ failed++;
+ } else {
+ passed++;
+ }
+ } finally {
+ line.close();
+ System.out.println(" - closed");
+ }
+ } catch (Throwable t) {
+ System.out.println(" - Caught exception. Not failed.");
+ System.out.println(" - "+t.toString());
+ }
+ }
+
+ private static void doMixerClip(Mixer mixer, AudioFormat format) {
+ if (mixer==null) return;
+ try {
+ System.out.println("Clip from mixer "+mixer+":");
+ System.out.println(" "+mixer.getMixerInfo());
+ DataLine.Info info = new DataLine.Info(
+ Clip.class,
+ format);
+
+ if (mixer.isLineSupported(info)) {
+ Clip clip = (Clip) mixer.getLine(info);
+ doLine1(clip, format);
+ } else {
+ System.out.println(" - Line not supported");
+ }
+ } catch (Throwable t) {
+ System.out.println(" - Caught exception. Not failed.");
+ System.out.println(" - "+t.toString());
+ }
+ }
+
+ private static void doMixerSDL(Mixer mixer, AudioFormat format) {
+ if (mixer==null) return;
+ try {
+ System.out.println("SDL from mixer "+mixer+":");
+ DataLine.Info info = new DataLine.Info(
+ SourceDataLine.class,
+ format);
+
+ if (mixer.isLineSupported(info)) {
+ SourceDataLine sdl = (SourceDataLine) mixer.getLine(info);
+ doLine1(sdl, format);
+ doLine2(sdl, format);
+ } else {
+ System.out.println(" - Line not supported");
+ }
+ } catch (Throwable t) {
+ System.out.println(" - Caught exception. Not failed.");
+ System.out.println(" - "+t.toString());
+ }
+ }
+
+ private static void doMixerTDL(Mixer mixer, AudioFormat format) {
+ if (mixer==null) return;
+ try {
+ System.out.println("TDL from mixer "+mixer+":");
+ DataLine.Info info = new DataLine.Info(
+ TargetDataLine.class,
+ format);
+ if (mixer.isLineSupported(info)) {
+ TargetDataLine tdl = (TargetDataLine) mixer.getLine(info);
+ doLine1(tdl, format);
+ doLine2(tdl, format);
+ } else {
+ System.out.println(" - Line not supported");
+ }
+ } catch (Throwable t) {
+ System.out.println(" - Caught exception. Not failed.");
+ System.out.println(" - "+t.toString());
+ }
+ }
+
+ private static void doAll() throws Exception {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ AudioFormat pcm;
+ for (int i=0; i<mixers.length; i++) {
+ Mixer mixer = AudioSystem.getMixer(mixers[i]);
+ pcm = new AudioFormat(samplerate, 16, 1, true, false);
+ doMixerClip(mixer, pcm);
+ pcm = new AudioFormat(samplerate, 8, 1, false, false);
+ doMixerSDL(mixer, pcm);
+ pcm = new AudioFormat(samplerate, 16, 2, true, true);
+ doMixerTDL(mixer, pcm);
+ }
+ if (mixers.length==0) {
+ System.out.println("No mixers available!");
+ }
+
+ }
+
+ public static void main(String args[]) throws Exception{
+ doAll();
+ if (passed==0 && failed==0) {
+ System.out.println("Could not execute any of the tests. Test NOT failed.");
+ } else if (failed == 0) {
+ System.out.println("Test PASSED.");
+ } else {
+ throw new Exception("Test FAILED!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/DataLine/LongFramePosition.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * 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 javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 5049129
+ * @summary DataLine.getLongFramePosition
+ * @key headful
+ */
+public class LongFramePosition {
+
+ public static void main(String[] args) throws Exception {
+ boolean failed = false;
+ try {
+ AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false);
+ SourceDataLine sdl = AudioSystem.getSourceDataLine(format);
+ try {
+ sdl.open(format);
+ sdl.start();
+ sdl.write(new byte[16384], 0, 16384);
+ Thread.sleep(1000);
+ int intPos = sdl.getFramePosition();
+ long longPos = sdl.getLongFramePosition();
+ System.out.println("After 1 second: getFramePosition() = "+intPos);
+ System.out.println(" getLongFramePosition() = "+longPos);
+ if (intPos <= 0 || longPos <= 0) {
+ failed = true;
+ System.out.println("## FAILED: frame position did not advance, or negative!");
+ }
+ if (Math.abs(intPos - longPos) > 100) {
+ failed = true;
+ System.out.println("## FAILED: frame positions are not the same!");
+ }
+ } finally {
+ sdl.close();
+ }
+ } catch(LineUnavailableException e){
+ System.out.println(e);
+ System.out.println("Cannot execute test.");
+ return;
+ }
+ if (failed) throw new Exception("Test FAILED!");
+ System.out.println("Test Passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/DirectAudio/TickAtEndOfPlay.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * 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 javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 5001959
+ * @summary Short tick sound after finished playing with SourceDataLine
+ * @run main/manual TickAtEndOfPlay
+ */
+public class TickAtEndOfPlay {
+
+ static boolean WorkAround1 = false;
+ static boolean WorkAround2 = false;
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("This test should only be run on Windows.");
+ System.out.println("Make sure that the speakers are connected and the volume is up.");
+ System.out.println("Close all other programs that may use the soundcard.");
+
+ System.out.println("You'll hear a 2-second tone. when the tone finishes,");
+ System.out.println(" there should be no noise. If you hear a short tick/noise,");
+ System.out.println(" the bug still applies.");
+
+ System.out.println("Press ENTER to continue.");
+ System.in.read();
+
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].equals("1")) WorkAround1 = true;
+ if (args[i].equals("2")) WorkAround2 = true;
+ }
+ if (WorkAround1) System.out.println("Using work around1: appending silence");
+ if (WorkAround2) System.out.println("Using work around2: waiting before close");
+
+ int zerolen = 0; // how many 0-bytes will be appended to playback
+ if (WorkAround1) zerolen = 1000;
+ int seconds = 2;
+ int sampleRate = 8000;
+ double frequency = 1000.0;
+ double RAD = 2.0 * Math.PI;
+ AudioFormat af = new AudioFormat((float)sampleRate,8,1,true,true);
+ System.out.println("Format: "+af);
+ DataLine.Info info = new DataLine.Info(SourceDataLine.class,af);
+ SourceDataLine source = (SourceDataLine)AudioSystem.getLine(info);
+ System.out.println("Line: "+source);
+ if (source.toString().indexOf("MixerSourceLine")>=0) {
+ System.out.println("This test only applies to non-Java Sound Audio Engine!");
+ return;
+ }
+ System.out.println("Opening...");
+ source.open(af);
+ System.out.println("Starting...");
+ source.start();
+ int datalen = sampleRate * seconds;
+ byte[] buf = new byte[datalen+zerolen];
+ for (int i=0; i<datalen; i++) {
+ buf[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+ }
+ System.out.println("Writing...");
+ source.write(buf,0,buf.length);
+ System.out.println("Draining...");
+ source.drain();
+ System.out.println("Stopping...");
+ source.stop();
+ if (WorkAround2) {
+ System.out.println("Waiting 200 millis...");
+ Thread.sleep(200);
+ }
+ System.out.println("Closing...");
+ source.close();
+ System.out.println("Done.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/DirectAudio/bug6372428.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,381 @@
+/*
+ * 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 javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/*
+ * @test
+ * @bug 6372428
+ * @summary playback and capture doesn't interrupt after terminating thread that
+ * calls start()
+ * @run main bug6372428
+ * @key headful
+ */
+public class bug6372428 {
+ public bug6372428() {
+ }
+
+ public static void main(final String[] args) {
+ bug6372428 pThis = new bug6372428();
+ boolean failed1 = false;
+ boolean failed2 = false;
+ log("");
+ log("****************************************************************");
+ log("*** Playback Test");
+ log("****************************************************************");
+ log("");
+ try {
+ pThis.testPlayback();
+ } catch (IllegalArgumentException | LineUnavailableException e) {
+ System.out.println("Playback test is not applicable. Skipped");
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ failed1 = true;
+ }
+ log("");
+ log("");
+ log("****************************************************************");
+ log("*** Capture Test");
+ log("****************************************************************");
+ log("");
+ try {
+ pThis.testRecord();
+ } catch (IllegalArgumentException | LineUnavailableException e) {
+ System.out.println("Record test is not applicable. Skipped");
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ failed2 = true;
+ }
+ log("");
+ log("");
+ log("****************************************************************");
+ if (failed1 || failed2) {
+ String s = "";
+ if (failed1 && failed2)
+ s = "playback and capture";
+ else if (failed1)
+ s = "playback only";
+ else
+ s = "capture only";
+ throw new RuntimeException("Test FAILED (" + s + ")");
+ }
+ log("*** All tests passed successfully.");
+ }
+
+ final static int DATA_LENGTH = 15; // in seconds
+ final static int PLAYTHREAD_DELAY = 5; // in seconds
+
+ // playback test classes/routines
+
+ class PlayThread extends Thread {
+ SourceDataLine line;
+ public PlayThread(SourceDataLine line) {
+ this.line = line;
+ this.setDaemon(true);
+ }
+
+ public void run() {
+ log("PlayThread: starting...");
+ line.start();
+ log("PlayThread: delaying " + (PLAYTHREAD_DELAY * 1000) + "ms...");
+ delay(PLAYTHREAD_DELAY * 1000);
+ log("PlayThread: exiting...");
+ }
+ }
+
+ class WriteThread extends Thread {
+ SourceDataLine line;
+ byte[] data;
+ volatile int remaining;
+ volatile boolean stopRequested = false;
+ public WriteThread(SourceDataLine line, byte[] data) {
+ this.line = line;
+ this.data = data;
+ remaining = data.length;
+ this.setDaemon(true);
+ }
+
+ public void run() {
+ while (remaining > 0 && !stopRequested) {
+ int avail = line.available();
+ if (avail > 0) {
+ if (avail > remaining)
+ avail = remaining;
+ int written = line.write(data, data.length - remaining, avail);
+ remaining -= written;
+ log("WriteThread: " + written + " bytes written");
+ } else {
+ delay(100);
+ }
+ }
+ if (remaining == 0) {
+ log("WriteThread: all data has been written, draining");
+ line.drain();
+ } else {
+ log("WriteThread: stop requested");
+ }
+ log("WriteThread: stopping");
+ line.stop();
+ log("WriteThread: exiting");
+ }
+
+ public boolean isCompleted() {
+ return (remaining <= 0);
+ }
+
+ public void requestStop() {
+ stopRequested = true;
+ }
+ }
+
+ void testPlayback() throws LineUnavailableException {
+ // prepare audio data
+ AudioFormat format = new AudioFormat(22050, 8, 1, false, false);
+ byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * DATA_LENGTH)];
+
+ // create & open source data line
+ //SourceDataLine line = AudioSystem.getSourceDataLine(format);
+ DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+ SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info);
+
+ line.open(format);
+
+ // start write data thread
+ WriteThread p1 = new WriteThread(line, soundData);
+ p1.start();
+
+ // start line
+ PlayThread p2 = new PlayThread(line);
+ p2.start();
+
+ // monitor line
+ long lineTime1 = line.getMicrosecondPosition() / 1000;
+ long realTime1 = currentTimeMillis();
+ while (true) {
+ delay(500);
+ if (!line.isActive()) {
+ log("audio data played completely");
+ break;
+ }
+ long lineTime2 = line.getMicrosecondPosition() / 1000;
+ long realTime2 = currentTimeMillis();
+ long dLineTime = lineTime2 - lineTime1;
+ long dRealTime = realTime2 - realTime1;
+ log("line pos: " + lineTime2 + "ms" + ", thread is " + (p2.isAlive() ? "alive" : "DIED"));
+ if (dLineTime < 0) {
+ throw new RuntimeException("ERROR: line position have decreased from " + lineTime1 + " to " + lineTime2);
+ }
+ if (dRealTime < 450) {
+ // delay() has been interrupted?
+ continue;
+ }
+ lineTime1 = lineTime2;
+ realTime1 = realTime2;
+ }
+ }
+
+
+ // recording test classes/routines
+
+ class RecordThread extends Thread {
+ TargetDataLine line;
+ public RecordThread(TargetDataLine line) {
+ this.line = line;
+ this.setDaemon(true);
+ }
+
+ public void run() {
+ log("RecordThread: starting...");
+ line.start();
+ log("RecordThread: delaying " + (PLAYTHREAD_DELAY * 1000) + "ms...");
+ delay(PLAYTHREAD_DELAY * 1000);
+ log("RecordThread: exiting...");
+ }
+ }
+
+ class ReadThread extends Thread {
+ TargetDataLine line;
+ byte[] data;
+ volatile int remaining;
+ public ReadThread(TargetDataLine line, byte[] data) {
+ this.line = line;
+ this.data = data;
+ remaining = data.length;
+ this.setDaemon(true);
+ }
+
+ public void run() {
+ log("ReadThread: buffer size is " + data.length + " bytes");
+ delay(200);
+ while ((remaining > 0) && line.isOpen()) {
+ int avail = line.available();
+ if (avail > 0) {
+ if (avail > remaining)
+ avail = remaining;
+ int read = line.read(data, data.length - remaining, avail);
+ remaining -= read;
+ log("ReadThread: " + read + " bytes read");
+ } else {
+ delay(100);
+ }
+ if (remaining <= 0) {
+ log("ReadThread: record buffer is full, exiting");
+ break;
+ }
+ }
+ if (remaining > 0) {
+ log("ReadThread: line has been stopped, exiting");
+ }
+ }
+
+ public int getCount() {
+ return data.length - remaining;
+ }
+ public boolean isCompleted() {
+ return (remaining <= 0);
+ }
+ }
+
+ void testRecord() throws LineUnavailableException {
+ // prepare audio data
+ AudioFormat format = new AudioFormat(22050, 8, 1, false, false);
+
+ // create & open target data line
+ //TargetDataLine line = AudioSystem.getTargetDataLine(format);
+ DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
+ TargetDataLine line = (TargetDataLine)AudioSystem.getLine(info);
+
+ line.open(format);
+
+ // start read data thread
+ byte[] data = new byte[(int) (format.getFrameRate() * format.getFrameSize() * DATA_LENGTH)];
+ ReadThread p1 = new ReadThread(line, data);
+ p1.start();
+
+ // start line
+ //new RecordThread(line).start();
+ RecordThread p2 = new RecordThread(line);
+ p2.start();
+
+ // monitor line
+ long endTime = currentTimeMillis() + DATA_LENGTH * 1000;
+
+ long realTime1 = currentTimeMillis();
+ long lineTime1 = line.getMicrosecondPosition() / 1000;
+
+ while (realTime1 < endTime && !p1.isCompleted()) {
+ delay(100);
+ long lineTime2 = line.getMicrosecondPosition() / 1000;
+ long realTime2 = currentTimeMillis();
+ long dLineTime = lineTime2 - lineTime1;
+ long dRealTime = realTime2 - realTime1;
+ log("line pos: " + lineTime2 + "ms" + ", thread is " + (p2.isAlive() ? "alive" : "DIED"));
+ if (dLineTime < 0) {
+ line.stop();
+ line.close();
+ throw new RuntimeException("ERROR: line position have decreased from " + lineTime1 + " to " + lineTime2);
+ }
+ if (dRealTime < 450) {
+ // delay() has been interrupted?
+ continue;
+ }
+ lineTime1 = lineTime2;
+ realTime1 = realTime2;
+ }
+ log("stopping line...");
+ line.stop();
+ line.close();
+
+ /*
+ log("");
+ log("");
+ log("");
+ log("recording completed, delaying 5 sec");
+ log("recorded " + p1.getCount() + " bytes, " + DATA_LENGTH + " seconds: " + (p1.getCount() * 8 / DATA_LENGTH) + " bit/sec");
+ log("");
+ log("");
+ log("");
+ delay(5000);
+ log("starting playing...");
+ playRecorded(format, data);
+ */
+ }
+
+ void playRecorded(AudioFormat format, byte[] data) throws Exception {
+ //SourceDataLine line = AudioSystem.getSourceDataLine(format);
+ DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+ SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info);
+
+ line.open();
+ line.start();
+
+ int remaining = data.length;
+ while (remaining > 0) {
+ int avail = line.available();
+ if (avail > 0) {
+ if (avail > remaining)
+ avail = remaining;
+ int written = line.write(data, data.length - remaining, avail);
+ remaining -= written;
+ log("Playing: " + written + " bytes written");
+ } else {
+ delay(100);
+ }
+ }
+
+ line.drain();
+ line.stop();
+ }
+
+ // 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) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/FileTypeExtension/FileTypeExtensionTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * 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
+ * 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.sampled.AudioFileFormat;
+
+/**
+ * @test
+ * @bug 4300529
+ * @summary Filename extension test. The filename extensions for file types
+ * AIFF-C, SND, and WAVE should not include a ".".
+ */
+public class FileTypeExtensionTest {
+
+ public static void main(String[] args) throws Exception {
+
+ AudioFileFormat.Type[] types = { AudioFileFormat.Type.AIFC,
+ AudioFileFormat.Type.AIFF,
+ AudioFileFormat.Type.AU,
+ AudioFileFormat.Type.SND,
+ AudioFileFormat.Type.WAVE };
+
+ boolean failed = false;
+
+ System.out.println("\nDefined file types and extensions:");
+
+ for (int i = 0; i < types.length; i++) {
+ System.out.println("\n");
+ System.out.println(" file type: " + types[i]);
+ System.out.println(" extension: " + types[i].getExtension());
+ if( types[i].getExtension().charAt(0) == '.' ) {
+ failed = true;
+ }
+ }
+
+ if (failed) {
+ System.err.println("Failed!");
+ throw new Exception("File type extensions begin with .");
+ } else {
+ System.err.println("Passed!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/LineEvent/LineInfoNPE.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,177 @@
+/*
+ * 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.sampled.Control;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+
+/**
+ * @test
+ * @bug 4672865
+ * @summary LineEvent.toString() throws unexpected NullPointerException
+ */
+public class LineInfoNPE {
+
+ static final int STATUS_PASSED = 0;
+ static final int STATUS_FAILED = 2;
+ static final int STATUS_TEMP = 95;
+
+ public static void main(String argv[]) throws Exception {
+ int testExitStatus = run(argv, System.out);
+ if (testExitStatus != STATUS_PASSED) {
+ throw new Exception("test FAILED!");
+ }
+ }
+
+ public static int run(String argv[], java.io.PrintStream out) {
+ int testResult = STATUS_PASSED;
+
+ out.println("\n==> Test for LineEvent class:");
+
+ Line testLine = new TestLine();
+ Line nullLine = null;
+
+ LineEvent.Type testLineEventType = LineEvent.Type.OPEN;
+ LineEvent.Type nullLineEventType = null;
+
+ LineEvent testedLineEvent = null;
+ out.println("\n>> LineEvent constructor for Line = null: ");
+ try {
+ testedLineEvent =
+ new LineEvent(nullLine, // the source Line of this event
+ testLineEventType, // LineEvent.Type - the event type
+ (long) 1000 // position - the number processed of sample frames
+ );
+ out.println("> No any Exception was thrown!");
+ out.println("> testedLineEvent.getType():");
+ try {
+ Line producedLine = testedLineEvent.getLine();
+ out.println("> PASSED: producedLine = " + producedLine);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ out.println("> testedLineEvent.toString():");
+ try {
+ String producedString = testedLineEvent.toString();
+ out.println("> PASSED: producedString = " + producedString);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ } catch (IllegalArgumentException illegArgExcept) {
+ out.println("> PASSED: expected IllegalArgumentException was thrown:");
+ illegArgExcept.printStackTrace(out);
+ } catch (NullPointerException nullPE) {
+ out.println("> PASSED: expected NullPointerException was thrown:");
+ nullPE.printStackTrace(out);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+
+ out.println("\n>> LineEvent constructor for LineEvent.Type = null: ");
+ try {
+ testedLineEvent =
+ new LineEvent(testLine, // the source Line of this event
+ nullLineEventType, // LineEvent.Type - the event type
+ (long) 1000 // position - the number processed of sample frames
+ );
+ out.println("> No any Exception was thrown!");
+ out.println("> testedLineEvent.getType():");
+ try {
+ LineEvent.Type producedType = testedLineEvent.getType();
+ out.println("> PASSED: producedType = " + producedType);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ out.println("> testedLineEvent.toString():");
+ try {
+ String producedString = testedLineEvent.toString();
+ out.println("> PASSED: producedString = " + producedString);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ } catch (IllegalArgumentException illegArgExcept) {
+ out.println("> PASSED: expected IllegalArgumentException was thrown:");
+ illegArgExcept.printStackTrace(out);
+ } catch (NullPointerException nullPE) {
+ out.println("> PASSED: expected NullPointerException was thrown:");
+ nullPE.printStackTrace(out);
+ } catch (Throwable thrown) {
+ out.println("## FAILED: unexpected Exception was thrown:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+
+ if ( testResult == STATUS_FAILED ) {
+ out.println("\n==> test FAILED!");
+ } else {
+ out.println("\n==> test PASSED!");
+ }
+ return testResult;
+ }
+} // end of test class
+
+class TestLine implements Line {
+
+ public void addLineListener(LineListener listener) {
+ }
+
+ public void close() {
+ }
+
+ public Control getControl(Control.Type control) {
+ return null;
+ }
+
+ public Control[] getControls() {
+ return new Control[0];
+ }
+
+ public Line.Info getLineInfo() {
+ return null;
+ }
+
+ public boolean isOpen() {
+ return false;
+ }
+
+ public boolean isControlSupported(Control.Type control) {
+ return false;
+ }
+
+ public void open() {
+ }
+
+ public void removeLineListener(LineListener listener) {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Lines/16and32KHz/Has16and32KHz.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2001, 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 4479441
+ * @summary Verify that the lines report 16KHz and 32KHz capability
+ */
+public class Has16and32KHz {
+
+ public static boolean ok32=false;
+ public static boolean ok16=false;
+
+ public static void showMixerLines(Line.Info[] lineinfo) {
+ for (int j = 0; j < lineinfo.length; j++) {
+ boolean isSDL=false; // SourceDataLine
+ Line.Info thisInfo=lineinfo[j];
+ System.out.println(" " + thisInfo);
+ String impl="";
+ if (thisInfo.getLineClass().equals(SourceDataLine.class)) {
+ isSDL=true;
+ impl+="SourceDataLine";
+ }
+ if (thisInfo.getLineClass().equals(Clip.class)) {
+ impl+="Clip";
+ }
+ if (thisInfo.getLineClass().equals(DataLine.class)) {
+ impl+="DataLine";
+ }
+ if (thisInfo.getLineClass().equals(TargetDataLine.class)) {
+ impl+="TargetDataLine";
+ }
+ if (thisInfo.getLineClass().equals(Mixer.class)) {
+ impl+="Mixer";
+ }
+ System.out.println(" implements "+impl);
+ try {
+ AudioFormat[] formats = ((DataLine.Info)lineinfo[j]).getFormats();
+ for (int k = 0; k < formats.length; k++) {
+ System.out.println(" " + formats[k] + ", "+ formats[k].getFrameSize()+" bytes/frame");
+ if (isSDL) {
+ if ((formats[k].getSampleRate()==AudioSystem.NOT_SPECIFIED)
+ || (formats[k].getSampleRate()==32000.0f)) {
+ ok32=true;
+ }
+ if ((formats[k].getSampleRate()==AudioSystem.NOT_SPECIFIED)
+ || (formats[k].getSampleRate()==16000.0f)) {
+ ok16=true;
+ }
+ }
+ }
+ } catch (ClassCastException e) {
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ boolean res=true;
+
+ Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
+ System.out.println(mixerInfo.length+" mixers on system.");
+ if (mixerInfo.length == 0) {
+ System.out.println("Cannot execute test. Not Failed!");
+ } else {
+ for (int i = 0; i < mixerInfo.length; i++) {
+ Mixer mixer = AudioSystem.getMixer(mixerInfo[i]);
+ System.out.println();
+ System.out.println(mixer+":");
+ showMixerLines(mixer.getSourceLineInfo());
+ showMixerLines(mixer.getTargetLineInfo());
+
+
+ }
+ res=ok16 && ok32;
+ }
+ if (res) {
+ System.out.println("Test passed");
+ } else {
+ System.out.println("Test failed");
+ throw new Exception("Test failed");
+ }
+ //ystem.exit(res?0:1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Lines/BufferSizeCheck.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4661602
+ * @summary Buffersize is checked when re-opening line
+ */
+public class BufferSizeCheck {
+
+ public static void main(String[] args) throws Exception {
+ boolean realTest = false;
+ if (!isSoundcardInstalled()) {
+ return;
+ }
+
+ try {
+ out("4661602: Buffersize is checked when re-opening line");
+ AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+ DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+ SourceDataLine sdl = (SourceDataLine) AudioSystem.getLine(info);
+ out("Opening with buffersize 12000...");
+ sdl.open(format, 12000);
+ out("Opening with buffersize 11000...");
+ realTest=true;
+ sdl.open(format, 11000);
+ try {
+ sdl.close();
+ } catch(Throwable t) {}
+ } catch (Exception e) {
+ e.printStackTrace();
+ // do not fail if no audio device installed - bug 4742021
+ if (realTest || !(e instanceof LineUnavailableException)) {
+ throw e;
+ }
+ }
+ out("Test passed");
+ }
+
+ static void out(String s) {
+ System.out.println(s); System.out.flush();
+ }
+
+ /**
+ * Returns true if at least one soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: "+e);
+ }
+ 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/sampled/Lines/ChangingBuffer.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,165 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4515126
+ * @summary Verify that the buffer passed to SourceDataLine.write() and
+ * Clip.open() will not be changed
+ */
+public class ChangingBuffer {
+
+ final static int samplerate = 44100;
+ final static byte[] buffer = new byte[16384];
+ static int successfulTests = 0;
+
+ private static void makeBuffer() {
+ for (int i=0; i<buffer.length; i++) {
+ buffer[i] = (byte) (i % 128);
+ }
+ }
+
+ private static void checkBufferSDL() throws Exception {
+ successfulTests++;
+ for (int i=0; i<buffer.length; i++) {
+ if (buffer[i] != ((byte) (i % 128))) {
+ throw new Exception("Buffer was changed by SourceDataLine.write()!. Test FAILED");
+ }
+ }
+ System.out.println(" -> passed for this line");
+ System.out.println("");
+ }
+
+ private static void checkBufferClip() throws Exception {
+ for (int i=0; i<buffer.length; i++) {
+ if (buffer[i] != (i % 128)) {
+ throw new Exception("Buffer was changed by Clip.open()!. Test FAILED");
+ }
+ }
+ System.out.println(" -> passed for this clip");
+ System.out.println("");
+ }
+
+ private static boolean doMixerClip(Mixer mixer, AudioFormat format) {
+ if (mixer==null) return false;
+ try {
+ System.out.println("Trying mixer "+mixer+":");
+ DataLine.Info info = new DataLine.Info(
+ Clip.class,
+ format,
+ (int) samplerate);
+
+ Clip clip = (Clip) mixer.getLine(info);
+ System.out.println(" - got clip: "+clip);
+ System.out.println(" - open with format "+format);
+ clip.open(format, buffer, 0, buffer.length);
+ System.out.println(" - playing...");
+ clip.start();
+ System.out.println(" - waiting while it's active...");
+ while (clip.isActive())
+ Thread.sleep(100);
+ System.out.println(" - waiting 100millis");
+ Thread.sleep(100);
+ System.out.println(" - drain1");
+ clip.drain();
+ System.out.println(" - drain2");
+ clip.drain();
+ System.out.println(" - stop");
+ clip.stop();
+ System.out.println(" - close");
+ clip.close();
+ System.out.println(" - closed");
+ } catch (Throwable t) {
+ System.out.println(" - Caught exception. Not failed.");
+ System.out.println(" - "+t.toString());
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean doMixerSDL(Mixer mixer, AudioFormat format) {
+ if (mixer==null) return false;
+ try {
+ System.out.println("Trying mixer "+mixer+":");
+ DataLine.Info info = new DataLine.Info(
+ SourceDataLine.class,
+ format,
+ (int) samplerate);
+
+ SourceDataLine sdl = (SourceDataLine) mixer.getLine(info);
+ System.out.println(" - got sdl: "+sdl);
+ System.out.println(" - open with format "+format);
+ sdl.open(format);
+ System.out.println(" - start...");
+ sdl.start();
+ System.out.println(" - write...");
+ sdl.write(buffer, 0, buffer.length);
+ Thread.sleep(200);
+ System.out.println(" - drain...");
+ sdl.drain();
+ System.out.println(" - stop...");
+ sdl.stop();
+ System.out.println(" - close...");
+ sdl.close();
+ System.out.println(" - closed");
+ } catch (Throwable t) {
+ System.out.println(" - Caught exception. Not failed.");
+ System.out.println(" - "+t.toString());
+ return false;
+ }
+ return true;
+ }
+
+ private static void doAll(boolean bigEndian) throws Exception {
+ AudioFormat pcm = new AudioFormat(
+ AudioFormat.Encoding.PCM_SIGNED,
+ samplerate, 16, 1, 2, samplerate, bigEndian);
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ for (int i=0; i<mixers.length; i++) {
+ Mixer mixer = AudioSystem.getMixer(mixers[i]);
+ makeBuffer(); if (doMixerClip(mixer, pcm)) checkBufferClip();
+ makeBuffer(); if (doMixerSDL(mixer, pcm)) checkBufferSDL();
+ }
+ if (mixers.length==0) {
+ System.out.println("No mixers available!");
+ }
+
+ }
+
+ public static void main(String args[]) throws Exception{
+ doAll(true);
+ doAll(false);
+ if (successfulTests==0) {
+ System.out.println("Could not execute any of the tests. Test NOT failed.");
+ } else {
+ System.out.println("Test PASSED.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Lines/ClickInPlay/ClickInPlay.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,147 @@
+/*
+ * 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.IOException;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * This is utility class for Test4218609.
+ */
+public class ClickInPlay {
+
+ static int sampleRate = 8000;
+ static double frequency = 2000.0;
+ static double RAD = 2.0 * Math.PI;
+
+ static byte[] audioData = new byte[sampleRate/2];
+ static DataLine.Info info;
+ static Clip source;
+
+ //static AudioInputStream ais = null;
+ static AudioFormat audioFormat;
+ //static String filename;
+
+ public static void print(String s) {
+ System.out.print(s);
+ }
+ public static void println(String s) {
+ System.out.println(s);
+ }
+
+ public static void key() {
+ println("");
+ print("Press ENTER to continue...");
+ try {
+ System.in.read();
+ } catch (IOException ioe) {
+ }
+ }
+
+ public static void play(Mixer mixer) {
+ int res = 0;
+ try {
+ println("Getting clip from mixer...");
+ source = (Clip) mixer.getLine(info);
+ println("Opening clip...");
+ source.open(audioFormat, audioData, 0, audioData.length);
+ println("Starting clip...");
+ source.loop(Clip.LOOP_CONTINUOUSLY);
+ println("Now open your ears:");
+ println("- if you hear a sine wave playing,");
+ println(" listen carefully if you can hear clicks.");
+ println(" If no, the bug is fixed.");
+ println("- if you don't hear anything, it's possible");
+ println(" that this mixer is not connected to an ");
+ println(" amplifier, or that its volume is set to 0");
+ key();
+ } catch (IllegalArgumentException iae) {
+ println("IllegalArgumentException: "+iae.getMessage());
+ println("Sound device cannot handle this audio format.");
+ println("ERROR: Test environment not correctly set up.");
+ if (source!=null) {
+ source.close();
+ source = null;
+ }
+ return;
+ } catch (LineUnavailableException lue) {
+ println("LineUnavailableException: "+lue.getMessage());
+ println("This is normal for some mixers.");
+ } catch (Exception e) {
+ println("Unexpected Exception: "+e.toString());
+ }
+ if (source != null) {
+ println("Stopping...");
+ source.stop();
+ println("Closing...");
+ source.close();
+ println("Closed.");
+ source = null;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ println("This is an interactive test.");
+ println("If you can hear clicks during playback in");
+ println("any mixer, the test is failed.");
+ println("");
+ println("Make sure that you have speakers connected");
+ println("and that the system mixer is not muted.");
+ println("");
+ println("Press a key to start the test.");
+ key();
+ Mixer.Info[] mixers=null;
+
+ println(" ...using self-generated sine wave for playback");
+ audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
+ for (int i=0; i<audioData.length; i++) {
+ audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+ }
+ info = new DataLine.Info(Clip.class, audioFormat);
+
+ mixers = AudioSystem.getMixerInfo();
+ int succMixers = 0;
+ for (int i=0; i<mixers.length; i++) {
+ try {
+ Mixer mixer = AudioSystem.getMixer(mixers[i]);
+ if (mixer.isLineSupported(info)) {
+ succMixers++;
+ println(" ...using mixer "+mixer.getMixerInfo());
+ play(mixer);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ if (succMixers == 0) {
+ println("No mixers available! ");
+ println("Cannot run test.");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Lines/ClickInPlay/Test4218609.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,380 @@
+/*
+ * 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.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 4218609
+ * @summary A soft audio click is heard when playing some audio file
+ * @build ClickInPlay
+ * @run main/manual Test4218609
+ */
+public class Test4218609 {
+
+ private static void init() throws Exception {
+ //*** Create instructions for the user here ***
+
+ String[] instructions =
+ {
+ "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 ClickInPlay\".",
+ "4. Follow the instructions shown in the terminal window.",
+ "If no error occured during the test, and the java application ",
+ "in the termial exited successfully, 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" )
+ {
+ Test4218609.pass();
+ }
+ else
+ {
+ Test4218609.fail();
+ }
+ }
+
+ }// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Lines/ClipOpenException.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,148 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 4679187
+ * @summary Clip.open() throws unexpected Exceptions. verifies that clip,
+ * sourcedataline and targetdataline throw IllegalArgumentExcepotion if
+ * any field in the format is AudioFormat.NOT_SPECIFIED
+ */
+public class ClipOpenException {
+ static boolean failed = false;
+
+ static byte[] audioData = new byte[2048];
+ static AudioFormat[] formats = {
+ new AudioFormat(AudioSystem.NOT_SPECIFIED,
+ AudioSystem.NOT_SPECIFIED,
+ AudioSystem.NOT_SPECIFIED,
+ true, false),
+ new AudioFormat(0, 0, 0, true, false)
+ };
+ static AudioFormat infoFormat = new AudioFormat(44100.0f,
+ 16,
+ 1,
+ true, false);
+ static DataLine.Info clipInfo = new DataLine.Info(Clip.class, infoFormat);
+ static DataLine.Info sdlInfo = new DataLine.Info(SourceDataLine.class, infoFormat);
+ static DataLine.Info tdlInfo = new DataLine.Info(TargetDataLine.class, infoFormat);
+
+
+ public static void print(String s) {
+ System.out.print(s);
+ }
+ public static void println(String s) {
+ System.out.println(s);
+ }
+
+ public static void test(Line line) {
+ for (int format = 0; format < formats.length; format++) {
+ try {
+ println(" Opening the line with format "+(format+1));
+ if (line instanceof Clip) {
+ ((Clip) line).open(formats[format], audioData, 0, audioData.length);
+ } else
+ if (line instanceof SourceDataLine) {
+ ((SourceDataLine) line).open(formats[format]);
+ } else
+ if (line instanceof TargetDataLine) {
+ ((TargetDataLine) line).open(formats[format]);
+ } else {
+ println(" Unknown type of line: "+line.getClass());
+ return;
+ }
+ println(" No exception! not OK.");
+ failed = true;
+ } catch (IllegalArgumentException iae) {
+ println(" IllegalArgumentException: "+iae.getMessage());
+ println(" OK");
+ } catch (LineUnavailableException lue) {
+ println(" LineUnavailableException: "+lue.getMessage());
+ println(" Probably incorrect, but may happen if the test system is correctly set up.");
+ } catch (Exception e) {
+ println(" Unexpected Exception: "+e.toString());
+ println(" NOT OK!");
+ failed = true;
+ }
+ println(" Closing line.");
+ line.close();
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ int succMixers = 0;
+ println("Using formats: ");
+ for (int i = 0 ; i<formats.length; i++) {
+ println(""+(i+1)+". "+formats[i]);
+ }
+ for (int i=0; i<mixers.length; i++) {
+ boolean succ = false;
+ try {
+ Mixer mixer = AudioSystem.getMixer(mixers[i]);
+ println("Mixer "+mixer.getMixerInfo()+":");
+ if (mixer.isLineSupported(clipInfo)) {
+ println("Getting clip from mixer...");
+ Clip clip = (Clip) mixer.getLine(clipInfo);
+ succ = true;
+ test(clip);
+ }
+ if (mixer.isLineSupported(sdlInfo)) {
+ println("Getting source data line from mixer...");
+ SourceDataLine sdl = (SourceDataLine) mixer.getLine(sdlInfo);
+ succ = true;
+ test(sdl);
+ }
+ if (mixer.isLineSupported(tdlInfo)) {
+ println("Getting target data line from mixer...");
+ TargetDataLine tdl = (TargetDataLine) mixer.getLine(tdlInfo);
+ succ = true;
+ test(tdl);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (succ) {
+ succMixers++;
+ }
+ }
+ if (succMixers == 0) {
+ println("No mixers available! ");
+ println("Cannot run test. NOT FAILED");
+ }
+ else if (failed) {
+ throw new Exception("Test FAILED");
+ }
+ println("Test passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Lines/FrameSize/FrameSizeTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2001, 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4469409
+ * @summary Check that the frame size in the formats returned by lines is
+ * correct
+ */
+public class FrameSizeTest {
+ public static void main(String[] args) throws Exception {
+ boolean res=true;
+ Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
+ for (int i = 0; i < mixerInfo.length; i++) {
+ Mixer mixer = AudioSystem.getMixer(mixerInfo[i]);
+ System.out.println(mixer);
+ Line.Info[] lineinfo = mixer.getSourceLineInfo();
+ for (int j = 0; j < lineinfo.length; j++) {
+ System.out.println(" " + lineinfo[j]);
+ try {
+ AudioFormat[] formats = ((DataLine.Info)lineinfo[j]).getFormats();
+ for (int k = 0; k < formats.length; k++) {
+ if ( (formats[k].getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
+ || formats[k].getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED))
+ && (formats[k].getFrameSize() != AudioSystem.NOT_SPECIFIED)
+ && ((formats[k].getSampleSizeInBits() == 16) || (formats[k].getSampleSizeInBits() == 8))
+ && ((((formats[k].getSampleSizeInBits() + 7) / 8) * formats[k].getChannels()) != formats[k].getFrameSize())) {
+ System.out.println(" # " + formats[k] + ", getFrameSize() wrongly returns"+ formats[k].getFrameSize());
+ res=false;
+ }
+ }
+ } catch (ClassCastException e) {
+ }
+ }
+ }
+
+ if (res) {
+ System.out.println("Test passed");
+ } else {
+ System.out.println("Test failed");
+ throw new Exception("Test failed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Lines/GetLine.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,99 @@
+/*
+ * 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.sampled.AudioPermission;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4932835
+ * @summary REGRESSION: IAE for supported line in AudioSystem.getLine()
+ */
+public class GetLine {
+
+ static boolean isSoundAccessDenied = false;
+ static {
+ SecurityManager securityManager = System.getSecurityManager();
+ if (securityManager != null) {
+ try {
+ securityManager.checkPermission(new AudioPermission("*"));
+ } catch (SecurityException e) {
+ isSoundAccessDenied = true;
+ }
+ }
+ }
+
+ static final int STATUS_PASSED = 0;
+ static final int STATUS_FAILED = 2;
+ static final int STATUS_TEMP = 95;
+ static java.io.PrintStream log = System.err;
+
+ public static void main(String argv[]) throws Exception {
+ if (run(argv, System.out) == STATUS_FAILED) {
+ throw new Exception("Test FAILED");
+ }
+ System.out.println("Test passed.");
+ }
+
+ public static int run(String argv[], java.io.PrintStream out) {
+ String testCaseID = "LineListener2001";
+
+ log.println("===== " + testCaseID + " =====");
+
+ boolean failed = false;
+ Line l = null;
+
+
+
+ // get the default SourceDataLine
+
+ DataLine.Info s_info = new DataLine.Info(SourceDataLine.class, null);
+ Line.Info infos[] = AudioSystem.getSourceLineInfo( s_info );
+
+ if( infos.length < 1 ) {
+ log.println("Line.Info array == 0");
+ return STATUS_PASSED;
+ }
+ try {
+ l = AudioSystem.getLine(infos[0]);
+ } catch(SecurityException lue) {
+ log.println("SecurityException");
+ return STATUS_PASSED;
+ } catch (LineUnavailableException e1) {
+ log.println("LUE");
+ return STATUS_PASSED;
+ } catch (IllegalArgumentException iae) {
+ log.println("IllegalArgumentException should not be thrown "
+ + "for supported line");
+ iae.printStackTrace(log);
+ return STATUS_FAILED;
+ }
+ out.println("Passed.");
+ return STATUS_PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Lines/SDLwrite.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,271 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4680710
+ * @summary SourceDataLine.write() behavior is not correct for not open or not
+ * started lines
+ */
+public class SDLwrite {
+
+ static final int STATUS_PASSED = 0;
+ static final int STATUS_FAILED = 2;
+
+ public static void main(String argv[]) throws Exception {
+ int testExitStatus = run(argv, System.out);
+ if (testExitStatus != STATUS_PASSED) {
+ throw new Exception("test FAILED!");
+ }
+ }
+
+ public static int run(String argv[], java.io.PrintStream out) {
+ int testResult = STATUS_PASSED;
+
+ out.println
+ ("\n==> Test for SourceDataLine.write() method for not open and not started line:");
+
+ Mixer.Info[] installedMixersInfo = AudioSystem.getMixerInfo();
+
+ if ( installedMixersInfo == null ) {
+ out.println("## AudioSystem.getMixerInfo() returned unexpected result:");
+ out.println("# expected: an array of Mixer.Info objects (may be array of length 0);");
+ out.println("# produced: null;");
+ return STATUS_FAILED;
+ }
+
+ if ( installedMixersInfo.length == 0 ) {
+ // there are no mixers installed on the system - so this testcase can not be tested
+ return STATUS_PASSED;
+ }
+
+ Mixer testedMixer = null;
+ for (int i=0; i < installedMixersInfo.length; i++) {
+ try {
+ testedMixer = AudioSystem.getMixer(installedMixersInfo[i]);
+ } catch (SecurityException securityException) {
+ // installed Mixer is unavailable because of security restrictions
+ continue;
+ } catch (Throwable thrown) {
+ out.println("## AudioSystem.getMixer() threw unexpected exception:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ continue;
+ }
+
+ try {
+ testedMixer.open();
+ } catch (LineUnavailableException lineUnavailableException) {
+ // testedMixer is not available due to resource restrictions
+ continue;
+ } catch (SecurityException securityException) {
+ // testedMixer is not available due to security restrictions
+ continue;
+ } catch (Throwable thrown) {
+ out.println("## Mixer.open() threw unexpected exception:");
+ out.println("# Mixer = " + testedMixer);
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ continue;
+ }
+ Line.Info supportedSourceLineInfo[] = null;
+ try {
+ supportedSourceLineInfo = testedMixer.getSourceLineInfo();
+ } catch (Throwable thrown) {
+ out.println("## Mixer.getSourceLineInfo() threw unexpected exception:");
+ out.println("# Mixer = " + testedMixer);
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ testedMixer.close();
+ continue;
+ }
+ if ( supportedSourceLineInfo == null ) {
+ out.println("## Mixer.getSourceLineInfo() returned null array");
+ out.println("# Mixer = " + testedMixer);
+ testResult = STATUS_FAILED;
+ testedMixer.close();
+ continue;
+ }
+ out.println("\n>>> testedMixer["+i+"] = " + testedMixer);
+ out.println("\n>> supportedSourceLineInfo.length = " + supportedSourceLineInfo.length);
+
+ for (int j=0; j < supportedSourceLineInfo.length; j++) {
+ Line.Info testSourceLineInfo = supportedSourceLineInfo[j];
+
+ Line testSourceLine = null;
+ try {
+ testSourceLine = testedMixer.getLine(testSourceLineInfo);
+ } catch (LineUnavailableException lineUnavailableException) {
+ // line is not available due to resource restrictions
+ continue;
+ } catch (SecurityException securityException) {
+ // line is not available due to security restrictions
+ continue;
+ } catch (Throwable thrown) {
+ out.println("## Mixer.getLine(Line.Info) threw unexpected Exception:");
+ out.println("# Mixer = " + testedMixer);
+ out.println("# Line.Info = " + testSourceLineInfo);
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ continue;
+ }
+
+ out.println("\n> testSourceLineInfo["+j+"] = " + testSourceLineInfo);
+ out.println("> testSourceLine = " + testSourceLine);
+ if ( ! (testSourceLine instanceof SourceDataLine) ) {
+ out.println("> testSourceLine is not SourceDataLine");
+ continue;
+ }
+
+ SourceDataLine testedSourceLine = (SourceDataLine)testSourceLine;
+ AudioFormat lineAudioFormat = testedSourceLine.getFormat();
+
+ int bufferSizeToWrite = 1;
+ if ( lineAudioFormat.getSampleSizeInBits() != AudioSystem.NOT_SPECIFIED ) {
+ bufferSizeToWrite = lineAudioFormat.getSampleSizeInBits()/8;
+ if ( lineAudioFormat.getSampleSizeInBits()%8 != 0 ) {
+ bufferSizeToWrite++;
+ }
+ }
+ if ( lineAudioFormat.getFrameSize() != AudioSystem.NOT_SPECIFIED ) {
+ bufferSizeToWrite = lineAudioFormat.getFrameSize();
+ }
+ byte[] dataToWrite = new byte[bufferSizeToWrite];
+ for (int k=0; k < bufferSizeToWrite; k++) {
+ dataToWrite[k] = (byte)1;
+ }
+ int offsetToWrite = 0;
+
+ out.println
+ ("\n> check SourceDataLine.write() for not open line with correct length of data:");
+ int writtenBytes = -1;
+ try {
+ writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
+ out.println("> Bytes written: number of written bytes = " + writtenBytes);
+ } catch (Throwable thrown) {
+ out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
+ out.println("# Unexpected Exception is thrown");
+ out.println("# Mixer = " + testedMixer);
+ out.println("# SourceDataLine = " + testedSourceLine);
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+
+ out.println
+ ("\n> check SourceDataLine.write() for not open line with incorrect length of data:");
+ writtenBytes = -1;
+ bufferSizeToWrite--;
+ try {
+ writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
+ out.println("> Bytes written: number of written bytes = " + writtenBytes);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ out.println("> Permissible IllegalArgumentException for the present instance is thrown:");
+ illegalArgumentException.printStackTrace(out);
+ } catch (Throwable thrown) {
+ out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
+ out.println("# Unexpected Exception is thrown");
+ out.println("# Mixer = " + testedMixer);
+ out.println("# SourceDataLine = " + testedSourceLine);
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+
+ out.println
+ ("\n> open tested line:");
+ bufferSizeToWrite++;
+ try {
+ testedSourceLine.open(lineAudioFormat, bufferSizeToWrite);
+ out.println("> OK - line is opened");
+ } catch (LineUnavailableException lineUnavailableException) {
+ out.println("> Line is not available due to resource restrictions:");
+ lineUnavailableException.printStackTrace(out);
+ continue;
+ } catch (SecurityException securityException) {
+ out.println("> Line is not available due to security restrictions:");
+ securityException.printStackTrace(out);
+ continue;
+ } catch (Throwable thrown) {
+ out.println("## SourceDataLine.open(AudioFormat format) failed:");
+ out.println("# Unexpected Exception is thrown");
+ out.println("# Mixer = " + testedMixer);
+ out.println("# SourceDataLine = " + testedSourceLine);
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ continue;
+ }
+
+ out.println
+ ("\n> check SourceDataLine.write() for not started line with correct length of data:");
+ writtenBytes = -1;
+ try {
+ writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
+ out.println("> Bytes written: number of written bytes = " + writtenBytes);
+ } catch (Throwable thrown) {
+ out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
+ out.println("# Unexpected Exception is thrown");
+ out.println("# Mixer = " + testedMixer);
+ out.println("# SourceDataLine = " + testedSourceLine);
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+
+ out.println
+ ("\n> check SourceDataLine.write() for not started line with incorrect length of data:");
+ writtenBytes = -1;
+ bufferSizeToWrite--;
+ try {
+ writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
+ out.println("> Bytes written: number of written bytes = " + writtenBytes);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ out.println("> Permissible IllegalArgumentException for the present instance is thrown:");
+ illegalArgumentException.printStackTrace(out);
+ } catch (Throwable thrown) {
+ out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
+ out.println("# Unexpected Exception is thrown");
+ out.println("# Mixer = " + testedMixer);
+ out.println("# SourceDataLine = " + testedSourceLine);
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+ testedSourceLine.close();
+
+ } // for (int j=0; j < supportedSourceLineInfo.length; j++)
+ testedMixer.close();
+
+ } // for (int i=0; i < installedMixersInfo.length; i++)
+
+ if ( testResult == STATUS_FAILED ) {
+ out.println("\n==> test FAILED!");
+ } else {
+ out.println("\n==> test PASSED!");
+ }
+ return testResult;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Lines/SourceDataLineDefaultBufferSizeCrash.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,248 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4681384
+ * @summary SourceDataLine.write() causes Unexpected Signal 11 in native code
+ * outside the VM
+ */
+public class SourceDataLineDefaultBufferSizeCrash {
+
+ static final int STATUS_PASSED = 0;
+ static final int STATUS_FAILED = 2;
+ static final int STATUS_TEMP = 95;
+
+ public static void main(String argv[]) throws Exception {
+ int testExitStatus = run(argv, System.out) + STATUS_TEMP;
+ }
+
+ public static int run(String argv[], java.io.PrintStream out) throws Exception {
+ int testResult = STATUS_PASSED;
+
+ int framesNumberToExceed = 2;
+ if ( argv.length > 0 ) {
+ try {
+ framesNumberToExceed = Integer.parseInt(argv[0]);
+ }
+ catch (NumberFormatException e) {
+ }
+ }
+
+ out.println
+ ("\n==> Test for SourceDataLine.write() method:");
+
+ Mixer.Info[] installedMixersInfo = AudioSystem.getMixerInfo();
+
+ if ( installedMixersInfo == null ) {
+ out.println("## AudioSystem.getMixerInfo() returned unexpected result:");
+ out.println("# expected: an array of Mixer.Info objects (may be array of length 0);");
+ out.println("# produced: null;");
+ return STATUS_FAILED;
+ }
+
+ if ( installedMixersInfo.length == 0 ) {
+ // there are no mixers installed on the system -
+ // so this testcase can not be tested
+ out.println("\n>>> There are no mixers installed on the system!");
+ return STATUS_PASSED;
+ }
+
+ out.println("\n>>> Number of mixers installed on the system = "
+ + installedMixersInfo.length);
+ Mixer installedMixer = null;
+ for (int i=0; i < installedMixersInfo.length; i++) {
+ try {
+ installedMixer = AudioSystem.getMixer(installedMixersInfo[i]);
+ } catch (SecurityException securityException) {
+ // installed Mixer is unavailable because of security restrictions
+ out.println("\n>>> installedMixer[" + i
+ + "] is unavailable because of security restrictions");
+ continue;
+ } catch (Throwable thrown) {
+ out.println("\n## installedMixer[" + i + "] is unavailable because of");
+ out.println("# AudioSystem.getMixer() threw unexpected exception:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ continue;
+ }
+
+ out.println("\n>>> installedMixer["+i+"] = " + installedMixer);
+ try {
+ installedMixer.open();
+ } catch (LineUnavailableException lineUnavailableException) {
+ // installedMixer is not available due to resource restrictions
+ out.println(">> installedMixer[" + i
+ + "] is not opened because of resource restrictions");
+ continue;
+ } catch (SecurityException securityException) {
+ // installedMixer is not available due to security restrictions
+ out.println(">> installedMixer[" + i
+ + "] is not opened because of security restrictions");
+ continue;
+ } catch (Throwable thrown) {
+ out.println("## installedMixer.open() throws unexpected exception:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ continue;
+ }
+ Line.Info supportedSourceLineInfo[] = null;
+ try {
+ supportedSourceLineInfo = installedMixer.getSourceLineInfo();
+ } catch (Throwable thrown) {
+ out.println("## installedMixer.getSourceLineInfo() throws "
+ + "unexpected exception:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ installedMixer.close();
+ continue;
+ }
+ if ( supportedSourceLineInfo == null ) {
+ out.println("## installedMixer.getSourceLineInfo() returned null array");
+ out.println("# Mixer = " + installedMixer);
+ testResult = STATUS_FAILED;
+ installedMixer.close();
+ continue;
+ }
+ out.println("\n>> Number of SourceLineInfo supported by installedMixer ="
+ + supportedSourceLineInfo.length);
+
+ for (int j=0; j < supportedSourceLineInfo.length; j++) {
+ Line.Info testSourceLineInfo = supportedSourceLineInfo[j];
+
+ out.println("\n> testSourceLineInfo["+j+"] = " + testSourceLineInfo);
+ Line testSourceLine = null;
+ try {
+ testSourceLine = installedMixer.getLine(testSourceLineInfo);
+ } catch (LineUnavailableException lineUnavailableException) {
+ // line is not available due to resource restrictions
+ out.println("> Line for this SourceLine Info is not available "
+ + "due to resource restrictions");
+ continue;
+ } catch (SecurityException securityException) {
+ // line is not available due to security restrictions
+ out.println("> Line for this SourceLine Info is not available "
+ + "due to security restrictions");
+ continue;
+ } catch (Throwable thrown) {
+ out.println("## installedMixer.getLine(testSourceLineInfo) throws"
+ + "unexpected Exception:");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ continue;
+ }
+
+ out.println("> testedSourceLine = " + testSourceLine);
+ if ( ! (testSourceLine instanceof SourceDataLine) ) {
+ out.println("> testSourceLine is not SourceDataLine");
+ continue;
+ }
+
+ SourceDataLine testedSourceLine = (SourceDataLine)testSourceLine;
+ AudioFormat lineAudioFormat = testedSourceLine.getFormat();
+
+ out.println("\n> opening tested SourceLine:");
+ try {
+ //testedSourceLine.open(lineAudioFormat, 2048);
+ testedSourceLine.open(lineAudioFormat);
+ out.println("> OK - line is opened with "+testedSourceLine.getBufferSize()+" bytes buffer");
+ } catch (LineUnavailableException lineUnavailableException) {
+ out.println("> Line is not available due to resource restrictions:");
+ lineUnavailableException.printStackTrace(out);
+ continue;
+ } catch (SecurityException securityException) {
+ out.println("> Line is not available due to security restrictions:");
+ securityException.printStackTrace(out);
+ continue;
+ } catch (Throwable thrown) {
+ out.println("## SourceDataLine.open(AudioFormat format) failed:");
+ out.println("# Unexpected Exception is thrown");
+ out.println("# Mixer = " + installedMixer);
+ out.println("# SourceDataLine = " + testedSourceLine);
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ continue;
+ }
+
+ testedSourceLine.start();
+
+ int frameSize = 1;
+ if ( lineAudioFormat.getFrameSize() != AudioSystem.NOT_SPECIFIED ) {
+ frameSize = lineAudioFormat.getFrameSize();
+ } else {
+ if ( lineAudioFormat.getSampleSizeInBits() != AudioSystem.NOT_SPECIFIED ) {
+ frameSize = lineAudioFormat.getSampleSizeInBits()/8;
+ if ( lineAudioFormat.getSampleSizeInBits()%8 != 0 ) {
+ frameSize++;
+ }
+ }
+ }
+ int bufferSizeToWrite = testedSourceLine.available()
+ + (frameSize * framesNumberToExceed);
+ byte[] dataToWrite = new byte[bufferSizeToWrite];
+ for (int k=0; k < bufferSizeToWrite; k++) {
+ dataToWrite[k] = (byte)1;
+ }
+ int offsetToWrite = 0;
+
+ out.println("\n> check SourceDataLine.write() to write more data "
+ + "than can currently be written:");
+
+ out.println("> testedSourceLine.available() = " + testedSourceLine.available());
+ out.println("> frame size = " + frameSize);
+ out.println("> number of bytes to write = " + bufferSizeToWrite);
+ int writtenBytes = -1;
+ try {
+ writtenBytes =
+ testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
+ out.println("> OK - number of written bytes = " + writtenBytes);
+ } catch (Throwable thrown) {
+ out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
+ out.println("# Unexpected Exception is thrown");
+ thrown.printStackTrace(out);
+ testResult = STATUS_FAILED;
+ }
+
+ testedSourceLine.close();
+
+ } // for (int j=0; j < supportedSourceLineInfo.length; j++)
+ installedMixer.close();
+
+ } // for (int i=0; i < installedMixersInfo.length; i++)
+
+ if ( testResult == STATUS_FAILED ) {
+ throw new Exception("Test FAILED!");
+ } else {
+ out.println("\n==> test PASSED!");
+ }
+ return testResult;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Lines/StopStart.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,282 @@
+/*
+ * 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 java.util.Random;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4828556
+ * @summary stopping and starting sampled audio plays small chunk in infinite
+ * loop
+ */
+public class StopStart implements Runnable {
+
+ static int sampleRate = 8000;
+ static double frequency = 2000.0;
+ static double RAD = 2.0 * Math.PI;
+ static Random random = new Random();
+
+ static byte[] audioData = new byte[sampleRate/2];
+ static SourceDataLine source;
+
+ static boolean terminated = false;
+
+ static int buffersWritten = 0;
+ static long bytesWritten = 0;
+ static int buffersWrittenAfter5Seconds;
+
+ static AudioInputStream ais = null;
+ static AudioFormat audioFormat;
+ static String filename;
+
+ static int executedTests=0;
+ static int successfulTests = 0;
+
+ public static void constructAIS() throws Exception {
+ ais = AudioSystem.getAudioInputStream(new File(filename));
+ }
+
+ public static void doStartStopTest1() throws Exception {
+ System.out.println("TEST 1: play for 3 seconds, stop/start/stop/start/play for 3 seconds...");
+ source.start();
+ Thread.sleep(100);
+ bytesWritten = 0;
+ System.out.println("Waiting for 3 seconds...");
+ Thread.sleep(3000);
+ buffersWrittenAfter5Seconds = buffersWritten;
+ System.out.println("Buffers Written: "+buffersWritten);
+ System.out.println("stop()->start()->stop()->start()");
+ source.stop();
+ //System.out.println("start()");
+ source.start();
+ //System.out.println("stop()2 ----------------------------------------------------------");
+ source.stop();
+ //System.out.println("start()");
+ source.start();
+ System.out.println("Buffers Written: "+buffersWritten);
+ System.out.println("Waiting for 3 seconds...");
+ Thread.sleep(3000);
+ System.out.println("Buffers Written: "+buffersWritten);
+ if (buffersWritten >= ((buffersWrittenAfter5Seconds * 2) - ((buffersWrittenAfter5Seconds / 4)))) {
+ successfulTests++;
+ }
+ }
+
+ private static int nextWaitTime() {
+ int waitTime = random.nextInt(25);
+ waitTime*=waitTime;
+ if (waitTime<20) waitTime = 0;
+ return waitTime;
+ }
+
+
+ public static void doStartStopTest2() throws Exception {
+ System.out.println("TEST 2: start and stop 100 times with random wait in between");
+ int max=100;
+ for (int i=0; i<max; i++) {
+ System.out.println("Round "+i);
+ System.out.println("Start....");
+ source.start();
+ int waitTime = nextWaitTime();
+ System.out.println("Waiting for "+waitTime+"ms...");
+ if (waitTime>0) {
+ Thread.sleep(waitTime);
+ }
+ System.out.println("stop()");
+ source.stop();
+ waitTime = nextWaitTime();
+ System.out.println("Waiting for "+waitTime+"ms...");
+ if (waitTime>0) {
+ Thread.sleep(waitTime);
+ }
+ }
+ }
+
+ public static void doStartStopTest3() throws Exception {
+ System.out.println("TEST 3: start and stop 100 times with random wait only every 10 rounds ");
+ int max=100;
+ for (int i=0; i<max; i++) {
+ System.out.println("Round "+i);
+ System.out.println("Start....");
+ source.start();
+ if (i % 10 == 9) {
+ int waitTime = nextWaitTime();
+ System.out.println("Waiting for "+waitTime+"ms...");
+ if (waitTime>0) {
+ Thread.sleep(waitTime);
+ }
+ }
+ System.out.println("stop()");
+ source.stop();
+ if (i % 13 == 12) {
+ int waitTime = nextWaitTime();
+ System.out.println("Waiting for "+waitTime+"ms...");
+ if (waitTime>0) {
+ Thread.sleep(waitTime);
+ }
+ }
+ }
+ }
+
+ public static void runTest(int testNum) {
+ terminated = false;
+ Thread thread = null;
+ buffersWrittenAfter5Seconds = 0;
+ // make the tests reproduceable by always seeding with same value
+ random.setSeed(1);
+ try {
+ executedTests++;
+ thread = new Thread(new StopStart());
+ thread.start();
+ switch (testNum) {
+ case 1: doStartStopTest1(); break;
+ case 2: doStartStopTest2(); break;
+ case 3: doStartStopTest3(); break;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ source.stop();
+ source.close();
+ if (thread!=null) {
+ terminated = true;
+ System.out.println("Waiting for thread to die...");
+ try {
+ thread.join();
+ } catch (InterruptedException ie) {
+ ie.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ filename = null;
+ if (args.length>0) {
+ File f = new File(args[0]);
+ if (f.exists()) {
+ filename = args[0];
+ System.out.println("Opening "+filename);
+ constructAIS();
+ audioFormat = ais.getFormat();
+ }
+ }
+ if (filename == null) {
+ audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
+ for (int i=0; i<audioData.length; i++) {
+ audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+ }
+ }
+ long startTime = System.currentTimeMillis();
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ for (int i=0; i<mixers.length; i++) {
+ try {
+ Mixer mixer = AudioSystem.getMixer(mixers[i]);
+ DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
+ String mixerName = mixer.getMixerInfo().getName();
+ try {
+ source = (SourceDataLine) mixer.getLine(info);
+ source.open(audioFormat);
+ } catch (IllegalArgumentException iae) {
+ System.out.println("Mixer "+mixerName+" does not provide a SourceDataLine.");
+ continue;
+ } catch (LineUnavailableException lue) {
+ System.out.println("Mixer "+mixerName+": no lines available.");
+ continue;
+ }
+ System.out.println("***** Testing on Mixer "+mixerName+":");
+ //runTest(2);
+ //runTest(3);
+ runTest(1);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ if (mixers.length==0) {
+ System.out.println("No mixers available!");
+ } else {
+ long duration = System.currentTimeMillis() - startTime;
+
+ System.out.println("Test took "+(duration/1000)+"s and "+(duration % 1000)+"ms.");
+ }
+
+ System.out.println("Exiting main()");
+ if (executedTests>0) {
+ if (successfulTests == 0) {
+ if (args.length == 0) {
+ throw new Exception("Test FAILED");
+ }
+ System.out.println("test FAILED.");
+ } else {
+ System.out.println("test successful.");
+ }
+ } else {
+ System.out.println("Could not execute any tests - are soundcards correctly installed?");
+ System.out.println("Test NOT FAILED.");
+ }
+ }
+
+ public void run() {
+ int len = audioData.length;
+ int offset = len;
+ System.out.println("Thread: started. Beginning audio i/o");
+ while (!terminated) {
+ try {
+ //if (!source.isActive()) {
+ // Thread.sleep(50);
+ //}
+ if (offset >= len) {
+ offset = 0;
+ if (ais!=null) {
+ do {
+ len = ais.read(audioData, 0, audioData.length);
+ if (len < 0) {
+ constructAIS();
+ }
+ } while (len < 0);
+ }
+ }
+ int toWrite = len - offset;
+ int written = source.write(audioData, offset, toWrite);
+ offset+=written;
+ bytesWritten += written;
+ buffersWritten = (int) (bytesWritten / audioData.length);
+ } catch (Exception e) {
+ e.printStackTrace();
+ terminated = true;
+ }
+ }
+ System.out.println("Thread: closing line");
+ source.stop();
+ source.close();
+ System.out.println("Thread finished");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/LinuxBlock/PlaySine.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,269 @@
+/*
+ * 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 java.io.IOException;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4834461
+ * @summary Applet hang when you load it during sound card is in use
+ * @run main/manual PlaySine
+ */
+public class PlaySine {
+
+ static int sampleRate = 8000;
+ static double frequency = 2000.0;
+ static double RAD = 2.0 * Math.PI;
+
+ static byte[] audioData = new byte[sampleRate/2];
+ static SourceDataLine source;
+ static Mixer mixer = null;
+
+ static AudioInputStream ais = null;
+ static AudioFormat audioFormat;
+ static String filename;
+
+ public static void constructAIS() {
+ try {
+ ais = AudioSystem.getAudioInputStream(new File(filename));
+ } catch (Exception e) {
+ println("ERROR: could not open "+filename+": "+e.getMessage());
+ }
+ }
+
+ public static void print(String s) {
+ System.out.print(s);
+ }
+ public static void println(String s) {
+ System.out.println(s);
+ }
+
+ public static void key() {
+ println("");
+ print("Press ENTER to continue...");
+ try {
+ System.in.read();
+ } catch (IOException ioe) {
+ }
+ }
+
+ static int audioLen = -1;
+ static int audioOffset = -1;
+
+ public static void writeData() {
+ if (audioLen == -1) {
+ audioLen = audioData.length;
+ }
+ if (audioOffset < 0) {
+ audioOffset = audioLen;
+ }
+ try {
+ if (audioOffset >= audioLen) {
+ audioOffset = 0;
+ if (ais!=null) {
+ do {
+ audioLen = ais.read(audioData, 0, audioData.length);
+ if (audioLen < 0) {
+ constructAIS();
+ }
+ } while (audioLen < 0);
+ }
+ }
+ int toWrite = audioLen - audioOffset;
+ int written = source.write(audioData, audioOffset, toWrite);
+ audioOffset+=written;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ public static int play(boolean shouldPlay) {
+ int res = 0;
+ DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
+ try {
+ println("Getting line from mixer...");
+ source = (SourceDataLine) mixer.getLine(info);
+ println("Opening line...");
+ println(" -- if the program is hanging here, kill the process that has blocks the audio device now.");
+ source.open(audioFormat);
+ println("Starting line...");
+ source.start();
+ println("Writing audio data for 1 second...");
+ long startTime = System.currentTimeMillis();
+ while (System.currentTimeMillis() - startTime < 1000) {
+ writeData();
+ Thread.sleep(100);
+ }
+ res = 1;
+ } catch (IllegalArgumentException iae) {
+ println("IllegalArgumentException: "+iae.getMessage());
+ println("Sound device cannot handle this audio format.");
+ println("ERROR: Test environment not correctly set up.");
+ if (source!=null) {
+ source.close();
+ }
+ return 3;
+ } catch (LineUnavailableException lue) {
+ println("LineUnavailableException: "+lue.getMessage());
+ if (shouldPlay) {
+ println("ERROR: the line should be available now!.");
+ println(" Verify that you killed the other audio process.");
+ } else {
+ println("Correct behavior! the bug is fixed.");
+ }
+ res = 2;
+ } catch (Exception e) {
+ println("Unexpected Exception: "+e.toString());
+ }
+ if (source != null) {
+ println("Draining...");
+ try {
+ source.drain();
+ } catch (NullPointerException npe) {
+ println("(NullPointerException: bug fixed in J2SE 1.4.2");
+ }
+ println("Stopping...");
+ source.stop();
+ println("Closing...");
+ source.close();
+ source = null;
+ }
+ return res;
+ }
+
+ public static void main(String[] args) throws Exception {
+ println("This is an interactive test. You can run it with a filename as argument");
+ println("It is only meant to be run on linux, with the (old) OSS kernel drivers (/dev/dsp)");
+ println("This test should not be run on systems with ALSA installed, or kernel 2.6 or higher.");
+ println("");
+ println("The test verifies that Java Sound fails correctly if another process is blocking");
+ println("the audio device.");
+ println("");
+ println("Checking sanity...");
+ Mixer.Info[] mixers=null;
+
+ mixers = AudioSystem.getMixerInfo();
+ for (int i=0; i<mixers.length; i++) {
+ try {
+ Mixer thisMixer = AudioSystem.getMixer(mixers[i]);
+ String mixerName = thisMixer.getMixerInfo().getName();
+ if (mixerName.indexOf("Java Sound")>=0
+ && mixerName.indexOf("Engine")>=0) {
+ mixer = thisMixer;
+ break;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ if (mixer == null) {
+ if (mixers.length==0) {
+ System.out.println("ERROR: No mixers available!");
+ } else {
+ println("ERROR: Java Sound Engine could not be found.");
+ }
+ println("Cannot run this test.");
+ return;
+ }
+ println(" ...using mixer "+mixer.getMixerInfo());
+
+ String osname = System.getProperty("os.name");
+ if ((osname == null) || (osname.toLowerCase().indexOf("linux")<0)) {
+ println("ERROR: not running on linux (you are running on "+osname+")");
+ return;
+ }
+ println(" ...running on "+osname);
+ println(" ...sanity test OK.");
+
+ filename = null;
+ if (args.length>0) {
+ File f = new File(args[0]);
+ if (f.exists()) {
+ filename = args[0];
+ println("Opening "+filename);
+ constructAIS();
+ if (ais!=null) {
+ audioFormat = ais.getFormat();
+ }
+ }
+ }
+ if (ais == null) {
+ println("Using self-generated sine wave for playback");
+ audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
+ for (int i=0; i<audioData.length; i++) {
+ audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+ }
+ }
+
+ println("");
+ println("Now, on a second console, run the following command:");
+ println(" cat - < /dev/zero > /dev/dsp");
+ key();
+ println("After you press ENTER now, the mixer will be opened.");
+ println("There are 3 possible cases that can occur:");
+ println("1) you'll hear a sine wave");
+ println(" -> you are running with mixing OSS drivers. ");
+ println(" Some soundcards only provide mixing OSS drivers.");
+ println(" Test environment not valid. ");
+ println(" Repeat on another machine where you can reproduce the bug first.");
+ println("2) this program stops doing anything after 'Opening line...'");
+ println(" -> this is the bug.");
+ println(" Kill the command on the other console with Ctrl-C, this program");
+ println(" should continue working then.");
+ println("3) this program reports a LineUnavailableException");
+ println(" -> bug is fixed.");
+ println(" OR you run with non-blocking OSS drivers.");
+ println(" make sure that you can reproduce this bug first with e.g. J2SE 1.4.1");
+ key();
+ int playedFirst = play(false);
+ int playedSecond = 0;
+
+ if (playedFirst == 2) {
+ println("");
+ println("Now kill the other process with Ctrl-C.");
+ println("After that, this program should be able to play ");
+ println("the sine wave without problems.");
+ key();
+ playedSecond = play(true);
+ }
+ println("");
+ if (playedFirst == 1) {
+ println("Test FAILED.");
+ }
+ else if (playedFirst == 2 && playedSecond == 1) {
+ println("Test SUCCESSFUL");
+ } else {
+ println("Test not failed (but not successful either...).");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/LinuxCrash/ClipLinuxCrash.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,163 @@
+/*
+ * 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.InputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+
+/**
+ * @test
+ * @bug 4498848
+ * @summary Sound causes crashes on Linux (part 1)
+ */
+public class ClipLinuxCrash {
+
+ static Clip clip;
+
+ public static long bytes2Ms(long bytes, AudioFormat format) {
+ return (long) (bytes / format.getFrameRate() * 1000
+ / format.getFrameSize());
+ }
+
+ static int staticLen = 1000;
+
+ static boolean addLen = true;
+
+ public static long start() throws Exception {
+ AudioFormat fmt = new AudioFormat(44100, 16, 2, true, false);
+ if (addLen) {
+ staticLen += (int) (staticLen / 5) + 1000;
+ } else {
+ staticLen -= (int) (staticLen / 5) + 1000;
+ }
+ if (staticLen > 8 * 44100 * 4) {
+ staticLen = 8 * 44100 * 4;
+ addLen = !addLen;
+ }
+ if (staticLen < 1000) {
+ staticLen = 1000;
+ addLen = !addLen;
+ }
+ int len = staticLen;
+ len -= (len % 4);
+ byte[] fakedata = new byte[len];
+ InputStream is = new ByteArrayInputStream(fakedata);
+ AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
+ 44100, 16, 2, 4, 44100, false);
+ AudioInputStream ais = new AudioInputStream(is, format, fakedata.length
+ / format.getFrameSize());
+
+ out(" preparing to play back " + len + " bytes == " + bytes2Ms(len,
+ format)
+ + "ms audio...");
+
+ DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
+ clip = (Clip) AudioSystem.getLine(info);
+ clip.addLineListener(new LineListener() {
+ public void update(LineEvent e) {
+ if (e.getType() == LineEvent.Type.STOP) {
+ out(" calling close() from event dispatcher thread");
+ ((Clip) e.getSource()).close();
+ } else if (e.getType() == LineEvent.Type.CLOSE) {
+ }
+ }
+ });
+
+ out(" opening...");
+ try {
+ clip.open(ais);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ clip.close();
+ clip = null;
+ }
+ ais.close();
+ if (clip != null) {
+ out(" starting...");
+ clip.start();
+ }
+ return bytes2Ms(fakedata.length, format);
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (AudioSystem.getMixerInfo().length == 0) {
+ System.out.println("Cannot execute test: no mixers installed!");
+ System.out.println("Not Failed.");
+ return;
+ }
+ try {
+ int COUNT = 10;
+ out();
+ out("4498848 Sound causes crashes on Linux (testing with Clip)");
+ if (args.length > 0) {
+ COUNT = Integer.parseInt(args[0]);
+ }
+ for (int i = 0; i < COUNT; i++) {
+ out(" trial " + (i + 1) + "/" + COUNT);
+ start();
+ int waitTime = 500 + (1000 * (i
+ % 2)); // every second
+ // time wait 1500, rather than 500ms.
+ out(" waiting for " + waitTime
+ + " ms for audio playback to stop...");
+ Thread.sleep(waitTime);
+ out(" calling close() from main thread");
+ if (clip != null) {
+ clip.close();
+ }
+ // let the subsystem enough time to actually close the soundcard
+ out(" waiting for 2 seconds...");
+ Thread.sleep(2000);
+ out();
+ }
+ out(" waiting for 1 second...");
+ Thread.sleep(1000);
+ } catch (Exception e) {
+ e.printStackTrace();
+ out(" waiting for 1 second");
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) {
+ }
+ throw e;
+ }
+ out("Test passed");
+ }
+
+ static void out() {
+ out("");
+ }
+
+ 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/sampled/LinuxCrash/ClipLinuxCrash2.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,188 @@
+/*
+ * 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.InputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4498848
+ * @summary Sound causes crashes on Linux (part 3)
+ */
+public class ClipLinuxCrash2 implements LineListener{
+ Clip clip;
+ int stopOccured;
+ static final Object lock = new Object();
+
+ public static long bytes2Ms(long bytes, AudioFormat format) {
+ return (long) (bytes/format.getFrameRate()*1000/format.getFrameSize());
+ }
+
+ static int staticLen=1000;
+ static boolean addLen=true;
+
+ ClipLinuxCrash2() {
+ }
+
+ public void update(LineEvent e) {
+ if (e.getType() == LineEvent.Type.STOP) {
+ stopOccured++;
+ out(" Test program: receives STOP event for clip="+clip.toString()+" no."+stopOccured);
+ out(" Test program: Calling close() in event dispatcher thread");
+ clip.close();
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+ }
+ else if (e.getType() == LineEvent.Type.CLOSE) {
+ out(" Test program: receives CLOSE event for "+clip.toString());
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+ }
+ else if (e.getType() == LineEvent.Type.START) {
+ out(" Test program: receives START event for "+clip.toString());
+ }
+ else if (e.getType() == LineEvent.Type.OPEN) {
+ out(" Test program: receives OPEN event for "+clip.toString());
+ }
+ }
+
+ public long start() throws Exception {
+ AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+
+ if (addLen) {
+ staticLen+=(int) (staticLen/5)+1000;
+ } else {
+ staticLen-=(int) (staticLen/5)+1000;
+ }
+ if (staticLen>8*44100*4) {
+ staticLen = 8*44100*4;
+ addLen=!addLen;
+ }
+ if (staticLen<1000) {
+ staticLen = 1000;
+ addLen=!addLen;
+ }
+ int len = staticLen;
+ len -= (len % 4);
+ out(" Test program: preparing to play back "+len+" bytes == "+bytes2Ms(len, format)+"ms audio...");
+
+ byte[] fakedata=new byte[len];
+ InputStream is = new ByteArrayInputStream(fakedata);
+ AudioInputStream ais = new AudioInputStream(is, format, fakedata.length/format.getFrameSize());
+
+ DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
+ clip = (Clip) AudioSystem.getLine(info);
+ clip.addLineListener(this);
+
+ out(" Test program: opening clip="+((clip==null)?"null":clip.toString()));
+ clip.open(ais);
+ ais.close();
+ out(" Test program: starting clip="+((clip==null)?"null":clip.toString()));
+ clip.start();
+ return bytes2Ms(fakedata.length, format);
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (!isSoundcardInstalled()) {
+ return;
+ }
+
+ try {
+ int COUNT=10;
+ out();
+ out("4498848 Sound causes crashes on Linux");
+ if (args.length>0) {
+ COUNT=Integer.parseInt(args[0]);
+ }
+ for (int i=0; i<COUNT; i++) {
+ out("trial "+(i+1)+"/"+COUNT);
+ ClipLinuxCrash2 t = new ClipLinuxCrash2();
+ t.start();
+ int waitTime = 300+(1300*(i % 2)); // every 2nd time wait 1600, rather than 300ms.
+ out(" Test program: waiting for "+waitTime+" ms for audio playback to stop...");
+ Thread.sleep(waitTime);
+ out(" Test program: calling close() from main thread");
+ t.clip.close();
+ // let the subsystem enough time to actually close the soundcard
+ //out(" Test program: waiting for 2 seconds...");
+ //Thread.sleep(2000);
+ //out();
+ }
+ out(" Test program: waiting for 1 second...");
+ Thread.sleep(1000);
+ } catch (Exception e) {
+ e.printStackTrace();
+ out(" Test program: waiting for 1 second");
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) {}
+ // do not fail if no audio device installed - bug 4742021
+ if (!(e instanceof LineUnavailableException)) {
+ throw e;
+ }
+ }
+ out("Test passed");
+ }
+
+ static void out() {
+ out("");
+ }
+
+ static void out(String s) {
+ System.out.println(s); System.out.flush();
+ }
+
+ /**
+ * Returns true if at least one soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: "+e);
+ }
+ 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/sampled/LinuxCrash/SDLLinuxCrash.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,317 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4498848
+ * @summary Sound causes crashes on Linux (part 2)
+ */
+public class SDLLinuxCrash implements Runnable {
+ SourceDataLine sdl;
+ int size;
+
+ SDLLinuxCrash(SourceDataLine sdl, int size) {
+ this.sdl = sdl;
+ this.size = size - (size % 4);
+ }
+
+ public void run() {
+ int written=0;
+ //byte[] buffer = new byte[4096];
+ byte[] buffer = data;
+ out(" starting data line feed thread.");
+ try {
+ while (written<size) {
+ int toWrite = buffer.length;
+ if (toWrite+written > size) {
+ toWrite = size-written;
+ }
+ toWrite -= (toWrite % 4);
+ //out(" writing "+toWrite+" bytes.");
+ int thisWritten = sdl.write(buffer, 0, toWrite);
+ if (thisWritten<toWrite) {
+ out(" only wrote "+thisWritten+" bytes instead of "+toWrite);
+ }
+ if (thisWritten<=0) {
+ break;
+ }
+ written += thisWritten;
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ out(" leaving data line feed thread.");
+ }
+
+ public static long bytes2Ms(long bytes, AudioFormat format) {
+ return (long) (bytes/format.getFrameRate()*1000/format.getFrameSize());
+ }
+
+ static int staticLen=1000;
+ static boolean addLen=true;
+
+ public static SourceDataLine start() throws Exception {
+ AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+ if (addLen) {
+ staticLen+=(int) (staticLen/5)+1000;
+ } else {
+ staticLen-=(int) (staticLen/5)+1000;
+ }
+ if (staticLen>8*44100*4) {
+ staticLen = 8*44100*4;
+ addLen=!addLen;
+ }
+ if (staticLen<1000) {
+ staticLen = 1000;
+ addLen=!addLen;
+ }
+ int len = staticLen;
+ len -= (len % 4);
+ out(" preparing to play back "+len+" bytes == "+bytes2Ms(len, format)+"ms audio...");
+
+ DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+ SourceDataLine sdl = (SourceDataLine) AudioSystem.getLine(info);
+ sdl.addLineListener(new LineListener() {
+ public void update(LineEvent e) {
+ if (e.getType() == LineEvent.Type.STOP) {
+ out(" calling close() from event dispatcher thread");
+ ((SourceDataLine) e.getSource()).close();
+ }
+ else if (e.getType() == LineEvent.Type.CLOSE) {
+ }
+ }
+ });
+
+ out(" opening...");
+ sdl.open();
+ out(" starting...");
+ sdl.start();
+ (new Thread(new SDLLinuxCrash(sdl, len))).start();
+ return sdl;
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (!isSoundcardInstalled()) {
+ return;
+ }
+
+ try {
+ int COUNT=10;
+ out();
+ out("4498848 Sound causes crashes on Linux (testing with SourceDataLine)");
+ if (args.length>0) {
+ COUNT=Integer.parseInt(args[0]);
+ }
+ for (int i=0; i<COUNT; i++) {
+ out(" trial "+(i+1)+"/"+COUNT);
+ SourceDataLine sdl = start();
+ int waitTime = 500+(1000*(i % 2)); // every 2nd time wait 1500, rather than 500ms.
+ out(" waiting for "+waitTime+" ms for audio playback to stop...");
+ Thread.sleep(waitTime);
+ out(" calling close() from main thread");
+ sdl.close();
+ // let the subsystem enough time to actually close the soundcard
+ out(" waiting for 2 seconds...");
+ Thread.sleep(2000);
+ out();
+ }
+ out(" waiting for 1 second...");
+ Thread.sleep(1000);
+ } catch (Exception e) {
+ e.printStackTrace();
+ out(" waiting for 1 second");
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) {}
+ // do not fail if no audio device installed - bug 4742021
+ if (!(e instanceof LineUnavailableException)) {
+ throw e;
+ }
+ }
+ out("Test passed");
+ }
+
+ static void out() {
+ out("");
+ }
+
+ static void out(String s) {
+ System.out.println(s); System.out.flush();
+ }
+
+ /**
+ * Returns true if at least one soundcard is correctly installed
+ * on the system.
+ */
+ public static boolean isSoundcardInstalled() {
+ boolean result = false;
+ try {
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ if (mixers.length > 0) {
+ result = AudioSystem.getSourceDataLine(null) != null;
+ }
+ } catch (Exception e) {
+ System.err.println("Exception occured: "+e);
+ }
+ 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;
+ }
+
+
+
+ static final byte[] data = new byte[] {
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+ 123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 122, 122
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Mixers/BogusMixers.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * 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.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4667064
+ * @summary Java Sound provides bogus SourceDataLine and TargetDataLine
+ */
+public class BogusMixers {
+
+ public static void main(String[] args) throws Exception {
+ try {
+ out("4667064: Java Sound provides bogus SourceDataLine and TargetDataLine");
+
+ Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
+ out(" available Mixers:");
+ for (int i = 0; i < aInfos.length; i++) {
+ if (aInfos[i].getName().startsWith("Java Sound Audio Engine")) {
+ Mixer mixer = AudioSystem.getMixer(aInfos[i]);
+ Line.Info[] tlInfos = mixer.getTargetLineInfo();
+ for (int ii = 0; ii<tlInfos.length; ii++) {
+ if (tlInfos[ii].getLineClass() == DataLine.class) {
+ throw new Exception("Bogus TargetDataLine with DataLine info present!");
+ }
+ }
+ }
+ if (aInfos[i].getName().startsWith("WinOS,waveOut,multi threaded")) {
+ throw new Exception("Bogus mixer 'WinOS,waveOut,multi threaded' present!");
+ }
+ out(aInfos[i].getName());
+ }
+ if (aInfos.length == 0)
+ {
+ out("[No mixers available] - not a failure of this test case.");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ }
+ out("Test passed");
+ }
+
+ 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/sampled/Mixers/BothEndiansAndSigns.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,136 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4936397
+ * @summary Verify that there'll for a given endianness, there's also the little
+ * endian version
+ */
+public class BothEndiansAndSigns {
+ static boolean failed = false;
+ static int testedFormats = 0;
+
+ public static void main(String[] args) throws Exception {
+ out("4936397: Verify that there'll for a given endianness, there's also the little endian version");
+ out(" and the same for signed'ness for 8-bit formats");
+
+ Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
+ for (int i = 0; i < aInfos.length; i++) {
+ try {
+ Mixer mixer = AudioSystem.getMixer(aInfos[i]);
+ out("Mixer "+aInfos[i]);
+ checkLines(mixer, mixer.getSourceLineInfo());
+ checkLines(mixer, mixer.getTargetLineInfo());
+ } catch (Exception e) {
+ out("Unexpected exception when getting a mixer: "+e);
+ }
+ }
+ if (testedFormats == 0) {
+ out("[No appropriate lines available] - cannot exercise this test.");
+ } else {
+ if (failed) {
+ throw new Exception("Test FAILED!");
+ }
+ out("Test passed");
+ }
+ }
+
+ public static void checkLines(Mixer mixer, Line.Info[] infos) {
+ for (int i = 0; i<infos.length; i++) {
+ try {
+ if (infos[i] instanceof DataLine.Info) {
+ DataLine.Info info = (DataLine.Info) infos[i];
+ System.out.println(" Line "+info+" (max. "+mixer.getMaxLines(info)+" simultaneously): ");
+ AudioFormat[] formats = info.getFormats();
+ for (int f = 0; f < formats.length; f++) {
+ try {
+ AudioFormat otherEndianOrSign = getOtherEndianOrSign(formats[f]);
+ if (otherEndianOrSign != null) {
+ checkFormat(formats, otherEndianOrSign);
+ }
+ } catch (Exception e1) {
+ out(" Unexpected exception when getting a format: "+e1);
+ }
+ }
+ }
+ } catch (Exception e) {
+ out(" Unexpected exception when getting a line: "+e);
+ }
+ }
+ }
+
+ public static void checkFormat(AudioFormat[] formats, AudioFormat format) {
+ for (int i = 0; i < formats.length; i++) {
+ testedFormats++;
+ if (formats[i].matches(format)) {
+ return;
+ }
+ }
+ out(" ## expected this format: "+format
+ +" ("+format.getChannels()+" channels, "
+ +"frameSize="+format.getFrameSize()+", "
+ +(format.isBigEndian()?"big endian":"little endian")
+ +")");
+ failed = true;
+ }
+
+ public static AudioFormat getOtherEndianOrSign(AudioFormat format) {
+ AudioFormat.Encoding newEnc = null;
+ boolean newEndian = format.isBigEndian();
+ boolean isSigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED);
+ boolean isUnsigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED);
+ if ((isSigned || isUnsigned) && format.getSampleSizeInBits() > 0) {
+ if (format.getSampleSizeInBits() == 8) {
+ // return the other signed'ness
+ if (isSigned) {
+ newEnc = AudioFormat.Encoding.PCM_UNSIGNED;
+ } else {
+ newEnc = AudioFormat.Encoding.PCM_SIGNED;
+ }
+ } else {
+ newEnc = format.getEncoding();
+ newEndian = !newEndian;
+ }
+ if (newEnc != null) {
+ return new AudioFormat(newEnc, format.getSampleRate(),
+ format.getSampleSizeInBits(),
+ format.getChannels(),
+ format.getFrameSize(),
+ format.getFrameRate(),
+ newEndian);
+ }
+ }
+ return null;
+ }
+
+ 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/sampled/Mixers/DirectSoundRepeatingBuffer/DirectSoundRepeatingBuffer.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,156 @@
+/*
+ * 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.IOException;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * This is utility class for Test4997635.
+ */
+public class DirectSoundRepeatingBuffer {
+
+ static int sampleRate = 8000;
+ static double frequency = 1000.0;
+ static double RAD = 2.0 * Math.PI;
+
+ static byte[] audioData = new byte[sampleRate/8];
+ static DataLine.Info info;
+ static SourceDataLine source;
+
+ //static AudioInputStream ais = null;
+ static AudioFormat audioFormat;
+ //static String filename;
+
+ public static void print(String s) {
+ System.out.print(s);
+ }
+ public static void println(String s) {
+ System.out.println(s);
+ }
+
+ public static void key() {
+ println("");
+ print("Press ENTER to continue...");
+ try {
+ System.in.read();
+ } catch (IOException ioe) {
+ }
+ println("");
+ }
+
+ public static void play(Mixer mixer) {
+ int res = 0;
+ try {
+ println("Getting SDL from mixer...");
+ source = (SourceDataLine) mixer.getLine(info);
+ println("Opening SDL...");
+ source.open(audioFormat);
+ println("Writing data to SDL...");
+ source.write(audioData, 0, audioData.length);
+ println("Starting SDL...");
+ source.start();
+ println("Now open your ears:");
+ println("- you should have heard a short tone,");
+ println(" followed by silence.");
+ println("- if after a while you hear repeated tones,");
+ println(" the bug is NOT fixed.");
+ println("- if the program remains silent after the ");
+ println(" initial tone, the bug is fixed.");
+ key();
+ } catch (IllegalArgumentException iae) {
+ println("IllegalArgumentException: "+iae.getMessage());
+ println("Sound device cannot handle this audio format.");
+ println("ERROR: Test environment not correctly set up.");
+ if (source!=null) {
+ source.close();
+ source = null;
+ }
+ return;
+ } catch (LineUnavailableException lue) {
+ println("LineUnavailableException: "+lue.getMessage());
+ println("This is normal for some mixers.");
+ } catch (Exception e) {
+ println("Unexpected Exception: "+e.toString());
+ }
+ if (source != null) {
+ println("Stopping...");
+ source.stop();
+ println("Closing...");
+ source.close();
+ println("Closed.");
+ source = null;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ println("This is an interactive test for DirectAudio.");
+ println("If the tone repeats, the test is failed.");
+ println("");
+ println("Make sure that you have speakers connected");
+ println("and that the system mixer is not muted.");
+ println("");
+ println("Press a key to start the test.");
+ key();
+ Mixer.Info[] mixers=null;
+
+ println(" ...using self-generated sine wave for playback");
+ audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
+ for (int i=0; i<audioData.length; i++) {
+ audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+ }
+ info = new DataLine.Info(SourceDataLine.class, audioFormat);
+
+ mixers = AudioSystem.getMixerInfo();
+ int succMixers = 0;
+ for (int i=0; i<mixers.length; i++) {
+ println(""+mixers[i]+":");
+ if ((mixers[i].getName()+mixers[i].getDescription()+mixers[i].getVendor()).indexOf("Direct") < 0) {
+ println(" ->not a DirectAudio Mixer!");
+ } else {
+ try {
+ Mixer mixer = AudioSystem.getMixer(mixers[i]);
+ if (!mixer.isLineSupported(info)) {
+ println(" ->doesn't support SourceDataLine!");
+ } else {
+ succMixers++;
+ println(" -> is getting tested.");
+ play(mixer);
+ }
+ } catch (Exception e) {
+ println(" -> Exception occured: "+e);
+ e.printStackTrace();
+ }
+ }
+ }
+ if (succMixers == 0) {
+ println("No DirectAudio mixers available! ");
+ println("Cannot run test.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Mixers/DirectSoundRepeatingBuffer/Test4997635.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,381 @@
+/*
+ * 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.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 4997635
+ * @summary Win: SourceDataLine playback loops endlessly unless you manually
+ * stop()
+ * @build DirectSoundRepeatingBuffer
+ * @run main/manual Test4997635
+ */
+public class Test4997635 {
+
+ private static void init() throws Exception {
+ //*** Create instructions for the user here ***
+
+ String[] instructions =
+ {
+ "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 DirectSoundRepeatingBuffer\".",
+ "4. Follow the instructions shown in the terminal window.",
+ "If no error occured during the test, and the java application ",
+ "in the termial exited successfully, 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" )
+ {
+ Test4997635.pass();
+ }
+ else
+ {
+ Test4997635.fail();
+ }
+ }
+
+ }// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Mixers/DirectSoundUnderrunSilence/DirectSoundUnderrunSilence.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,161 @@
+/*
+ * 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.IOException;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * This is utility class for Test5032020.
+ */
+public class DirectSoundUnderrunSilence {
+
+ static int sampleRate = 8000;
+ static double frequency = 1000.0;
+ static double RAD = 2.0 * Math.PI;
+
+ static byte[] audioData = new byte[sampleRate/8];
+ static DataLine.Info info;
+ static SourceDataLine source;
+
+ //static AudioInputStream ais = null;
+ static AudioFormat audioFormat;
+ //static String filename;
+
+ public static void print(String s) {
+ System.out.print(s);
+ }
+ public static void println(String s) {
+ System.out.println(s);
+ }
+
+ public static void key() {
+ println("");
+ print("Press ENTER to continue...");
+ try {
+ System.in.read();
+ } catch (IOException ioe) {
+ }
+ println("");
+ }
+
+ public static void play(Mixer mixer) {
+ int res = 0;
+ try {
+ println("Getting SDL from mixer...");
+ source = (SourceDataLine) mixer.getLine(info);
+ println("Opening SDL...");
+ source.open(audioFormat);
+ println("Writing data to SDL...");
+ source.write(audioData, 0, audioData.length);
+ println("Starting SDL...");
+ source.start();
+ println("Now open your ears:");
+ println("You should have heard a short tone,");
+ println("followed by silence (no repeating tones).");
+ key();
+ source.write(audioData, 0, audioData.length);
+ println("Now you should have heard another short tone.");
+ println("If you did not hear a second tone, or more than 2 tones,");
+ println("the test is FAILED.");
+ println("otherwise, if you heard a total of 2 tones, the bug is fixed.");
+ key();
+ } catch (IllegalArgumentException iae) {
+ println("IllegalArgumentException: "+iae.getMessage());
+ println("Sound device cannot handle this audio format.");
+ println("ERROR: Test environment not correctly set up.");
+ if (source!=null) {
+ source.close();
+ source = null;
+ }
+ return;
+ } catch (LineUnavailableException lue) {
+ println("LineUnavailableException: "+lue.getMessage());
+ println("This is normal for some mixers.");
+ } catch (Exception e) {
+ println("Unexpected Exception: "+e.toString());
+ }
+ if (source != null) {
+ println("Stopping...");
+ source.stop();
+ println("Closing...");
+ source.close();
+ println("Closed.");
+ source = null;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ println("This is an interactive test for DirectAudio.");
+ println("If it's impossible to play data after an underun, the test fails.");
+ println("");
+ println("Make sure that you have speakers connected");
+ println("and that the system mixer is not muted.");
+ println("Also stop all other programs playing sounds:");
+ println("It has been seen that it alters the results.");
+ println("");
+ println("Press a key to start the test.");
+ key();
+ Mixer.Info[] mixers=null;
+
+ println(" ...using self-generated sine wave for playback");
+ audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
+ for (int i=0; i<audioData.length; i++) {
+ audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+ }
+ info = new DataLine.Info(SourceDataLine.class, audioFormat);
+
+ mixers = AudioSystem.getMixerInfo();
+ int succMixers = 0;
+ for (int i=0; i<mixers.length; i++) {
+ println(""+mixers[i]+":");
+ if ((mixers[i].getName()+mixers[i].getDescription()+mixers[i].getVendor()).indexOf("Direct") < 0) {
+ println(" ->not a DirectAudio Mixer!");
+ } else {
+ try {
+ Mixer mixer = AudioSystem.getMixer(mixers[i]);
+ if (!mixer.isLineSupported(info)) {
+ println(" ->doesn't support SourceDataLine!");
+ } else {
+ succMixers++;
+ println(" -> is getting tested.");
+ play(mixer);
+ }
+ } catch (Exception e) {
+ println(" -> Exception occured: "+e);
+ e.printStackTrace();
+ }
+ }
+ }
+ if (succMixers == 0) {
+ println("No DirectAudio mixers available! ");
+ println("Cannot run test.");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Mixers/DirectSoundUnderrunSilence/Test5032020.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,380 @@
+/*
+ * 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.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 5032020
+ * @summary Win: Direct Audio is silent after underrun
+ * @build DirectSoundUnderrunSilence
+ * @run main/manual Test5032020
+ */
+public class Test5032020 {
+
+ private static void init() throws Exception {
+ //*** Create instructions for the user here ***
+
+ String[] instructions =
+ {
+ "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 DirectSoundUnderrunSilence\".",
+ "4. Follow the instructions shown in the terminal window.",
+ "If no error occured during the test, and the java application ",
+ "in the termial exited successfully, 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" )
+ {
+ Test5032020.pass();
+ }
+ else
+ {
+ Test5032020.fail();
+ }
+ }
+
+ }// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Mixers/DisabledAssertionCrash.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 4991672
+ * @summary disabled assertion at maximum thread priority causes audio crash
+ * @run main/timeout=600 DisabledAssertionCrash
+ */
+public class DisabledAssertionCrash {
+ private static final int bufferSize = 1024;
+
+ public static void main(String[] args) {
+
+ System.out.println("This program hangs if priority is set,");
+ System.out.println("and assertion is in the code.");
+ System.out.println("The program crashes the entire Windows system");
+ System.out.println("if assertions are disabled.");
+ try {
+ Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
+ AudioFormat audioFormat = new AudioFormat(44100,16,1,true,true);
+ Line.Info sourceDataLineInfo = new DataLine.Info(SourceDataLine.class,audioFormat);
+ SourceDataLine sourceDataLine =
+ (SourceDataLine) AudioSystem.getLine(sourceDataLineInfo);
+ System.out.println("SourceDataLine: "+sourceDataLine);
+ sourceDataLine.open(audioFormat, bufferSize);
+ sourceDataLine.start();
+ Line.Info targetDataLineInfo =
+ new DataLine.Info(TargetDataLine.class,audioFormat);
+ TargetDataLine targetDataLine =
+ (TargetDataLine) AudioSystem.getLine(targetDataLineInfo);
+ System.out.println("TargetDataLine: "+targetDataLine);
+ targetDataLine.open(audioFormat, bufferSize);
+ targetDataLine.start();
+ byte[] data = new byte[bufferSize];
+
+ // execute for 20 seconds
+ float bufferTime = (((float) data.length) / audioFormat.getFrameSize()) / audioFormat.getFrameRate();
+ int count = (int) (20.0f / bufferTime);
+ System.out.println("Buffer time: "+(bufferTime * 1000)+" millis. "+count+" iterations.");
+ for (int i = 0; i < count; i++) {
+ int cnt = targetDataLine.read(data,0,data.length);
+ sourceDataLine.write(data,0,cnt);
+ assert cnt == data.length;
+ }
+ System.out.println("Successfully recorded/played "+count+" buffers. Passed");
+ } catch(LineUnavailableException lue) {
+ System.out.println("Audio hardware is not available!");
+ lue.printStackTrace();
+ System.out.println("Cannot execute test. NOT failed.");
+ } catch(IllegalArgumentException iae) {
+ System.out.println("No audio hardware is installed!");
+ iae.printStackTrace();
+ System.out.println("Test system not correctly setup.");
+ System.out.println("Cannot execute test. NOT failed.");
+ } catch(Exception e) {
+ System.out.println("Unexpected Exception: "+e);
+ e.printStackTrace();
+ System.out.println("Cannot execute test. NOT failed.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Mixers/NoSimpleInputDevice.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * 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.sampled.AudioSystem;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4936397
+ * @summary Verify that there'll be either SimpleInputDevice OR DirectAudioDevice
+ */
+public class NoSimpleInputDevice {
+
+ public static void main(String[] args) throws Exception {
+ out("4936397: Verify that there'll be either SimpleInputDevice OR DirectAudioDevice");
+ boolean foundSimpleInputDevice = false;
+ boolean foundDirectAudioDevice = false;
+
+ Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
+ for (int i = 0; i < aInfos.length; i++) {
+ try {
+ Mixer mixer = AudioSystem.getMixer(aInfos[i]);
+ String mixerClass = mixer.getClass().toString();
+ if (mixerClass.indexOf("SimpleInputDevice") >= 0) {
+ out("Found SimpleInputDevice: "+aInfos[i]);
+ foundSimpleInputDevice = true;
+ }
+ if (mixerClass.indexOf("DirectAudioDevice") >= 0) {
+ out("Found DirectAudioDevice: "+aInfos[i]);
+ foundDirectAudioDevice = true;
+ }
+ } catch (Exception e) {
+ out("Unexpected exception: "+e);
+ }
+ }
+ if (aInfos.length == 0) {
+ out("[No mixers available] - cannot exercise this test.");
+ } else {
+ if (foundSimpleInputDevice && foundDirectAudioDevice) {
+ out("Found both types of capture devices!");
+ throw new Exception("Test FAILED!");
+ }
+ out("Did not find both types of capture devices. Test passed");
+ }
+ }
+
+ 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/sampled/Mixers/PhantomMixers.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * 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.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 4794104
+ * @summary mixers are always present, independent of available soundcards
+ * @run main/manual PhantomMixers
+ */
+public class PhantomMixers {
+
+ public static void main(String args[]) throws Exception {
+ int SDLformats = 0;
+ int TDLformats = 0;
+ Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
+ for(int i=0; i<mixerInfo.length; i++){
+ Mixer.Info thisMixerInfo = mixerInfo[i];
+ System.out.println("Mixer #"+i+": "
+ + thisMixerInfo.getName()
+ + ": " + thisMixerInfo.getDescription());
+ Mixer mixer = AudioSystem.getMixer(thisMixerInfo);
+ Line.Info[] srcLineInfo = mixer.getSourceLineInfo();
+ Line.Info[] dstLineInfo = mixer.getTargetLineInfo();
+ int count = srcLineInfo.length + dstLineInfo.length;
+ System.out.print(" -> " + (srcLineInfo.length + dstLineInfo.length) + " line");
+ switch (count) {
+ case 0: System.out.println("s"); break;
+ case 1: System.out.println(""); break;
+ default: System.out.println("s:"); break;
+ }
+ int l;
+ for (l = 0; l < srcLineInfo.length; l++) {
+ System.out.println(" "+srcLineInfo[l].toString());
+ if (srcLineInfo[l].getLineClass() == SourceDataLine.class
+ && (srcLineInfo[l] instanceof DataLine.Info)) {
+ SDLformats += ((DataLine.Info) srcLineInfo[l]).getFormats().length;
+ }
+ }
+ for (l = 0; l < dstLineInfo.length; l++) {
+ System.out.println(" "+dstLineInfo[l].toString());
+ if (dstLineInfo[l].getLineClass() == TargetDataLine.class
+ && (dstLineInfo[l] instanceof DataLine.Info)) {
+ TDLformats += ((DataLine.Info) dstLineInfo[l]).getFormats().length;
+ }
+ }
+ }
+ if (mixerInfo.length == 0) {
+ System.out.println("[no mixers present]");
+ }
+ System.out.println(""+SDLformats+" total formats for SourceDataLines");
+ System.out.println(""+TDLformats+" total formats for TargetDataLines");
+ System.out.println("");
+ System.out.println("If there are audio devices correctly installed on your");
+ System.out.println("system, you should see at least one Mixer, and in total");
+ System.out.println("at least each one SourceDataLine and TargetDataLine, both");
+ System.out.println("providing at least one format.");
+ System.out.println("");
+ System.out.println("Now disable your soundcard and repeat the test.");
+ System.out.println("The corresponding mixer(s) should not provide any formats");
+ System.out.println("anymore. If you disable all available soundcards");
+ System.out.println("on your computer, the number of formats above should be");
+ System.out.println("0 for both line types (although mixers are allowed to exist).");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Mixers/PlugHwMonoAnd8bitAvailable.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,163 @@
+/*
+ * 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 javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 5013897
+ * @summary Verify that plughw: provides mono and 8-bit lines
+ */
+public class PlugHwMonoAnd8bitAvailable {
+ static int failed = 0;
+ static int testedFormats = 0;
+
+ public static void main(String[] args) throws Exception {
+ out("5013897: Verify that plughw: provides mono and 8-bit lines");
+
+ Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
+ for (int i = 0; i < aInfos.length; i++) {
+ try {
+ Mixer mixer = AudioSystem.getMixer(aInfos[i]);
+ out("Mixer "+aInfos[i]);
+ if (aInfos[i].getName().contains("plughw")) {
+ checkLines(mixer, mixer.getSourceLineInfo());
+ checkLines(mixer, mixer.getTargetLineInfo());
+ } else {
+ out(" -> not plughw, ignored.");
+ }
+ } catch (Exception e) {
+ out("Unexpected exception when getting a mixer: "+e);
+ }
+ }
+ if (testedFormats == 0) {
+ out("[No appropriate lines available] - cannot exercise this test.");
+ } else {
+ if (failed>0) {
+ throw new Exception("Test FAILED!");
+ }
+ out("Successfully verified "+testedFormats+" formats.");
+ out("Test passed");
+ }
+ }
+
+ public static void checkLines(Mixer mixer, Line.Info[] infos) {
+ for (int i = 0; i<infos.length; i++) {
+ try {
+ System.out.println(" Line "+infos[i]+" (max. "+mixer.getMaxLines(infos[i])+" simultaneously): ");
+ if (infos[i] instanceof DataLine.Info) {
+ DataLine.Info info = (DataLine.Info) infos[i];
+ int thisTestedFormats = testedFormats;
+ int thisFailed = failed;
+ AudioFormat[] formats = info.getFormats();
+ for (int f = 0; f < formats.length; f++) {
+ if (formats[f].getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
+ || formats[f].getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED)) {
+ try {
+ if (formats[f].getSampleSizeInBits() > 16) {
+ // if a bit size larger than 16 is available, also 16-bit must be there
+ checkFormat(formats, getOtherBits(formats[f], 16));
+ } else
+ if (formats[f].getSampleSizeInBits() > 8) {
+ // if a bit size larger than 8 is available, also 8-bit must be there
+ checkFormat(formats, getOtherBits(formats[f], 8));
+ }
+ if (formats[f].getChannels() > 2) {
+ // if more than 2 channels, also 2 channels must be there
+ checkFormat(formats, getOtherChannels(formats[f], 2));
+ } else
+ if (formats[f].getChannels() > 1) {
+ // if more than 1 channel, also 1 channel must be there
+ checkFormat(formats, getOtherChannels(formats[f], 1));
+ }
+ } catch (Exception e1) {
+ out(" Unexpected exception when getting a format: "+e1);
+ }
+ }
+ }
+ if (testedFormats - thisTestedFormats == 0) {
+ out(" -->could not test any formats");
+ } else if (failed - thisFailed == 0) {
+ out(" -->"+(testedFormats - thisTestedFormats)+" formats tested OK");
+ }
+
+ } else {
+ out(" --> not a DataLine");
+ }
+ } catch (Exception e) {
+ out(" Unexpected exception when getting a line: "+e);
+ }
+ }
+ }
+
+ public static void checkFormat(AudioFormat[] formats, AudioFormat format) {
+ testedFormats++;
+ for (int i = 0; i < formats.length; i++) {
+ if (formats[i].matches(format)) {
+ return;
+ }
+ }
+ out(" ## expected this format: "+format
+ +" ("+format.getChannels()+" channels, "
+ +"frameSize="+format.getFrameSize()+", "
+ +(format.isBigEndian()?"big endian":"little endian")
+ +")");
+ failed++;
+ }
+
+ // only works for PCM encodings
+ public static AudioFormat getOtherBits(AudioFormat format, int newBits) {
+ boolean isSigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED);
+ return new AudioFormat(format.getSampleRate(),
+ newBits,
+ format.getChannels(),
+ isSigned,
+ (newBits>8)?format.isBigEndian():false);
+ }
+
+ // only works for PCM encodings
+ public static AudioFormat getOtherChannels(AudioFormat format, int newChannels) {
+ int newFrameSize;
+ if (newChannels <= 0 || format.getChannels() <= 0 || format.getFrameSize() <= 0) {
+ newFrameSize = -1;
+ } else {
+ newFrameSize = format.getFrameSize() / format.getChannels() * newChannels;
+ }
+ return new AudioFormat(format.getEncoding(),
+ format.getSampleRate(),
+ format.getSampleSizeInBits(),
+ newChannels,
+ newFrameSize,
+ format.getFrameRate(),
+ format.isBigEndian());
+ }
+
+
+ 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/sampled/Mixers/UnexpectedIAE.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * 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 javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4964288
+ * @summary Unexpected IAE raised while getting TargetDataLine
+ */
+public class UnexpectedIAE {
+
+ public static void main(String argv[]) throws Exception {
+ boolean success = true;
+
+ Mixer.Info [] infos = AudioSystem.getMixerInfo();
+
+ for (int i=0; i<infos.length; i++) {
+ Mixer mixer = AudioSystem.getMixer(infos[i]);
+ System.out.println("Mixer is: " + mixer);
+ Line.Info [] target_line_infos = mixer.getTargetLineInfo();
+ for (int j = 0; j < target_line_infos.length; j++) {
+ try {
+ System.out.println("Trying to get:" + target_line_infos[j]);
+ mixer.getLine(target_line_infos[j]);
+ } catch (IllegalArgumentException iae) {
+ System.out.println("Unexpected IllegalArgumentException raised:");
+ iae.printStackTrace();
+ success = false;
+ } catch (LineUnavailableException lue) {
+ System.out.println("Unexpected LineUnavailableException raised:");
+ lue.printStackTrace();
+ success = false;
+ }
+ }
+ }
+ if (success) {
+ System.out.println("Test passed");
+ } else {
+ throw new Exception("Test FAILED");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Recording/TargetDataLineFlush.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,204 @@
+/*
+ * 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.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 4836433
+ * @summary Windows: TargetDataLine.flush() does not work. Since this test has
+ * some real-time variance, I disabled it by making it a manual test.
+ * @run main/manual TargetDataLineFlush
+ */
+public class TargetDataLineFlush {
+ TargetDataLine inLine;
+ int SAMPLE_RATE = 11025;
+ int BUFFER_MILLIS = 1000;
+ int WAIT_MILLIS;
+ int BITS = 16;
+ int CHANNELS = 2;
+ int bufferSize;
+ AudioFormat format;
+ Mixer.Info[] mixers;
+ static boolean failed = false;
+
+ public TargetDataLineFlush() {
+ mixers = AudioSystem.getMixerInfo();
+ }
+
+ private void init() {
+ // float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian
+ format = new AudioFormat( (float) SAMPLE_RATE, BITS, CHANNELS, true, false);
+ bufferSize = SAMPLE_RATE * BUFFER_MILLIS / 1000 * format.getFrameSize();
+ }
+
+ boolean openInputLine(int num) throws LineUnavailableException {
+ init();
+ DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); // format is an AudioFormat object
+ // Obtain and open a outLine.
+ if (num < 0) {
+ if (!AudioSystem.isLineSupported(info)) {
+ System.out.println("TargetDataLine is not supported by default mixer.");
+ return false;
+ }
+ inLine = (TargetDataLine) AudioSystem.getLine(info);
+ } else {
+ Mixer mixer = AudioSystem.getMixer(mixers[num]);
+ if (!mixer.isLineSupported(info)) {
+ System.out.println("TargetDataLine is not supported by this mixer.");
+ return false;
+ }
+ inLine = (TargetDataLine) mixer.getLine(info);
+ }
+ inLine.open(format, bufferSize);
+ /*if (Math.abs(inLine.getBufferSize() - bufferSize) > 100) {
+ inLine.close();
+ System.out.println("TargetDataLine does not support buffer size of "+bufferSize+" bytes!");
+ return false;
+ }*/
+ bufferSize = inLine.getBufferSize();
+ /* 3/4 of buffer size ot wait */
+ WAIT_MILLIS = (int) (bufferSize / format.getFrameSize() * 750 / format.getFrameRate());
+ System.out.println("Buffer size: "+bufferSize+" bytes = "
+ +((int) (bufferSize / format.getFrameSize() * 750 / format.getFrameRate()))+" millis");
+ return true;
+ }
+
+ private String available() {
+ int avail = inLine.available();
+ int availMillis = (int) (avail / format.getFrameSize() * 1000 / format.getFrameRate());
+ return "available "+avail+" bytes = "+availMillis+" millis";
+ }
+
+ private boolean recordSound(int num) throws LineUnavailableException {
+ if (!openInputLine(num)) {
+ return false;
+ }
+ byte data[] = new byte[1000];
+ try {
+ System.out.println("Got line: "+inLine);
+ System.out.println("Start recording" );
+ inLine.start();
+ System.out.print("Warm-up...");
+ //System.out.print("Waiting 500 millis...");
+ try { Thread.sleep(500); } catch (InterruptedException ie) {}
+ //System.out.println("done. "+available());
+ //System.out.print("Reading all data...");
+ int avail0 = inLine.available();
+ if (avail0 == 0) {
+ System.out.println("Problem: TargetDataLine did not deliver any data!");
+ System.out.println("Not a test failure, but serious failure nonetheless.");
+ } else {
+ while ((avail0 -= inLine.read(data, 0, Math.min(data.length, avail0))) > 0);
+ System.out.println("done. "+available());
+ System.out.print("Waiting "+(WAIT_MILLIS)+" millis...");
+ try { Thread.sleep(WAIT_MILLIS); } catch (InterruptedException ie) {}
+ int avail1 = inLine.available();
+ System.out.println("done. "+available());
+
+ System.out.print("Flushing...");
+ inLine.flush();
+ System.out.println("done. "+available());
+ System.out.print("Waiting "+(WAIT_MILLIS)+" millis...");
+ try { Thread.sleep(WAIT_MILLIS); } catch (InterruptedException ie) {}
+ int avail2 = inLine.available();
+ System.out.println("done. "+available());
+ if (avail2 > avail1) {
+ failed = true;
+ System.out.println("Failed: Flushing with native flush() should "
+ +"result in fewer bytes available.");
+ }
+ if (avail2 == 0) {
+ failed = true;
+ System.out.println("Failed: Recording after flush() did not work at all!");
+ }
+ }
+ } finally {
+ System.out.print("Closing line....");
+ inLine.close();
+ System.out.println("done");
+ }
+ return true;
+ }
+
+ public void runTests(int testRuns) {
+ if (mixers.length > 0) {
+ for (int num = -1; num < mixers.length; num++) {
+ try {
+ if (num<0) {
+ System.out.println("------Using default line...." );
+ } else {
+ System.out.println("------Using line "+num+" from mixer "+mixers[num]+"...");
+ }
+ for (int testRun = 0; testRun < testRuns; testRun++) {
+ if (testRuns>1) {
+ System.out.println("--Run "+(testRun+1)+"/"+testRuns+":");
+ }
+ if (!recordSound(num)) {
+ break;
+ }
+ }
+ } catch (Exception ex) {
+ System.out.println("Caught " + ex );
+ }
+ System.out.println("------------------------------------------------------");
+ if (failed) {
+ break;
+ }
+ }
+ } else {
+ System.out.println("No mixers present. Cannot execute this test.");
+ }
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("Test TargetDataLineFlush");
+ System.out.println("This verifies that TargetDataLine.flush() actually");
+ System.out.println("flushes the native buffers. This is done by");
+ System.out.println("comparing a manual flush (i.e. just discarding");
+ System.out.println("everything that is currently available in the TargetDataLine)");
+ System.out.println("to a flushed line");
+ TargetDataLineFlush app = new TargetDataLineFlush();
+ int testRuns = 1;
+ if (args.length > 0) {
+ try {
+ testRuns = Integer.parseInt(args[0]);
+ } catch (NumberFormatException nfe) {
+ System.out.println("Usage: java TargetDataLineFlush [number of runs]");
+ System.out.println("Parameters ignored.");
+ }
+ }
+ app.runTests(testRuns);
+ if (failed) {
+ throw new Exception("Test FAILED");
+ }
+ // test always passes if it gets here
+ System.out.println("Test PASSED");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/AIFFCp037.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * 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.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4369044
+ * @summary javax.sound.sampled.AudioSystem.getAudioInputStream() works wrong
+ * with Cp037
+ */
+public class AIFFCp037 {
+
+ public static void main(String args[]) throws Exception {
+ System.setProperty("file.encoding", "Cp037");
+ // try to read this file with Cp037 encoding
+ AudioSystem.getAudioInputStream(new ByteArrayInputStream(SHORT_AIFF));
+ System.out.println(" test passed.");
+ }
+
+ public static String getString(byte b) {
+ //String res = Integer.toHexString(b & 0xFF).toUpperCase();
+ //while (res.length()<2) res="0"+res;
+ //return res;
+ return String.valueOf(b);
+ }
+
+
+ public static void printFile(String filename) throws Exception {
+ File file = new File(filename);
+ FileInputStream fis = new FileInputStream(file);
+ byte[] data = new byte[(int) file.length()];
+ fis.read(data);
+ String s = "";
+ for (int i=0; i<data.length; i++) {
+ s+=getString(data[i])+", ";
+ if (s.length()>72) {
+ System.out.println(s);
+ s="";
+ }
+ }
+ System.out.println(s);
+ }
+
+ public static byte[] SHORT_AIFF = {
+ 70, 79, 82, 77, 0, 0, 4, -54, 65, 73, 70, 70, 67, 79, 77, 77, 0, 0, 0, 18,
+ 0, 1, 0, 0, 2, 78, 0, 16, 64, 12, -84, 68, 0, 0, 0, 0, 0, 0, 83, 83, 78,
+ 68, 0, 0, 4, -92, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -2, 0, -2, 0, 0, 0, 0, 0,
+ -3, 0, -5, 0, -2, 0, 3, 0, 1, 0, -3, 0, -5, 0, -6, 0, -6, 0, -5, 0, -2, 0,
+ -2, 0, -5, 0, -6, 0, -3, 0, 0, 0, 0, 0, -3, 0, -5, 0, -6, 0, -8, 0, -5, 0,
+ 1, 0, 4, 0, 1, 0, -5, 0, -8, 0, -3, 0, 3, 0, 4, 0, 0, 0, -8, 0, -11, 0, -8,
+ 0, -3, 0, 0, 0, 0, 0, 1, 0, 0, 0, -5, 0, -9, 0, -8, 0, 0, 0, 6, 0, 7, 0,
+ 0, 0, -8, 0, -11, 0, -8, 0, 0, 0, 4, 0, 6, 0, 3, 0, -2, 0, -5, 0, -5, 0,
+ 0, 0, 6, 0, 6, 0, 1, 0, -5, 0, -3, 0, 1, 0, 6, 0, 6, 0, 1, 0, -3, 0, -3,
+ 0, 0, 0, 3, 0, 3, 0, 0, 0, -3, 0, -2, 0, 3, 0, 6, 0, 4, 0, 0, 0, -2, 0, -2,
+ 0, 1, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -3, 0, 1, 0, 6,
+ 0, 6, 0, 1, 0, 0, 0, 1, 0, 0, 0, -2, 0, -2, 0, 3, 0, 4, 0, 0, 0, -5, 0, -3,
+ 0, 1, 0, 4, 0, 4, 0, 0, 0, -2, 0, 1, 0, 1, 0, -2, 0, -6, 0, -6, 0, -2, 0,
+ 6, 0, 7, 0, 4, 0, 0, 0, -5, 0, -6, 0, -5, 0, 0, 0, 4, 0, 4, 0, 0, 0, -5,
+ 0, -8, 0, -8, 0, -5, 0, 1, 0, 3, 0, 1, 0, -3, 0, -6, 0, -6, 0, -5, 0, -5,
+ 0, -3, 0, 1, 0, 3, 0, 1, 0, -2, 0, -5, 0, -5, 0, -5, 0, -3, 0, 3, 0, 6, 0,
+ 6, 0, 0, 0, -3, 0, -3, 0, 0, 0, 1, 0, 0, 0, 3, 0, 4, 0, 0, 0, -3, 0, -5,
+ 0, -2, 0, 1, 0, -2, 0, -2, 0, 1, 0, 4, 0, 1, 0, -3, 0, -2, 0, 0, 0, 0, 0,
+ -3, 0, -6, 0, -5, 0, 0, 0, 3, 0, 0, 0, -3, 0, -5, 0, -5, 0, -2, 0, -2, 0,
+ -5, 0, -6, 0, -3, 0, 1, 0, 1, 0, -2, 0, -8, 0, -8, 0, -3, 0, 1, 0, 3, 0,
+ 1, 0, -5, 0, -8, 0, -6, 0, -2, 0, 3, 0, 4, 0, -2, 0, -5, 0, -6, 0, -3, 0,
+ -2, 0, -2, 0, -2, 0, -2, 0, -3, 0, -5, 0, -6, 0, -5, 0, -2, 0, 0, 0, 0, 0,
+ -2, 0, -3, 0, -5, 0, -5, 0, -3, 0, -3, 0, -2, 0, -2, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 1, 0, 1, 0, -2, 0, -5, 0, -3, 0, 1, 0, 4, 0, 6, 0, 4, 0, 1, 0, 0, 0,
+ 0, 0, 3, 0, 4, 0, 1, 0, -3, 0, -3, 0, 1, 0, 6, 0, 4, 0, 1, 0, -3, 0, -5,
+ 0, -2, 0, 3, 0, 6, 0, 7, 0, 1, 0, -5, 0, -5, 0, 1, 0, 7, 0, 6, 0, 3, 0, 1,
+ 0, -2, 0, -5, 0, -5, 0, -2, 0, 3, 0, 3, 0, 3, 0, 0, 0, -3, 0, -5, 0, -3,
+ 0, 0, 0, 6, 0, 9, 0, 4, 0, -2, 0, -6, 0, -5, 0, -2, 0, 3, 0, 4, 0, 3, 0,
+ -2, 0, -6, 0, -3, 0, 1, 0, 3, 0, -3, 0, -6, 0, 0, 0, 4, 0, 1, 0, -6, 0, -9,
+ 0, -5, 0, 1, 0, 1, 0, 0, 0, -2, 0, -3, 0, -5, 0, -6, 0, -5, 0, 0, 0, 3, 0,
+ 3, 0, -2, 0, -6, 0, -6, 0, -3, 0, -2, 0, -2, 0, -5, 0, -6, 0, -5, 0, -2,
+ 0, 0, 0, -2, 0, -3, 0, -3, 0, -3, 0, -2, 0, 0, 0, 1, 0, 0, 0, -2, 0, -2,
+ 0, -3, 0, -5, 0, -5, 0, -2, 0, 0, 0, 3, 0, 3, 0, 0, 0, -3, 0, -3, 0, 0, 0,
+ -2, 0, -5, 0, -3, 0, 0, 0, 1, 0, -3, 0, -8, 0, -6, 0, -2, 0, -2, 0, -6, 0,
+ -6, 0, -5, 0, -3, 0, -3, 0, -6, 0, -6, 0, -3, 0, -3, 0, -3, 0, -3, 0, 0,
+ 0, 1, 0, -3, 0, -6, 0, -3, 0, 1, 0, 0, 0, -6, 0, -9, 0, -9, 0, -6, 0, -2,
+ 0, 1, 0, 3, 0, -3, 0, -5, 0, -3, 0, -2, 0, -3, 0, -6, 0, -5, 0, -2, 0, -2,
+ 0, -5, 0, -5, 0, -2, 0, -2, 0, -5, 0, -6, 0, -6, 0, -2, 0, -2, 0, -2, 0,
+ -3, 0, -5, 0, -5, 0, -3, 0, 1, 0, 0, 0, 1, 0, 1, 0, 3, 0, 6, 0, 6, 0, 3,
+ 0, -6, 0, -12, 0, -8, 0, 1, 0, 9, 0, 7, 0, 1, 0, -3, 0, 0, 0, 3, 0, 0, 0,
+ 0, 0, 3, 0, 6, 0, 7, 0, 3, 0, -3, 0, -5, 0, 0, 0, 4, 0, 4, 0, 3, 0, 1, 0,
+ 3, 0, 3, 0, 0, 0, -2, 0, 0, 0, 1, 0, 1, 0, 1, 0, 3, 0, 3, 0, 1, 0, 0, 0,
+ 0, 0, 3, 0, 1, 0, -2, 0, -2, 0, 1, 0, 1, 0, -3, 0, -3, 0, 0, 0, 4, 0, 6,
+ 0, 6, 0, 3, 0, -3, 0, -8, 0, -5, 0, 1, 0, 3, 0, 1, 0, 1, 0, 0, 0, -3, 0,
+ -6, 0, -5, 0, 1, 0, 3, 0, -2, 0, -3, 0, 0, 0, 1, 0, 1, 0, -3, 0, -5, 0, -2,
+ 0, -2, 0, -2, 0, 0, 0, 1, 0, 1, 0, -2, 0, -5, 0, -8, 0, -6, 0, -5, 0, -2,
+ 0, 1, 0, 0, 0, -5, 0, -6, 0, 0, 0, 4, 0, 1, 0, -5, 0, -5, 0, -3, 0, -2, 0,
+ -3, 0, -3, 0, 0, 0, 0, 0, -2, 0, -3, 0, -2, 0, 1, 0, -2, 0, -5, 0, -3, 0,
+ 0, 0, 3, 0, 0, 0, -3, 0, -3, 0, -3, 0, -3, 0, -3, 0, 0, 0, 3, 0, 4, 0, -2,
+ 0, -8, 0, -8, 0, -5, 0, 3, 0, 3, 0, -2, 0, -6, 0, -8, 0, -3, 0, 1, 0, 0,
+ 0, -5, 0, -5, 0, -2, 0, -2, 0, -3, 0, -5, 0, -3, 0, 0, 0, 0, 0, -2, 0, -5,
+ 0, -6, 0, -5, 0, -3, 0, 0, 0, 0, 0, -3, 0, -3, 0, -5, 0, -5, 0, -6, 0, -6,
+ 0, -6, 0, -5, 0, 0, 0, 1, 0, 0, 0, -5, 0, -6, 0, -5, 0, -2, 0, -2, 0, -3,
+ 0, -5, 0, -8, 0, -9, 0, -6, 0, -2, 0, 0, 0, -2, 0, -5, 0, -5, 0, -2, 0, 3,
+ 0, 4, 0, 0, 0, -2, 0, -2, 0, 1, 0, 1, 0, 1, 0, 3, 0
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/AIFFLargeHeader.java Wed Jul 05 22:25:59 2017 +0200
@@ -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.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4399551
+ * @summary Repost of bug candidate: cannot replay aif file. AIFF headers were
+ * checked for certain size also tests that ulaw encoded AIFC files can
+ * be read.
+ */
+public class AIFFLargeHeader {
+
+ public static void main(String args[]) throws Exception {
+ System.out.println();
+ System.out.println();
+ System.out.println("4399551: Repost of bug candidate: cannot replay aif file (Review ID: 108108)");
+ // try to read this file
+ AudioSystem.getAudioInputStream(new ByteArrayInputStream(SHORT_AIFC_ULAW));
+ System.out.println(" test passed.");
+ }
+
+ public static String getString(byte b) {
+ //String res = Integer.toHexString(b & 0xFF).toUpperCase();
+ //while (res.length()<2) res="0"+res;
+ //return res;
+ return String.valueOf(b);
+ }
+
+
+ public static void printFile(String filename) throws Exception {
+ File file = new File(filename);
+ FileInputStream fis = new FileInputStream(file);
+ byte[] data = new byte[(int) file.length()];
+ fis.read(data);
+ String s = "";
+ for (int i=0; i<data.length; i++) {
+ s+=getString(data[i])+", ";
+ if (s.length()>72) {
+ System.out.println(s);
+ s="";
+ }
+ }
+ System.out.println(s);
+ }
+
+ public static byte[] SHORT_AIFC_ULAW = {
+ 70, 79, 82, 77, 0, 0, 2, 50, 65, 73, 70, 67, 70, 86, 69, 82, 0, 0, 0, 4,
+ -94, -128, 81, 64, 67, 79, 77, 77, 0, 0, 0, 30, 0, 1, 0, 1, 118, -9, 0, 16,
+ 64, 12, -84, 68, 0, 0, 0, 0, 0, 0, 117, 108, 97, 119, 7, 117, 110, 107, 110,
+ 111, 119, 110, 83, 83, 78, 68, 0, 0, 1, -13, 0, 0, 0, 0, 0, 0, 0, 0, 103,
+ 103, 103, -1, -1, 91, 77, 103, -45, -25, 91, 77, 73, 73, 77, 103, 103, 77,
+ 73, 91, -1, -1, 91, 77, 73, 65, 77, -25, -51, -25, 77, 65, 91, -45, -51,
+ -1, 65, 58, 65, 91, -1, -1, -25, -1, 77, 62, 65, -1, -59, -63, -1, 65, 58,
+ 65, -1, -51, -59, -45, 103, 77, 77, -1, -59, -59, -25, 77, 91, -25, -59,
+ -59, -25, 91, 91, -1, -45, -45, -1, 91, 103, -45, -59, -51, -1, 103, 103,
+ -25, -25, -45, -45, -1, -1, -1, -1, 103, 91, -25, -59, -59, -25, -1, -25,
+ -1, 103, 103, -45, -51, -1, 77, 91, -25, -51, -51, -1, 103, -25, -25, 103,
+ 73, 73, 103, -59, -63, -51, -1, 77, 73, 77, -1, -51, -51, -1, 77, 65, 65,
+ 77, -25, -45, -25, 91, 73, 73, 77, 77, 91, -25, -45, -25, 103, 77, 77, 77,
+ 91, -45, -59, -59, -1, 91, 91, -1, -25, -1, -45, -51, -1, 91, 77, 103, -25,
+ 103, 103, -25, -51, -25, 91, 103, -1, -1, 91, 73, 77, -1, -45, -1, 91, 77,
+ 77, 103, 103, 77, 73, 91, -25, -25, 103, 65, 65, 91, -25, -45, -25, 77, 65,
+ 73, 103, -45, -51, 103, 77, 73, 91, 103, 103, 103, 103, 91, 77, 73, 77, 103,
+ -1, -1, 103, 91, 77, 77, 91, 91, 103, 103, -1, -25, -25, -1, -25, -25, 103,
+ 77, 91, -25, -51, -59, -51, -25, -1, -1, -45, -51, -25, 91, 91, -25, -59,
+ -51, -25, 91, 77, 103, -45, -59, -63, -25, 77, 77, -25, -63, -59, -45, -25,
+ 103, 77, 77, 103, -45, -45, -45, -1, 91, 77, 91, -1, -59, -68, -51, 103,
+ 73, 77, 103, -45, -51, -45, 103, 73, 91, -25, -45, 91, 73, -1, -51, -25,
+ 73, 62, 77, -25, -25, -1, 103, 91, 77, 73, 77, -1, -45, -45, 103, 73, 73,
+ 91, 103, 103, 77, 73, 77, 103, -1, 103, 91, 91, 91, 103, -1, -25, -1, 103,
+ 103, 91, 77, 77, 103, -1, -45, -45, -1, 91, 91, -1, 103, 77, 91, -1, -25,
+ 91, 65, 73, 103, 103, 73, 73, 77, 91, 91, 73, 73, 91, 91, 91, 91, -1, -25,
+ 91, 73, 91, -25, -1, 73, 62, 62, 73, 103, -25, -45, 91, 77, 91, 103, 91,
+ 73, 77, 103, 103, 77, 77, 103, 103, 77, 73, 73, 103, 103, 103, 91, 77, 77,
+ 91, -25, -1, -25, -25, -45, -59, -59, -45, 73, 56, 65, -25, -68, -63, -25,
+ 91, -1, -45, -1, -1, -45, -59, -63, -1, 103, 103, -25, -25, 103, 91, -1,
+ -45, -51, -25, 103, 91, 91, 103, -25, -25, -25, 103, 73, 77, -1, -51, -45,
+ 103, 91, 103, -25, -1, 91, 91, 91, -1, -45, -51, -25, 91, 77, 103, -1, -1,
+ 91, -1, -1, -1, 103, 91, 91, 73, 77, 103, -25, -25, 103, 91, 103, 103, 103,
+ -1, -45, -1, 77, 77, -1
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/Aiff12bit.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4895934
+ * @summary AudioInputStream.getFrameLength returns wrong value for 12-bit AIFF
+ * file
+ */
+public class Aiff12bit {
+
+ public static void test(byte[] file) throws Exception {
+ InputStream inputStream = new ByteArrayInputStream(file);
+ AudioFileFormat aff = AudioSystem.getAudioFileFormat(inputStream);
+
+ if (aff.getFormat().getSampleSizeInBits() != 12) {
+ throw new Exception("Wrong sample size. test FAILED");
+ }
+ if (aff.getFormat().getFrameSize() != 2) {
+ throw new Exception("Wrong frame size. test FAILED");
+ }
+ if (aff.getFrameLength() != 100) {
+ throw new Exception("Wrong file length. test FAILED");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ test(AIFF_12BIT);
+
+ System.out.println("Test passed.");
+ }
+
+ public static byte[] AIFF_12BIT = {
+ 70, 79, 82, 77, 0, 0, 0, -10, 65, 73, 70, 70, 67, 79, 77, 77,
+ 0, 0, 0, 18, 0, 1, 0, 0, 0, 100, 0, 12, 64, 8, -6, 0,
+ 0, 0, 0, 0, 0, 0, 83, 83, 78, 68, 0, 0, 0, -48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 48, 0, 64,
+ 0, 80, 0, 96, 0, 112, 0, -128, 0, -112, 0, -96, 0, -80, 0, -64,
+ 0, -48, 0, -32, 0, -16, 1, 0, 1, 16, 1, 32, 1, 48, 1, 64,
+ 1, 80, 1, 96, 1, 112, 1, -128, 1, -112, 1, -96, 1, -80, 1, -64,
+ 1, -48, 1, -32, 1, -16, 2, 0, 2, 16, 2, 32, 2, 48, 2, 64,
+ 2, 80, 2, 96, 2, 112, 2, -128, 2, -112, 2, -96, 2, -80, 2, -64,
+ 2, -48, 2, -32, 2, -16, 3, 0, 3, 16, 3, 32, 3, 48, 3, 64,
+ 3, 80, 3, 96, 3, 112, 3, -128, 3, -112, 3, -96, 3, -80, 3, -64,
+ 3, -48, 3, -32, 3, -16, 4, 0, 4, 16, 4, 32, 4, 48, 4, 64,
+ 4, 80, 4, 96, 4, 112, 4, -128, 4, -112, 4, -96, 4, -80, 4, -64,
+ 4, -48, 4, -32, 4, -16, 5, 0, 5, 16, 5, 32, 5, 48, 5, 64,
+ 5, 80, 5, 96, 5, 112, 5, -128, 5, -112, 5, -96, 5, -80, 5, -64,
+ 5, -48, 5, -32, 5, -16, 6, 0, 6, 16, 6, 32, 6, 48,
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/AuNotSpecified.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * 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.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4940459
+ * @summary AudioInputStream.getFrameLength() returns 0 instead of NOT_SPECIFIED
+ */
+public class AuNotSpecified {
+ public static boolean failed = false;
+
+ public static void main(String[] params) throws Exception {
+
+ AudioInputStream is =
+ AudioSystem.getAudioInputStream(new
+ ByteArrayInputStream(new byte[] {
+ (byte)0x2E, (byte)0x73, (byte)0x6E, (byte)0x64, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x18,
+ (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x03,
+ (byte)0x00, (byte)0x00, (byte)0x1F, (byte)0x40, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x01,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00,
+ }));
+ if (is.getFrameLength() != AudioSystem.NOT_SPECIFIED) {
+ System.out.println("frame length should be NOT_SPECIFIED, but is: "+is.getFrameLength());
+ failed=true;
+ }
+ //assertTrue(is.getFrameLength() == AudioSystem.NOT_SPECIFIED);
+ //assertTrue(is.read(new byte[8]) == 8);
+ //assertTrue(is.read(new byte[2]) == -1);
+ if (failed) throw new Exception("Test FAILED!");
+ System.out.println("Test Passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/AuZeroLength.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * 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.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4629669
+ * @summary AU file reader: problems with empty files
+ */
+public class AuZeroLength {
+
+ public static String getString(byte b) {
+ //String res = Integer.toHexString(b & 0xFF).toUpperCase();
+ //while (res.length()<2) res="0"+res;
+ //return res;
+ return String.valueOf(b);
+ }
+
+
+ public static void printFile(String filename) throws Exception {
+ File file = new File(filename);
+ FileInputStream fis = new FileInputStream(file);
+ byte[] data = new byte[(int) file.length()];
+ fis.read(data);
+ String s = "";
+ for (int i=0; i<data.length; i++) {
+ s+=getString(data[i])+", ";
+ if (s.length()>72) {
+ System.out.println(s);
+ s="";
+ }
+ }
+ System.out.println(s);
+ }
+
+ public static void test(byte[] file) throws Exception {
+ InputStream inputStream = new ByteArrayInputStream(file);
+ AudioFileFormat aff = AudioSystem.getAudioFileFormat(inputStream);
+
+ if (aff.getFrameLength() != 0) {
+ throw new Exception("File length is "+aff.getFrameLength()+" instead of 0. test FAILED");
+ }
+ System.out.println(aff.getType()+" file length is 0.");
+ }
+
+ public static void main(String[] args) throws Exception {
+ test(ZERO_AU);
+ test(ZERO_WAV);
+ test(ZERO_AIFF);
+
+ System.out.println("Test passed.");
+ }
+
+ public static byte[] ZERO_AU = {
+ 46, 115, 110, 100, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -84, 68, 0,
+ 0, 0, 1, 116, 101, 115, 116, 46, 119, 97, 118
+ };
+
+ public static byte[] ZERO_WAV = {
+ 82, 73, 70, 70, 36, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0,
+ 0, 1, 0, 1, 0, 68, -84, 0, 0, -120, 88, 1, 0, 2, 0, 16, 0, 100, 97, 116,
+ 97, 0, 0, 0, 0
+ };
+
+ public static byte[] ZERO_AIFF = {
+ 70, 79, 82, 77, 0, 0, 0, 46, 65, 73, 70, 70, 67, 79, 77, 77, 0, 0, 0, 18,
+ 0, 1, 0, 0, 0, 0, 0, 16, 64, 14, -84, 68, 0, 0, 0, 0, 0, 0, 83, 83, 78, 68,
+ 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/OpenWaveFile.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,125 @@
+/*
+ * 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.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4489272
+ * @summary AudioSystem.getAudioFileFormat() fails for InputStream, but works
+ * for URL
+ */
+public class OpenWaveFile {
+
+ static void check(Object source) throws Exception {
+ AudioFileFormat aff2 = null;
+ if (source instanceof File) {
+ aff2 = AudioSystem.getAudioFileFormat((File) source);
+ }
+ else if (source instanceof InputStream) {
+ aff2 = AudioSystem.getAudioFileFormat((InputStream) source);
+ }
+ else if (source instanceof URL) {
+ aff2 = AudioSystem.getAudioFileFormat((URL) source);
+ } else throw new Exception("wrong source. Test FAILED");
+ System.out.println("Got: "+aff2);
+ if (aff2.getFormat().getSampleSizeInBits()==-1) {
+ throw new Exception("wrong audio format. Test FAILED");
+ }
+ }
+
+ public static void main(String args[]) throws Exception {
+ //check(new File(args[0]));
+ //check(new URL("file", "", args[0]));
+ check(new ByteArrayInputStream(SHORT_AU));
+ check(new ByteArrayInputStream(SHORT_WAVE));
+ check(new ByteArrayInputStream(SHORT_AIFF));
+ System.out.println("Test passed.");
+
+ //printFile(args[0]);
+ }
+
+ public static String getString(byte b) {
+ //String res = Integer.toHexString(b & 0xFF).toUpperCase();
+ //while (res.length()<2) res="0"+res;
+ //return res;
+ return String.valueOf(b);
+ }
+
+
+ public static void printFile(String filename) throws Exception {
+ File file = new File(filename);
+ FileInputStream fis = new FileInputStream(file);
+ byte[] data = new byte[(int) file.length()];
+ fis.read(data);
+ String s = "";
+ for (int i=0; i<data.length; i++) {
+ s+=getString(data[i])+", ";
+ if (s.length()>72) {
+ System.out.println(s);
+ s="";
+ }
+ }
+ System.out.println(s);
+ }
+
+ public static byte[] SHORT_WAVE = {
+ 82, 73, 70, 70, -120, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0,
+ 0, 0, 1, 0, 1, 0, 34, 86, 0, 0, 34, 86, 0, 0, 1, 0, 8, 0, 100, 97, 116, 97,
+ 100, 0, 0, 0, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, 127, 127, -128, 127,
+ 127, 127, -128, -128, -128, -128, 127, 127, -128, -128, 127, -128, -128,
+ -128, 127, 127, 127, -128, -128, -128, 127, 127, 127, 127, -128, -128, -128,
+ -128, -128, -128, 127, 127, 127, -128, -128, -128, -128, -128, 127, -128,
+ -128, 127, -128, -128, 127, 127, -128, -128, 127, 127, -128, -128, -128,
+ -128, -128, 127, 127, -128, -128, -128, 127, 127, 127, -128, 127, -128, -128,
+ 127, 127, 127, -128, -128, -128, 127, 127, -128, -128,
+ };
+
+ public static byte[] SHORT_AU = {
+ 46, 115, 110, 100, 0, 0, 0, 24, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 86, 34, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
+ 0, -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, -1, 0, 0, 0, -1, -1, -1, 0, 0, 0,
+ -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, -1,
+ 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, -1, -1, -1, 0,
+ -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, 0, 0,
+ };
+
+ public static byte[] SHORT_AIFF = {
+ 70, 79, 82, 77, 0, 0, 0, -110, 65, 73, 70, 70, 67, 79, 77, 77, 0, 0, 0, 18,
+ 0, 1, 0, 0, 0, 100, 0, 8, 64, 13, -84, 68, 0, 0, 0, 0, 0, 0, 83, 83, 78,
+ 68, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0,
+ -1, 0, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1,
+ -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, 0,
+ 0, -1, -1, 0, 0, 0, -1, -1, -1, 0, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1,
+ 0, 0,
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileWriter/AUwithULAW.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * 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.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4391108
+ * @summary Writing au files with ulaw encoding is broken
+ */
+public class AUwithULAW {
+ public static void main(String args[]) throws Exception {
+ System.out.println();
+ System.out.println();
+ System.out.println("4391108: Writing au files with ulaw encoding is broken");
+ byte[] fakedata=new byte[1234];
+ InputStream is = new ByteArrayInputStream(fakedata);
+ AudioFormat inFormat = new AudioFormat(AudioFormat.Encoding.ULAW, 8000, 8, 1, 1, 8000, false);
+
+ AudioInputStream ais = new AudioInputStream(is, inFormat, fakedata.length);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream(1500);
+ System.out.println(" ulaw data will be written as AU to stream...");
+ int t = AudioSystem.write(ais, AudioFileFormat.Type.AU, out);
+ byte[] writtenData = out.toByteArray();
+ is = new ByteArrayInputStream(writtenData);
+ System.out.println(" Get AudioFileFormat of written file");
+ AudioFileFormat fileformat = AudioSystem.getAudioFileFormat(is);
+ AudioFileFormat.Type type = fileformat.getType();
+ System.out.println(" The file format type: "+type);
+ if (fileformat.getFrameLength()!=fakedata.length
+ && fileformat.getFrameLength()!=AudioSystem.NOT_SPECIFIED) {
+ throw new Exception("The written file's frame length is "+fileformat.getFrameLength()+" but should be "+fakedata.length+" !");
+ }
+ ais = AudioSystem.getAudioInputStream(is);
+ System.out.println(" Got Stream with format: "+ais.getFormat());
+ System.out.println(" test passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileWriter/AiffSampleRate.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * 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.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4914639
+ * @summary JavaSound writes wrong sample rates to AIFF files
+ */
+public class AiffSampleRate {
+
+ private static final float[] testSampleRates =
+ {8000.0F, 8000.0F + 0.011F, 8193.975F, 10000.0F, 11025.0F, 12000.0F,
+ 16000.0F, 22050.0F, 24000.0F, 32000.0F, 44100.0F - 1.22222F, 44100.0F,
+ 47888.888F, 48000.0F, 96000.0F, 192000.0F};
+
+ public static void main(String[] args) throws Exception {
+ boolean isTestPassed = true;
+
+ out("#4914639: JavaSound writes wrong sample rates to AIFF files");
+ for (int i = 0; i < testSampleRates.length; i++) {
+ isTestPassed &= testSampleRate(testSampleRates[i]);
+ }
+ if (isTestPassed) {
+ out("Test PASSED.");
+ } else {
+ throw new Exception("Test FAILED.");
+ }
+ }
+
+ private static boolean testSampleRate(float sampleRate) {
+ boolean result = true;
+
+ try {
+ // create AudioInputStream with sample rate of 10000 Hz
+ ByteArrayInputStream data = new ByteArrayInputStream(new byte[1]);
+ AudioFormat format = new AudioFormat(sampleRate, 8, 1, true, true);
+ AudioInputStream stream = new AudioInputStream(data, format, 1);
+
+ // write to AIFF file
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ AudioSystem.write(stream, AudioFileFormat.Type.AIFF, outputStream);
+ byte[] fileData = outputStream.toByteArray();
+ InputStream inputStream = new ByteArrayInputStream(fileData);
+ AudioFileFormat aff = AudioSystem.getAudioFileFormat(inputStream);
+ if (! equals(sampleRate, aff.getFormat().getFrameRate())) {
+ out("error for sample rate " + sampleRate);
+ result = false;
+ }
+ } catch (Exception e) {
+ out(e);
+ out("Test NOT FAILED");
+ }
+ return result;
+ }
+
+ private static boolean equals(float f1, float f2) {
+ return Math.abs(f2 - f1) < 1.0E-9;
+ }
+
+ 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/sampled/spi/AudioFileWriter/RIFFHeader.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4636355
+ * @summary Check that RIFF headers are written with extra data length field.
+ */
+public class RIFFHeader {
+
+ public static void main(String args[]) throws Exception {
+ System.out.println();
+ System.out.println();
+ System.out.println("4636355: Check that RIFF headers are written with extra data length field.");
+ byte[] fakedata=new byte[1234];
+ MyByteArrayInputStream is = new MyByteArrayInputStream(fakedata);
+ AudioFormat inFormat = new AudioFormat(AudioFormat.Encoding.ULAW, 8000, 8, 1, 1, 8000, true);
+
+ AudioInputStream ais = new AudioInputStream((InputStream) is, inFormat, fakedata.length);
+ ByteArrayOutputStream out = new ByteArrayOutputStream(1500);
+ System.out.println(" ulaw data will be written as WAVE to stream...");
+ int t = AudioSystem.write(ais, AudioFileFormat.Type.WAVE, out);
+ byte[] writtenData = out.toByteArray();
+ // now header must have at least 46 bytes
+ System.out.println(" Length should be "+(fakedata.length+46)+" bytes: "+writtenData.length);
+ // re-read this file
+ is = new MyByteArrayInputStream(writtenData);
+ System.out.println(" Get AudioFileFormat of written file");
+ AudioFileFormat fileformat = AudioSystem.getAudioFileFormat(is);
+ AudioFileFormat.Type type = fileformat.getType();
+ System.out.println(" The file format type: "+type);
+ if (fileformat.getFrameLength()!=fakedata.length
+ && fileformat.getFrameLength()!=AudioSystem.NOT_SPECIFIED) {
+ throw new Exception("The written file's frame length is "+fileformat.getFrameLength()+" but should be "+fakedata.length+" !");
+ }
+ ais = AudioSystem.getAudioInputStream(is);
+ System.out.println(" Got Stream with format: "+ais.getFormat());
+ if (is.getPos()<46) {
+ throw new Exception("After reading the header, stream position must be at least 46, but is "+is.getPos()+" !");
+ }
+ System.out.println(" test passed.");
+ }
+
+ static class MyByteArrayInputStream extends ByteArrayInputStream {
+
+ MyByteArrayInputStream(byte[] data) {
+ super(data);
+ }
+
+ int getPos() {
+ return pos;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileWriter/WaveBigEndian.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 5001952
+ * @summary Writing WAVE with big endian data produces corrupt file. WAVE should
+ * always write signed 16-bit, little endian, regardless of the
+ * endianness of the input data.
+ */
+public class WaveBigEndian {
+
+ static boolean failed = false;
+
+ public static byte[] writeDataAndGetAIS(boolean bigEndian) throws Exception {
+ if (bigEndian) {
+ out("Create WAVE file from big endian data...");
+ } else {
+ out("Create WAVE file from little endian data...");
+ }
+ byte[] data = new byte[3000];
+ for (int i = 0; i < data.length; i+=2) {
+ if (bigEndian) {
+ data[i] = (byte) i;
+ data[i+1] = (byte) (i+1);
+ } else {
+ data[i] = (byte) (i+1);
+ data[i+1] = (byte) i;
+ }
+ }
+ AudioFormat format = new AudioFormat(44100.0f, 16, 1, true, bigEndian);
+ InputStream is = new ByteArrayInputStream(data);
+ AudioInputStream ais = new AudioInputStream(is, format, data.length);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ int written = AudioSystem.write(ais, AudioFileFormat.Type.WAVE, os);
+ data = os.toByteArray();
+ out("Wrote "+written+" bytes, got "+data.length+" bytes in written file.");
+ is = new ByteArrayInputStream(data);
+ ais = AudioSystem.getAudioInputStream(is);
+ out("Got AIS with length = "+ais.getFrameLength()+" frames.");
+ return data;
+ }
+
+
+ public static void main(String args[]) throws Exception {
+ byte[] data1 = writeDataAndGetAIS(false);
+ byte[] data2 = writeDataAndGetAIS(true);
+
+ if (data1.length != data2.length) {
+ out("# data1.length != data2.length!");
+ failed = true;
+ } else {
+ for (int i = 0 ; i < data1.length; i++) {
+ if (data1[i] != data2[i]) {
+ out("# At index "+i+": le="+(data1[i] & 0xFF)+" be="+(data2[i] & 0xFF)+" !");
+ failed = true;
+ }
+ }
+ }
+
+ if (failed) throw new Exception("Test FAILED!");
+ out("Files are identical.");
+ out("test passed");
+ }
+
+ static void out(String s) {
+ System.out.println(s);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileWriter/WriteAuUnspecifiedLength.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4351296
+ * @summary Cannot write AudioInputStream with unspecified length
+ */
+public class WriteAuUnspecifiedLength {
+
+ public static void main(String argv[]) throws Exception {
+ AudioFormat format = new AudioFormat(44100, 16, 2, true, true);
+ InputStream is = new ByteArrayInputStream(new byte[1000]);
+ AudioInputStream ais = new AudioInputStream(is, format, AudioSystem.NOT_SPECIFIED);
+ AudioSystem.write(ais, AudioFileFormat.Type.AU, new ByteArrayOutputStream());
+ System.out.println("Test passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/FormatConversionProvider/AlawUlaw.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,205 @@
+/*
+ * 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.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4714846
+ * @summary JavaSound ULAW (8-bit) encoder erroneously depends on endian-ness
+ */
+public class AlawUlaw {
+ static ByteArrayInputStream in;
+ static int byteLength = 1000;
+
+ static boolean failed = false;
+
+ public static void main(String[] args) throws Exception {
+ // generate some random data
+ byte[] soundData = new byte[byteLength];
+ for (int i=0; i<soundData.length; i++) {
+ soundData[i] = (byte) ((i % 256) - 128);
+ }
+
+ // create an AudioInputStream from it
+ in = new ByteArrayInputStream(soundData);
+ in.mark(1);
+
+ test1(PCM_FORMAT_1, ULAW_FORMAT_1, ULAW_FORMAT_2);
+ test1(PCM_FORMAT_2, ULAW_FORMAT_1, ULAW_FORMAT_2);
+ test2(ULAW_FORMAT_1, ULAW_FORMAT_2, PCM_FORMAT_1);
+ test2(ULAW_FORMAT_1, ULAW_FORMAT_2, PCM_FORMAT_2);
+
+ test1(PCM_FORMAT_1, ALAW_FORMAT_1, ALAW_FORMAT_2);
+ test1(PCM_FORMAT_2, ALAW_FORMAT_1, ALAW_FORMAT_2);
+ test2(ALAW_FORMAT_1, ALAW_FORMAT_2, PCM_FORMAT_1);
+ test2(ALAW_FORMAT_1, ALAW_FORMAT_2, PCM_FORMAT_2);
+
+ if (failed) {
+ throw new Exception("Test failed!");
+ }
+ }
+
+ public static String printFormat(AudioFormat format) {
+ return format.toString()+" "+(format.isBigEndian()?"big":"little")+" endian";
+ }
+
+
+ public static void test1(AudioFormat inFormat, AudioFormat outFormat1, AudioFormat outFormat2) throws Exception {
+ AudioInputStream inStream = new AudioInputStream(in, inFormat, -1);
+ System.out.println("Input Format: " + printFormat(inStream.getFormat()));
+
+ // get a converted stream
+ AudioInputStream stream1 = AudioSystem.getAudioInputStream(outFormat1, inStream);
+ System.out.println("Output Format 1: " + printFormat(stream1.getFormat()));
+
+ // get a converted stream in big endian ulaw
+ AudioInputStream stream2 = AudioSystem.getAudioInputStream(outFormat2, inStream);
+ System.out.println("Output Format 2: " + printFormat(stream2.getFormat()));
+
+ compareStreams(stream1, stream2);
+ }
+
+ public static void test2(AudioFormat inFormat1, AudioFormat inFormat2, AudioFormat outFormat) throws Exception {
+ AudioInputStream inStream1 = new AudioInputStream(in, inFormat1, -1);
+ System.out.println("Input Format1: " + printFormat(inStream1.getFormat()));
+
+ // get a converted stream
+ AudioInputStream stream1 = AudioSystem.getAudioInputStream(outFormat, inStream1);
+ System.out.println("Output Format 1: " + printFormat(stream1.getFormat()));
+
+ AudioInputStream inStream2 = new AudioInputStream(in, inFormat2, -1);
+ System.out.println("Input Format1: " + printFormat(inStream2.getFormat()));
+
+ // get a converted stream in big endian ulaw
+ AudioInputStream stream2 = AudioSystem.getAudioInputStream(outFormat, inStream2);
+ System.out.println("Output Format 2: " + printFormat(stream2.getFormat()));
+
+ compareStreams(stream1, stream2);
+ }
+
+ public static void compareStreams(InputStream stream1, InputStream stream2) throws Exception {
+ ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
+ ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
+
+ in.reset();
+ writeDirectly(stream1, baos1);
+ in.reset();
+ writeDirectly(stream2, baos2);
+
+ if (baos1.size() != baos2.size()) {
+ System.out.println(" stream1 has length = "+baos1.size()+", stream2 has length = "+baos2.size());
+ }
+ int len = baos1.size();
+ if (len > baos2.size()) {
+ len = baos2.size();
+ }
+ byte[] data1=baos1.toByteArray();
+ byte[] data2=baos2.toByteArray();
+ for (int i=0; i<len; i++) {
+ if (data1[i] != data2[i]) {
+ System.out.println(" FAILED! Difference encountered at position "+i);
+ failed = true;
+ return;
+ }
+ }
+ if (baos1.size() != baos2.size()) {
+ System.out.println(" No difference, but different length!");
+ failed = true;
+ return;
+ }
+ System.out.println(" PASSED");
+ }
+
+ public static void writeDirectly(InputStream in, OutputStream out) throws Exception {
+ // read data from the stream until we reach the end of the stream
+ byte tmp[] = new byte[16384];
+ while (true) {
+ int bytesRead = in.read(tmp, 0, tmp.length);
+ if (bytesRead == -1) {
+ break;
+ }
+ out.write(tmp, 0, bytesRead);
+ } // while
+ }
+
+ public static final AudioFormat PCM_FORMAT_1 =
+ new AudioFormat( AudioFormat.Encoding.PCM_SIGNED,
+ 8000f, //sample rate
+ 16, //bits per sample
+ 1, //channels
+ 2, //frame size
+ 8000f, // frame rate
+ false); //isBigEndian
+ public static final AudioFormat PCM_FORMAT_2 =
+ new AudioFormat( AudioFormat.Encoding.PCM_SIGNED,
+ 8000f, //sample rate
+ 16, //bits per sample
+ 1, //channels
+ 2, //frame size
+ 8000f, // frame rate
+ true); //isBigEndian
+
+ public static final AudioFormat ULAW_FORMAT_1 =
+ new AudioFormat( AudioFormat.Encoding.ULAW,
+ 8000f, //sample rate
+ 8, //bits per sample
+ 1, //channels
+ 1, //frame size
+ 8000f, // frame rate
+ false); //isBigEndian
+
+ public static final AudioFormat ULAW_FORMAT_2 =
+ new AudioFormat( AudioFormat.Encoding.ULAW,
+ 8000f, //sample rate
+ 8, //bits per sample
+ 1, //channels
+ 1, //frame size
+ 8000f, // frame rate
+ true); //isBigEndian
+
+ public static final AudioFormat ALAW_FORMAT_1 =
+ new AudioFormat( AudioFormat.Encoding.ALAW,
+ 8000f, //sample rate
+ 8, //bits per sample
+ 1, //channels
+ 1, //frame size
+ 8000f, // frame rate
+ false); //isBigEndian
+
+ public static final AudioFormat ALAW_FORMAT_2 =
+ new AudioFormat( AudioFormat.Encoding.ALAW,
+ 8000f, //sample rate
+ 8, //bits per sample
+ 1, //channels
+ 1, //frame size
+ 8000f, // frame rate
+ true); //isBigEndian
+}
--- a/jdk/test/javax/swing/ToolTipManager/7123767/bug7123767.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/javax/swing/ToolTipManager/7123767/bug7123767.java Wed Jul 05 22:25:59 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, 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
@@ -23,12 +23,25 @@
/*
* @test
- * @key headful
- * @bug 7123767
- * @summary Wrong tooltip location in Multi-Monitor configurations
- * @author Vladislav Karnaukhov
- * @modules java.desktop/sun.awt
- * @run main bug7123767
+ * @bug 7123767
+ *
+ * @summary Check if a tooltip location in Multi-Monitor
+ * configurations is correct.
+ * If the configurations number per device exceeds 5,
+ * then some 5 random configurations will be checked.
+ * Please Use -Dseed=X to set the random generator seed
+ * (if necessary).
+ *
+ * @author Vladislav Karnaukhov
+ *
+ * @key headful
+ * @key randomness
+ *
+ * @modules java.desktop/sun.awt
+ * @library /lib/testlibrary/
+ * @build jdk.testlibrary.*
+ *
+ * @run main/timeout=300 bug7123767
*/
import javax.swing.*;
@@ -37,8 +50,50 @@
import java.awt.event.MouseEvent;
import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Random;
+
+import jdk.testlibrary.RandomFactory;
+
+
public class bug7123767 extends JFrame {
+ // maximum number of GraphicsConfigurations checked per GraphicsDevice
+ private static final int MAX_N_CONFIGS = 5;
+ private static final List<GraphicsConfiguration> CONFIGS = getConfigs();
+
+ private static List<GraphicsConfiguration> getConfigs() {
+
+ Random rnd = RandomFactory.getRandom();
+
+ List<GraphicsConfiguration> configs = new ArrayList<>();
+
+ GraphicsEnvironment ge =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice[] devices = ge.getScreenDevices();
+
+ for (GraphicsDevice device : devices) {
+ GraphicsConfiguration[] allConfigs = device.getConfigurations();
+ int nConfigs = allConfigs.length;
+ if (nConfigs <= MAX_N_CONFIGS) {
+ Collections.addAll(configs, allConfigs);
+ } else { // see JDK-8159454
+ System.out.println("check only " + MAX_N_CONFIGS +
+ " configurations for device " + device);
+ configs.add(device.getDefaultConfiguration()); // check default
+ for (int j = 0; j < MAX_N_CONFIGS - 1; j++) {
+ int k = rnd.nextInt(nConfigs);
+ configs.add(allConfigs[k]);
+ }
+ }
+ }
+
+ return configs;
+ }
+
+
private static class TestFactory extends PopupFactory {
private static TestFactory newFactory = new TestFactory();
@@ -62,15 +117,21 @@
}
// Actual test happens here
+ @Override
public Popup getPopup(Component owner, Component contents, int x, int y) {
- GraphicsConfiguration mouseGC = testGC(MouseInfo.getPointerInfo().getLocation());
+
+ GraphicsConfiguration mouseGC =
+ testGC(MouseInfo.getPointerInfo().getLocation());
+
if (mouseGC == null) {
- throw new RuntimeException("Can't find GraphicsConfiguration that mouse pointer belongs to");
+ throw new RuntimeException("Can't find GraphicsConfiguration "
+ + "that mouse pointer belongs to");
}
GraphicsConfiguration tipGC = testGC(new Point(x, y));
if (tipGC == null) {
- throw new RuntimeException("Can't find GraphicsConfiguration that tip belongs to");
+ throw new RuntimeException(
+ "Can't find GraphicsConfiguration that tip belongs to");
}
if (!mouseGC.equals(tipGC)) {
@@ -81,17 +142,14 @@
}
private static GraphicsConfiguration testGC(Point pt) {
- GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice[] devices = environment.getScreenDevices();
- for (GraphicsDevice device : devices) {
- GraphicsConfiguration[] configs = device.getConfigurations();
- for (GraphicsConfiguration config : configs) {
- Rectangle rect = config.getBounds();
- Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(config);
- adjustInsets(rect, insets);
- if (rect.contains(pt))
- return config;
- }
+
+ for (GraphicsConfiguration config: CONFIGS) {
+
+ Rectangle rect = config.getBounds();
+ Insets insets =
+ Toolkit.getDefaultToolkit().getScreenInsets(config);
+ adjustInsets(rect, insets);
+ if (rect.contains(pt)) { return config; }
}
return null;
@@ -103,15 +161,18 @@
private static Robot robot;
public static void main(String[] args) throws Exception {
+
UIManager.setLookAndFeel(new MetalLookAndFeel());
setUp();
testToolTip();
TestFactory.uninstall();
+ if (frame != null) { frame.dispose(); }
}
// Creates a window that is stretched across all available monitors
// and adds itself as ContainerListener to track tooltips drawing
private bug7123767() {
+
super();
ToolTipManager.sharedInstance().setInitialDelay(0);
@@ -135,17 +196,16 @@
pack();
Rectangle rect = new Rectangle();
- GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice[] devices = environment.getScreenDevices();
- for (GraphicsDevice device : devices) {
- GraphicsConfiguration[] configs = device.getConfigurations();
- for (GraphicsConfiguration config : configs) {
- Insets localInsets = Toolkit.getDefaultToolkit().getScreenInsets(config);
- Rectangle localRect = config.getBounds();
- adjustInsets(localRect, localInsets);
- rect.add(localRect);
- }
+
+ for (GraphicsConfiguration config: CONFIGS) {
+
+ Insets localInsets =
+ Toolkit.getDefaultToolkit().getScreenInsets(config);
+ Rectangle localRect = config.getBounds();
+ adjustInsets(localRect, localInsets);
+ rect.add(localRect);
}
+
setBounds(rect);
}
@@ -166,35 +226,32 @@
robot.setAutoDelay(20);
robot.waitForIdle();
- GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice[] devices = environment.getScreenDevices();
- for (GraphicsDevice device : devices) {
- GraphicsConfiguration[] configs = device.getConfigurations();
- for (GraphicsConfiguration config : configs) {
- Rectangle rect = config.getBounds();
- Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(config);
- adjustInsets(rect, insets);
+ for (GraphicsConfiguration config: CONFIGS) {
- // Upper left
- glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
- rect.x + MARGIN, rect.y + MARGIN);
- robot.waitForIdle();
+ Rectangle rect = config.getBounds();
+ Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(config);
+ adjustInsets(rect, insets);
+
+ // Upper left
+ glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
+ rect.x + MARGIN, rect.y + MARGIN);
+ robot.waitForIdle();
- // Lower left
- glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
- rect.x + MARGIN, rect.y + rect.height - MARGIN);
- robot.waitForIdle();
+ // Lower left
+ glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
+ rect.x + MARGIN, rect.y + rect.height - MARGIN);
+ robot.waitForIdle();
- // Upper right
- glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
- rect.x + rect.width - MARGIN, rect.y + MARGIN);
- robot.waitForIdle();
+ // Upper right
+ glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
+ rect.x + rect.width - MARGIN, rect.y + MARGIN);
+ robot.waitForIdle();
- // Lower right
- glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
- rect.x + rect.width - MARGIN, rect.y + rect.height - MARGIN);
- robot.waitForIdle();
- }
+ // Lower right
+ glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
+ rect.x + rect.width - MARGIN, rect.y + rect.height - MARGIN);
+
+ robot.waitForIdle();
}
}
--- a/jdk/test/javax/swing/text/CSSBorder/6796710/bug6796710.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/javax/swing/text/CSSBorder/6796710/bug6796710.java Wed Jul 05 22:25:59 2017 +0200
@@ -24,11 +24,10 @@
/*
* @test
* @key headful
- * @bug 6796710 7124242
+ * @bug 6796710 7124242 8168540
* @summary Html content in JEditorPane is overlapping on swing components while resizing the application.
* @library ../../../regtesthelpers
* @build Util
- * @author Pavel Porvatov
@run main bug6796710
*/
@@ -109,7 +108,7 @@
}
});
- robot.waitForIdle();
+ robot.delay(1000);
// On Linux platforms realSync doesn't guaranties setSize completion
Thread.sleep(1000);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/editpad/EditPadTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,342 @@
+/*
+ * 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.
+ *
+ * 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 8167636 8167639 8168972
+ * @summary Testing built-in editor.
+ * @modules java.desktop/java.awt
+ * jdk.internal.ed/jdk.internal.editor.spi
+ * jdk.editpad/jdk.editpad
+ * @run testng EditPadTest
+ */
+
+import java.awt.AWTException;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.GraphicsEnvironment;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.WindowEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ServiceLoader;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+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;
+import javax.swing.JViewport;
+import javax.swing.SwingUtilities;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import jdk.internal.editor.spi.BuildInEditorProvider;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class EditPadTest {
+
+ private static final int DELAY = 500;
+ private static final String WINDOW_LABEL = "Test Edit Pad";
+
+ private static ExecutorService executor;
+ private static Robot robot;
+ private static JFrame frame = null;
+ private static JTextArea area = null;
+ private static JButton cancel = null;
+ private static JButton accept = null;
+ private static JButton exit = null;
+
+ @BeforeClass
+ public static void setUpEditorPadTest() {
+ if (!GraphicsEnvironment.isHeadless()) {
+ try {
+ robot = new Robot();
+ robot.setAutoWaitForIdle(true);
+ robot.setAutoDelay(DELAY);
+ } catch (AWTException e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+ }
+
+ @AfterClass
+ public static void shutdown() {
+ executorShutdown();
+ }
+
+ public void testSimple() {
+ testEdit("abcdef", 1, "xyz",
+ () -> assertSource("abcdef"),
+ () -> writeSource("xyz"),
+ () -> accept(),
+ () -> assertSource("xyz"),
+ () -> shutdownEditor());
+ }
+
+ public void testCancel() {
+ testEdit("abcdef", 0, "abcdef",
+ () -> assertSource("abcdef"),
+ () -> writeSource("xyz"),
+ () -> cancel());
+ }
+
+ public void testAbort() {
+ testEdit("abcdef", 0, "abcdef",
+ () -> assertSource("abcdef"),
+ () -> writeSource("xyz"),
+ () -> shutdownEditor());
+ }
+
+ public void testAcceptCancel() {
+ testEdit("abcdef", 1, "xyz",
+ () -> assertSource("abcdef"),
+ () -> writeSource("xyz"),
+ () -> accept(),
+ () -> assertSource("xyz"),
+ () -> writeSource("!!!!!!!!!"),
+ () -> cancel());
+ }
+
+ public void testAcceptEdit() {
+ testEdit("abcdef", 2, "xyz",
+ () -> assertSource("abcdef"),
+ () -> writeSource("NoNo"),
+ () -> accept(),
+ () -> assertSource("NoNo"),
+ () -> writeSource("xyz"),
+ () -> exit());
+ }
+
+ private void testEdit(String initialText,
+ int savedCount, String savedText, Runnable... actions) {
+ class Handler {
+
+ String text = null;
+ int count = 0;
+
+ void handle(String s) {
+ ++count;
+ text = s;
+ }
+ }
+ Handler save = new Handler();
+ Handler error = new Handler();
+
+ if (GraphicsEnvironment.isHeadless()) {
+ // Do not actually run if we are headless
+ return;
+ }
+ Future<?> task = doActions(actions);
+ builtInEdit(initialText, save::handle, error::handle);
+ complete(task);
+ assertEquals(error.count, 0, "Error: " + error.text);
+ assertTrue(save.count != savedCount
+ || save.text == null
+ ? savedText != null
+ : savedText.equals(save.text),
+ "Expected " + savedCount + " saves, got " + save.count
+ + ", expected \"" + savedText + "\" got \"" + save.text + "\"");
+ }
+
+ private static ExecutorService getExecutor() {
+ if (executor == null) {
+ executor = Executors.newSingleThreadExecutor();
+ }
+ return executor;
+ }
+
+ private static void executorShutdown() {
+ if (executor != null) {
+ executor.shutdown();
+ executor = null;
+ }
+ }
+
+ private void builtInEdit(String initialText,
+ Consumer<String> saveHandler, Consumer<String> errorHandler) {
+ ServiceLoader<BuildInEditorProvider> sl
+ = ServiceLoader.load(BuildInEditorProvider.class);
+ // Find the highest ranking provider
+ BuildInEditorProvider provider = null;
+ for (BuildInEditorProvider p : sl) {
+ if (provider == null || p.rank() > provider.rank()) {
+ provider = p;
+ }
+ }
+ if (provider != null) {
+ provider.edit(WINDOW_LABEL,
+ initialText, saveHandler, errorHandler);
+ } else {
+ throw new InternalError("Cannot find provider");
+ }
+ }
+
+ private Future<?> doActions(Runnable... actions) {
+ return getExecutor().submit(() -> {
+ try {
+ waitForIdle();
+ SwingUtilities.invokeLater(this::seekElements);
+ waitForIdle();
+ for (Runnable act : actions) {
+ act.run();
+ }
+ } catch (Throwable e) {
+ shutdownEditor();
+ if (e instanceof AssertionError) {
+ throw (AssertionError) e;
+ }
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ private void complete(Future<?> task) {
+ try {
+ task.get();
+ waitForIdle();
+ } catch (ExecutionException e) {
+ if (e.getCause() instanceof AssertionError) {
+ throw (AssertionError) e.getCause();
+ }
+ throw new RuntimeException(e);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ shutdownEditor();
+ }
+ }
+
+ private void writeSource(String s) {
+ SwingUtilities.invokeLater(() -> area.setText(s));
+ }
+
+ private void assertSource(String expected) {
+ String[] s = new String[1];
+ try {
+ SwingUtilities.invokeAndWait(() -> s[0] = area.getText());
+ } catch (InvocationTargetException | InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ assertEquals(s[0], expected);
+ }
+
+ private void accept() {
+ clickOn(accept);
+ }
+
+ private void exit() {
+ clickOn(exit);
+ }
+
+ private void cancel() {
+ clickOn(cancel);
+ }
+
+ private void shutdownEditor() {
+ SwingUtilities.invokeLater(this::clearElements);
+ waitForIdle();
+ }
+
+ private void waitForIdle() {
+ robot.waitForIdle();
+ robot.delay(DELAY);
+ }
+
+ private void seekElements() {
+ for (Frame f : Frame.getFrames()) {
+ if (f.getTitle().equals(WINDOW_LABEL)) {
+ frame = (JFrame) f;
+ // workaround
+ frame.setLocation(0, 0);
+ Container root = frame.getContentPane();
+ for (Component c : root.getComponents()) {
+ if (c instanceof JScrollPane) {
+ JScrollPane scrollPane = (JScrollPane) c;
+ for (Component comp : scrollPane.getComponents()) {
+ if (comp instanceof JViewport) {
+ JViewport view = (JViewport) comp;
+ area = (JTextArea) view.getComponent(0);
+ }
+ }
+ }
+ if (c instanceof JPanel) {
+ JPanel p = (JPanel) c;
+ for (Component comp : p.getComponents()) {
+ if (comp instanceof JButton) {
+ JButton b = (JButton) comp;
+ switch (b.getText()) {
+ case "Cancel":
+ cancel = b;
+ break;
+ case "Exit":
+ exit = b;
+ break;
+ case "Accept":
+ accept = b;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void clearElements() {
+ if (frame != null) {
+ frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
+ frame = null;
+ }
+ area = null;
+ accept = null;
+ cancel = null;
+ exit = null;
+ }
+
+ private void clickOn(JButton button) {
+ waitForIdle();
+ waitForIdle();
+ waitForIdle();
+ waitForIdle();
+ waitForIdle();
+ waitForIdle();
+ Point p = button.getLocationOnScreen();
+ Dimension d = button.getSize();
+ robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2);
+ robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+ }
+}
--- a/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java Wed Jul 05 22:25:59 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -35,7 +35,7 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary JavaVM
+ * @build JavaVM
* @run main/othervm NoConsoleOutput
*/
@@ -43,8 +43,6 @@
import java.io.File;
import java.rmi.Remote;
import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class NoConsoleOutput {
@@ -53,7 +51,7 @@
System.err.println("\nRegression test for bug 6409194\n");
/*
- * Exdecute a subprocess VM that does a bunch of RMI activity
+ * Execute a subprocess VM that does a bunch of RMI activity
* with a logging configuration file that does not specify a
* ConsoleHandler and with no legacy sun.rmi.*.logLevel system
* properties set.
@@ -65,7 +63,7 @@
ByteArrayOutputStream err = new ByteArrayOutputStream();
// We instantiate a JavaVM that should not produce any console output
- // (neither on standard output, nor on standard err streams).
+ // on standard err streams, where RMI logging messages are sent to.
JavaVM vm = new JavaVM(
DoRMIStuff.class.getName(),
"--add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED"
@@ -77,8 +75,7 @@
vm.execute();
/*
- * Verify that the subprocess had no System.out or System.err
- * output.
+ * Verify that the subprocess had no System.err output.
*/
String outString = out.toString();
String errString = err.toString();
@@ -89,7 +86,7 @@
System.err.print(err);
System.err.println("---------------------------------------------");
- if (outString.length() > 0 || errString.length() > 0) {
+ if (errString.length() > 0) {
throw new Error("TEST FAILED: unexpected subprocess output");
}
@@ -105,13 +102,8 @@
public Object echo(Object obj) { return obj; }
}
public static void main(String[] args) throws Exception {
- Registry registry = TestLibrary.createRegistryOnUnusedPort();
- int registryPort = TestLibrary.getRegistryPort(registry);
- Registry reg = LocateRegistry.getRegistry("", registryPort);
FooImpl fooimpl = new FooImpl();
- UnicastRemoteObject.exportObject(fooimpl, 0);
- reg.rebind("foo", fooimpl);
- Foo foostub = (Foo) reg.lookup("foo");
+ Foo foostub = (Foo) UnicastRemoteObject.exportObject(fooimpl, 0);
FooImpl fooimpl2 = new FooImpl();
UnicastRemoteObject.exportObject(fooimpl2, 0);
foostub.echo(fooimpl2);
--- a/jdk/test/sun/security/ec/TestEC.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/sun/security/ec/TestEC.java Wed Jul 05 22:25:59 2017 +0200
@@ -35,7 +35,7 @@
* @library ../pkcs11/sslecc
* @library ../../../java/security/testlibrary
* @modules jdk.crypto.pkcs11/sun.security.pkcs11.wrapper
- * @compile -XDignore.symbol.file TestEC.java
+ * @compile --add-modules jdk.crypto.pkcs11 TestEC.java
* @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
* @run main/othervm/java.security.policy=TestEC.policy -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
*/
--- a/jdk/test/sun/security/mscapi/IsSunMSCAPIAvailable.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/sun/security/mscapi/IsSunMSCAPIAvailable.java Wed Jul 05 22:25:59 2017 +0200
@@ -26,6 +26,7 @@
* @bug 6318171 6931562
* @requires os.family == "windows"
* @modules jdk.crypto.mscapi/sun.security.mscapi
+ * @compile --add-modules jdk.crypto.mscapi IsSunMSCAPIAvailable.java
* @run main/othervm IsSunMSCAPIAvailable
*/
--- a/jdk/test/sun/security/pkcs11/ec/TestCurves.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/sun/security/pkcs11/ec/TestCurves.java Wed Jul 05 22:25:59 2017 +0200
@@ -28,7 +28,7 @@
* @author Andreas Sterbenz
* @library ..
* @modules jdk.crypto.pkcs11/sun.security.pkcs11.wrapper
- * @compile -XDignore.symbol.file TestCurves.java
+ * @compile --add-modules jdk.crypto.pkcs11 TestCurves.java
* @run main/othervm TestCurves
* @run main/othervm TestCurves sm
* @key randomness
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/JLinkSigningTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,195 @@
+/*
+ * 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 8159393
+ * @summary Test signed jars involved in image creation
+ * @modules java.base/jdk.internal.jimage
+ * jdk.jlink/jdk.tools.jlink.internal
+ * jdk.compiler/com.sun.tools.javac
+ * java.base/sun.security.tools.keytool
+ * jdk.jartool/sun.security.tools.jarsigner
+ * jdk.jartool/sun.tools.jar
+ * @run main/othervm JLinkSigningTest
+ */
+
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+
+public class JLinkSigningTest {
+ static final String[] MODULE_INFO = {
+ "module test {",
+ "}",
+ };
+
+ static final String[] TEST_CLASS = {
+ "package test;",
+ "public class test {",
+ " public static void main(String[] args) {",
+ " }",
+ "}",
+ };
+
+ static void report(String command, String[] args) {
+ System.out.println(command + " " + String.join(" ", Arrays.asList(args)));
+ }
+
+ static void javac(String[] args) {
+ report("javac", args);
+ com.sun.tools.javac.Main javac = new com.sun.tools.javac.Main();
+
+ if (javac.compile(args) != 0) {
+ throw new RuntimeException("javac failed");
+ }
+ }
+
+ static void jar(String[] args) {
+ report("jar", args);
+ sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");
+
+ if (!jar.run(args)) {
+ throw new RuntimeException("jar failed");
+ }
+ }
+
+ static void keytool(String[] args) {
+ report("keytool", args);
+
+ try {
+ sun.security.tools.keytool.Main.main(args);
+ } catch (Exception ex) {
+ throw new RuntimeException("keytool failed");
+ }
+ }
+
+ static void jarsigner(String[] args) {
+ report("jarsigner", args);
+
+ try {
+ sun.security.tools.jarsigner.Main.main(args);
+ } catch (Exception ex) {
+ throw new RuntimeException("jarsigner failed");
+ }
+ }
+
+ static void jlink(String[] args) {
+ report("jlink", args);
+
+ try {
+ jdk.tools.jlink.internal.Main.run(new PrintWriter(System.out, true),
+ new PrintWriter(System.err, true),
+ args);
+ } catch (Exception ex) {
+ throw new RuntimeException("jlink failed");
+ }
+ }
+
+ public static void main(String[] args) {
+ final String JAVA_HOME = System.getProperty("java.home");
+ Path moduleInfoJavaPath = Paths.get("module-info.java");
+ Path moduleInfoClassPath = Paths.get("module-info.class");
+ Path testDirectoryPath = Paths.get("test");
+ Path testJavaPath = testDirectoryPath.resolve("test.java");
+ Path testClassPath = testDirectoryPath.resolve("test.class");
+ Path testModsDirectoryPath = Paths.get("testmods");
+ Path jmodsPath = Paths.get(JAVA_HOME, "jmods");
+ Path testjarPath = testModsDirectoryPath.resolve("test.jar");
+ String modulesPath = testjarPath.toString() +
+ File.pathSeparator +
+ jmodsPath.toString();
+
+ try {
+ Files.write(moduleInfoJavaPath, Arrays.asList(MODULE_INFO));
+ Files.createDirectories(testDirectoryPath);
+ Files.write(testJavaPath, Arrays.asList(TEST_CLASS));
+ Files.createDirectories(testModsDirectoryPath);
+ } catch (IOException ex) {
+ throw new RuntimeException("file construction failed");
+ }
+
+ javac(new String[] {
+ testJavaPath.toString(),
+ moduleInfoJavaPath.toString(),
+ });
+
+ jar(new String[] {
+ "-c",
+ "-f", testjarPath.toString(),
+ "--module-path", jmodsPath.toString(),
+ testClassPath.toString(),
+ moduleInfoClassPath.toString(),
+ });
+
+ keytool(new String[] {
+ "-genkey",
+ "-keyalg", "RSA",
+ "-dname", "CN=John Doe, OU=JPG, O=Oracle, L=Santa Clara, ST=California, C=US",
+ "-alias", "examplekey",
+ "-storepass", "password",
+ "-keypass", "password",
+ "-keystore", "examplekeystore",
+ "-validity", "365",
+ });
+
+ jarsigner(new String[] {
+ "-keystore", "examplekeystore",
+ "-verbose", testjarPath.toString(),
+ "-storepass", "password",
+ "-keypass", "password",
+ "examplekey",
+ });
+
+ try {
+ jlink(new String[] {
+ "--module-path", modulesPath,
+ "--add-modules", "test",
+ "--output", "foo",
+ });
+ } catch (Throwable ex) {
+ System.out.println("Failed as should");
+ }
+
+ try {
+ jlink(new String[] {
+ "--module-path", modulesPath,
+ "--add-modules", "test",
+ "--ignore-signing-information",
+ "--output", "foo",
+ });
+ System.out.println("Suceeded as should");
+ } catch (Throwable ex) {
+ System.err.println("Should not have failed");
+ throw new RuntimeException(ex);
+ }
+
+ System.out.println("Done");
+ }
+}
+
--- a/jdk/test/tools/jmod/JmodTest.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/tools/jmod/JmodTest.java Wed Jul 05 22:25:59 2017 +0200
@@ -28,6 +28,7 @@
* jdk.jlink
* @build jdk.testlibrary.FileUtils CompilerUtils
* @run testng JmodTest
+ * @bug 8142968
* @summary Basic test for jmod
*/
@@ -85,6 +86,31 @@
Files.createDirectories(MODS_DIR);
}
+ // JDK-8166286 - jmod fails on symlink to directory
+ @Test
+ public void testSymlinks() throws IOException {
+ Path apaDir = EXPLODED_DIR.resolve("apa");
+ Path classesDir = EXPLODED_DIR.resolve("apa").resolve("classes");
+ assertTrue(compileModule("apa", classesDir));
+ Path libDir = apaDir.resolve("lib");
+ createFiles(libDir, List.of("foo/bar/libfoo.so"));
+ try {
+ Path link = Files.createSymbolicLink(
+ libDir.resolve("baz"), libDir.resolve("foo").toAbsolutePath());
+ assertTrue(Files.exists(link));
+ } catch (UnsupportedOperationException uoe) {
+ // OS does not support symlinks. Nothing to test!
+ return;
+ }
+
+ Path jmod = MODS_DIR.resolve("apa.jmod");
+ jmod("create",
+ "--libs=", libDir.toString(),
+ "--class-path", classesDir.toString(),
+ jmod.toString())
+ .assertSuccess();
+ }
+
@Test
public void testList() throws IOException {
String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jmod/src/apa/jdk/test/apa/Apa.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,28 @@
+/*
+ * 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.test.apa;
+
+public class Apa { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jmod/src/apa/module-info.java Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+module apa {
+ exports jdk.test.apa;
+}
--- a/jdk/test/tools/launcher/MiscTests.java Mon Nov 07 16:08:18 2016 +0000
+++ b/jdk/test/tools/launcher/MiscTests.java Wed Jul 05 22:25:59 2017 +0200
@@ -69,8 +69,6 @@
static void test6856415() throws IOException {
final String mainClass = "Foo6856415";
- final String exportOpts
- = "--add-exports=jdk.crypto.pkcs11/sun.security.pkcs11=ALL-UNNAMED";
List<String> scratch = new ArrayList<>();
scratch.add("public class Foo6856415 {");
@@ -81,7 +79,9 @@
scratch.add("}");
createFile(new File(mainClass + ".java"), scratch);
- compile(mainClass + ".java", exportOpts);
+ compile(mainClass + ".java",
+ "--add-modules=jdk.crypto.pkcs11",
+ "--add-exports=jdk.crypto.pkcs11/sun.security.pkcs11=ALL-UNNAMED");
File testJar = new File("Foo.jar");
testJar.delete();
--- a/make/Bundles.gmk Mon Nov 07 16:08:18 2016 +0000
+++ b/make/Bundles.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -256,7 +256,7 @@
$(eval $(call SetupBundleFile, BUILD_DEMOS_BUNDLE, \
BUNDLE_NAME := $(DEMOS_BUNDLE_NAME), \
- FILES := $(call DoubleDollar, $(DEMOS_BUNDLE_FILES)), \
+ FILES := $(DEMOS_BUNDLE_FILES), \
BASE_DIR := $(JDK_IMAGE_DIR), \
SUBDIR := $(JDK_BUNDLE_SUBDIR), \
))
@@ -271,7 +271,7 @@
$(eval $(call SetupBundleFile, BUILD_TEST_BUNDLE, \
BUNDLE_NAME := $(TEST_BUNDLE_NAME), \
- FILES := $(call DoubleDollar, $(TEST_BUNDLE_FILES)), \
+ FILES := $(TEST_BUNDLE_FILES), \
BASE_DIR := $(TEST_IMAGE_DIR), \
))
--- a/make/CompileJavaModules.gmk Mon Nov 07 16:08:18 2016 +0000
+++ b/make/CompileJavaModules.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -95,7 +95,7 @@
################################################################################
java.desktop_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference \
- '-Xdoclint/package:java.*,javax.*' -Xlint:-deprecation,-exports
+ '-Xdoclint/package:java.*,javax.*' -Xlint:-deprecation,exports
java.desktop_COPY := .gif .png .wav .txt .xml .css .pf
java.desktop_CLEAN := iio-plugin.properties cursors.properties
@@ -365,6 +365,10 @@
################################################################################
+jdk.editpad_COPY := .properties
+
+################################################################################
+
jdk.internal.le_COPY := .properties
################################################################################
--- a/make/CreateJmods.gmk Mon Nov 07 16:08:18 2016 +0000
+++ b/make/CreateJmods.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -36,6 +36,7 @@
################################################################################
JMODS_DIR := $(IMAGES_OUTPUTDIR)/jmods
+JMODS_TEMPDIR := $(SUPPORT_OUTPUTDIR)/jmods
LIBS_DIR := $(firstword $(wildcard $(addsuffix /$(MODULE), \
$(SUPPORT_OUTPUTDIR)/modules_libs $(IMPORT_MODULES_LIBS))))
@@ -81,16 +82,19 @@
# Add dependencies on other jmod files. Only java.base needs access to other
# jmods.
ifeq ($(MODULE), java.base)
- ALL_UPGRADEABLE_MODULES = $(call FindAllUpgradeableModules)
# When creating a BUILDJDK, we don't need to add hashes to java.base
ifneq ($(CREATING_BUILDJDK), true)
- DEPS += $(patsubst %, $(JMODS_DIR)/%.jmod, \
- $(filter-out java.base $(ALL_UPGRADEABLE_MODULES), $(call FindAllModules)))
+ # When creating interim versions of jmods, skip hashes
+ ifneq ($(INTERIM_JMOD), true)
+ ALL_UPGRADEABLE_MODULES := $(call FindAllUpgradeableModules)
+ DEPS += $(patsubst %, $(JMODS_DIR)/%.jmod, \
+ $(filter-out java.base $(ALL_UPGRADEABLE_MODULES), $(call FindAllModules)))
- EXCLUDE_PATTERN := $(strip $(subst $(SPACE),|,$(strip $(ALL_UPGRADEABLE_MODULES))))
+ EXCLUDE_PATTERN := $(strip $(subst $(SPACE),|,$(strip $(ALL_UPGRADEABLE_MODULES))))
- JMOD_FLAGS += --module-path $(JMODS_DIR) \
- --hash-modules '^(?!$(EXCLUDE_PATTERN))'
+ JMOD_FLAGS += --module-path $(JMODS_DIR) \
+ --hash-modules '^(?!$(EXCLUDE_PATTERN))'
+ endif
endif
endif
@@ -102,13 +106,19 @@
DEPS += $(call CacheFind, $(JDK_OUTPUTDIR)/modules/jdk.jlink/jdk/tools/jmod)
endif
+# If creating interim versions of jmods, certain files need to be filtered out
+# to avoid false incremental rebuilds.
+ifeq ($(INTERIM_JMOD), true)
+ DEPS := $(filter-out $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/classlist, $(DEPS))
+endif
+
# TODO: What about headers?
# Create jmods in a temp dir and then move them into place to keep the
# module path in $(IMAGES_OUTPUTDIR)/jmods valid at all times.
$(JMODS_DIR)/$(MODULE).jmod: $(DEPS)
$(call LogWarn, Creating $(patsubst $(OUTPUT_ROOT)/%, %, $@))
- $(call MakeDir, $(@D) $(SUPPORT_OUTPUTDIR)/jmods)
- $(RM) $@ $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@)
+ $(call MakeDir, $(JMODS_DIR) $(JMODS_TEMPDIR))
+ $(RM) $@ $(JMODS_TEMPDIR)/$(notdir $@)
$(JMOD) create \
--module-version $(VERSION_SHORT) \
--os-name $(REQUIRED_OS_NAME) \
@@ -116,10 +126,10 @@
--os-version $(REQUIRED_OS_VERSION) \
--module-path $(JMODS_DIR) \
--exclude '**{_the.*,*.diz,*.debuginfo,*.dSYM/**,*.dSYM,*.pdb,*.map}' \
- $(JMOD_FLAGS) $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@)
- $(MV) $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@) $@
+ $(JMOD_FLAGS) $(JMODS_TEMPDIR)/$(notdir $@)
+ $(MV) $(JMODS_TEMPDIR)/$(notdir $@) $@
-TARGETS += $(IMAGES_OUTPUTDIR)/jmods/$(MODULE).jmod
+TARGETS += $(JMODS_DIR)/$(MODULE).jmod
################################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/GenerateLinkOptData.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,88 @@
+#
+# 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.
+#
+
+################################################################################
+# Generate classlist
+################################################################################
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include JarArchive.gmk
+
+################################################################################
+# Create a jar with our generator class. Using a jar is intentional since it
+# will load more classes
+
+$(eval $(call SetupJarArchive, CLASSLIST_JAR, \
+ SRCS := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \
+ INCLUDES := build/tools/classlist, \
+ JAR := $(SUPPORT_OUTPUTDIR)/classlist.jar, \
+))
+
+TARGETS += $(CLASSLIST_JAR)
+
+################################################################################
+
+LINK_OPT_DIR := $(SUPPORT_OUTPUTDIR)/link_opt
+CLASSLIST_FILE := $(LINK_OPT_DIR)/classlist
+JLI_TRACE_FILE := $(LINK_OPT_DIR)/jli_trace.out
+
+# If an external buildjdk has been supplied, we don't build a separate interim
+# image, so just use the external build jdk instead.
+ifeq ($(EXTERNAL_BUILDJDK), true)
+ INTERIM_IMAGE_DIR := $(BUILD_JDK)
+endif
+
+$(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXE_SUFFIX) $(CLASSLIST_JAR)
+ $(call MakeDir, $(LINK_OPT_DIR))
+ $(call LogInfo, Generating $(patsubst $(OUTPUT_ROOT)/%, %, $@))
+ $(call LogInfo, Generating $(patsubst $(OUTPUT_ROOT)/%, %, $(JLI_TRACE_FILE)))
+ $(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java -XX:DumpLoadedClassList=$@ \
+ -Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true \
+ -cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
+ build.tools.classlist.HelloClasslist \
+ $(LOG_DEBUG) 2>&1 > $(JLI_TRACE_FILE)
+
+# The jli trace is created by the same recipe as classlist. By declaring these
+# dependencies, make will correctly rebuild both jli trace and classlist
+# incrementally using the single recpie above.
+$(CLASSLIST_FILE): $(JLI_TRACE_FILE)
+$(JLI_TRACE_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXE_SUFFIX) $(CLASSLIST_JAR)
+
+TARGETS += $(CLASSLIST_FILE) $(JLI_TRACE_FILE)
+
+# Copy the classlist file into java.base libs
+$(eval $(call SetupCopyFiles, COPY_CLASSLIST, \
+ FILES := $(CLASSLIST_FILE), \
+ DEST := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base, \
+))
+
+TARGETS += $(COPY_CLASSLIST)
+
+################################################################################
+
+all: $(TARGETS)
--- a/make/Images.gmk Mon Nov 07 16:08:18 2016 +0000
+++ b/make/Images.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -113,8 +113,8 @@
JLINK_ORDER_RESOURCES := **module-info.class
JLINK_JLI_CLASSES :=
ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
- JLINK_ORDER_RESOURCES += @$(SUPPORT_OUTPUTDIR)/classlist/classlist
- JLINK_JLI_CLASSES := --generate-jli-classes=@$(SUPPORT_OUTPUTDIR)/classlist/jli_trace.out
+ JLINK_ORDER_RESOURCES += @$(SUPPORT_OUTPUTDIR)/link_opt/classlist
+ JLINK_JLI_CLASSES := --generate-jli-classes=@$(SUPPORT_OUTPUTDIR)/link_opt/jli_trace.out
endif
JLINK_ORDER_RESOURCES += \
/java.base/java/** \
@@ -142,7 +142,7 @@
$(ECHO) Creating jdk jimage
$(RM) -r $(JDK_IMAGE_DIR)
$(JLINK_TOOL) --add-modules $(JDK_MODULES_LIST) \
- $(JLINK_JDK_EXTRA_OPTS) \
+ $(JLINK_JDK_EXTRA_OPTS) \
--output $(JDK_IMAGE_DIR)
$(TOUCH) $@
@@ -152,7 +152,7 @@
$(RM) -r $(JRE_IMAGE_DIR)
$(JLINK_TOOL) --add-modules $(JRE_MODULES_LIST) \
$(JLINK_JRE_EXTRA_OPTS) \
- --output $(JRE_IMAGE_DIR)
+ --output $(JRE_IMAGE_DIR)
$(TOUCH) $@
JRE_COMPACT1_IMAGE_DIR := $(JRE_IMAGE_DIR)-compact1
@@ -360,34 +360,15 @@
JDK_TARGETS += $(JDK_IMAGE_DIR)/src.zip
################################################################################
-# classlist
-
-ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
- $(eval $(call SetupCopyFiles, JDK_COPY_CLASSLIST, \
- FILES := $(SUPPORT_OUTPUTDIR)/classlist/classlist, \
- DEST := $(JDK_IMAGE_DIR)/lib, \
- ))
-
- JDK_TARGETS += $(JDK_COPY_CLASSLIST)
-
- $(eval $(call SetupCopyFiles, JRE_COPY_CLASSLIST, \
- FILES := $(SUPPORT_OUTPUTDIR)/classlist/classlist, \
- DEST := $(JRE_IMAGE_DIR)/lib, \
- ))
-
- JRE_TARGETS += $(JRE_COPY_CLASSLIST)
-endif
-
-################################################################################
# /demo dir
# Avoid doing the expensive find unless called with "jdk" as target.
ifneq ($(filter jdk, $(MAKECMDGOALS)), )
DEMO_FILES := \
$(if $(wildcard $(SUPPORT_OUTPUTDIR)/demos/image), \
- $(call DoubleDollar, $(call DoubleDollar, \
+ $(call DoubleDollar, \
$(shell $(FIND) $(SUPPORT_OUTPUTDIR)/demos/image \
- -type f -a ! \( -name "_the*" -o -name "javac_state" \) ))) \
+ -type f -a ! \( -name "_the*" -o -name "javac_state" \) )) \
)
ifeq ($(ZIP_EXTERNAL_DEBUG_SYMBOLS), true)
--- a/make/InterimImage.gmk Mon Nov 07 16:08:18 2016 +0000
+++ b/make/InterimImage.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -36,15 +36,15 @@
INTERIM_MODULES_LIST := $(call CommaList, $(INTERIM_IMAGE_MODULES))
-JMODS := $(patsubst %, $(IMAGES_OUTPUTDIR)/jmods/%.jmod, $(INTERIM_IMAGE_MODULES))
+JMODS := $(patsubst %, $(INTERIM_JMODS_DIR)/%.jmod, $(INTERIM_IMAGE_MODULES))
JLINK_TOOL := $(JLINK) \
- --module-path $(IMAGES_OUTPUTDIR)/jmods \
+ --module-path $(INTERIM_JMODS_DIR) \
--endian $(OPENJDK_BUILD_CPU_ENDIAN)
$(INTERIM_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, INTERIM_MODULES_LIST)
- $(ECHO) Creating interim jimage
+ $(call LogWarn, Creating interim jimage)
$(RM) -r $(INTERIM_IMAGE_DIR)
$(JLINK_TOOL) \
--output $(INTERIM_IMAGE_DIR) \
--- a/make/Main.gmk Mon Nov 07 16:08:18 2016 +0000
+++ b/make/Main.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -376,15 +376,29 @@
# The interim-image is a small jlinked image that is used to generate artifacts
# at build time for use when linking the real images.
+INTERIM_JMOD_TARGETS := $(addsuffix -interim-jmod, $(INTERIM_IMAGE_MODULES))
+
+define DeclareInterimJmodRecipe
+ $1-interim-jmod:
+ +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f CreateJmods.gmk \
+ MODULE=$1 \
+ JMODS_DIR=$(INTERIM_JMODS_DIR) \
+ JMODS_TEMPDIR=$(INTERIM_JMODS_DIR)/temp \
+ INTERIM_JMOD=true \
+ )
+endef
+
+$(foreach m, $(INTERIM_IMAGE_MODULES), $(eval $(call DeclareInterimJmodRecipe,$m)))
+
interim-image:
+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f InterimImage.gmk)
ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
- generate-classlist:
- +($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f GenerateClasslist.gmk)
+ generate-link-opt-data:
+ +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f GenerateLinkOptData.gmk)
endif
-ALL_TARGETS += interim-image generate-classlist
+ALL_TARGETS += $(INTERIM_JMOD_TARGETS) interim-image generate-link-opt-data
################################################################################
# Build tests
@@ -607,13 +621,15 @@
# When creating a BUILDJDK, the java compilation has already been done by the
# normal build and copied in.
ifneq ($(CREATING_BUILDJDK), true)
- $(foreach m, $(JAVA_MODULES), $(eval $m-jmod: $m-java))
+ $(foreach m, $(JAVA_MODULES), $(eval $m_JMOD_DEPS += $m-java))
endif
- $(foreach m, $(GENDATA_MODULES), $(eval $m-jmod: $m-gendata))
- $(foreach m, $(RMIC_MODULES), $(eval $m-jmod: $m-rmic))
- $(foreach m, $(LIBS_MODULES), $(eval $m-jmod: $m-libs))
- $(foreach m, $(LAUNCHER_MODULES), $(eval $m-jmod: $m-launchers))
- $(foreach m, $(COPY_MODULES), $(eval $m-jmod: $m-copy))
+ $(foreach m, $(GENDATA_MODULES), $(eval $m_JMOD_DEPS += $m-gendata))
+ $(foreach m, $(RMIC_MODULES), $(eval $m_JMOD_DEPS += $m-rmic))
+ $(foreach m, $(LIBS_MODULES), $(eval $m_JMOD_DEPS += $m-libs))
+ $(foreach m, $(LAUNCHER_MODULES), $(eval $m_JMOD_DEPS += $m-launchers))
+ $(foreach m, $(COPY_MODULES), $(eval $m_JMOD_DEPS += $m-copy))
+ $(foreach m, $(ALL_MODULES), $(eval $m-jmod: $($(m)_JMOD_DEPS)))
+ $(foreach m, $(INTERIM_IMAGE_MODULES), $(eval $m-interim-jmod: $($(m)_JMOD_DEPS)))
# Jmods cannot be created until we have the jmod tool ready to run. During
# a normal build we run it from the exploded image, but when cross compiling
@@ -636,12 +652,13 @@
buildtools-modules: create-buildjdk
else
# While actually creating the buildjdk, the default deps applies.
- $(JMOD_TARGETS): $(DEFAULT_JMOD_DEPS)
+ $(JMOD_TARGETS) $(INTERIM_JMOD_TARGETS): $(DEFAULT_JMOD_DEPS)
endif
else
# The normal non cross compilation case uses the default deps.
# To avoid races with the optimize target, that also needs to happen first.
- $(JMOD_TARGETS): $(DEFAULT_JMOD_DEPS) exploded-image-optimize
+ $(JMOD_TARGETS) $(INTERIM_JMOD_TARGETS): $(DEFAULT_JMOD_DEPS) \
+ exploded-image-optimize
endif
zip-security: java.base-java java.security.jgss-java java.security.jgss-libs \
@@ -654,16 +671,17 @@
ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
ifeq ($(CREATE_BUILDJDK), true)
# If creating a buildjdk, the interim image needs to be based on that.
- generate-classlist: create-buildjdk
+ generate-link-opt-data: create-buildjdk
else ifeq ($(EXTERNAL_BUILDJDK), false)
# If an external buildjdk has been provided, we skip generating an
# interim-image and just use the external buildjdk for generating
# classlist.
- generate-classlist: interim-image
+ generate-link-opt-data: interim-image
endif
- generate-classlist: buildtools-jdk
+ generate-link-opt-data: buildtools-jdk
- jdk-image jre-image: generate-classlist
+ # The generated classlist needs to go into java.base-jmod.
+ java.base-jmod jdk-image jre-image: generate-link-opt-data
endif
jdk-image: jmods zip-source source-tips demos samples jrtfs-jar
@@ -695,7 +713,7 @@
create-buildjdk-interim-image: create-buildjdk-copy
- interim-image: $(addsuffix -jmod, $(INTERIM_IMAGE_MODULES))
+ interim-image: $(INTERIM_JMOD_TARGETS)
test-make: clean-test-make
--- a/make/common/MakeBase.gmk Mon Nov 07 16:08:18 2016 +0000
+++ b/make/common/MakeBase.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -454,7 +454,7 @@
Too many named arguments to macro, please update MAX_PARAMS in MakeBase.gmk))
# Iterate over 2 3 4... and evaluate the named parameters with $1_ as prefix
$(foreach i,$(PARAM_SEQUENCE), $(if $(strip $($i)),\
- $(strip $1)_$(strip $($i)))$(NEWLINE))
+ $(strip $1)_$(strip $(call DoubleDollar, $($i))))$(NEWLINE))
# Debug print all named parameter names and values
$(if $(findstring $(LOG_LEVEL),debug trace), \
$(info $0 $(strip $1) $(foreach i,$(PARAM_SEQUENCE), \
--- a/nashorn/.hgtags Mon Nov 07 16:08:18 2016 +0000
+++ b/nashorn/.hgtags Wed Jul 05 22:25:59 2017 +0200
@@ -376,3 +376,4 @@
785843878cf78d50cc2959ea2c5a4202bbe885b4 jdk-9+140
a46b7d3867957a868a6cc8ee66c05079b883733a jdk-9+141
d3f5d7311a1aec3152b17d75046d5d298245a0b4 jdk-9+142
+b4e57ead3fae4939b70dd345d1f6744a1dedfa21 jdk-9+143
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java Mon Nov 07 16:08:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java Wed Jul 05 22:25:59 2017 +0200
@@ -343,7 +343,7 @@
symbol = null;
} else if (symbol.isParam()) {
// Duplicate parameter. Null return will force an error.
- throw new AssertionError("duplicate parameter");
+ throwParserException(ECMAErrors.getMessage("syntax.error.duplicate.parameter", name), origin);
}
} else if (isVar) {
if (isBlockScope) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java Mon Nov 07 16:08:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java Wed Jul 05 22:25:59 2017 +0200
@@ -45,6 +45,7 @@
import jdk.nashorn.internal.ir.CallNode;
import jdk.nashorn.internal.ir.CaseNode;
import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ClassNode;
import jdk.nashorn.internal.ir.ContinueNode;
import jdk.nashorn.internal.ir.DebuggerNode;
import jdk.nashorn.internal.ir.EmptyNode;
@@ -60,9 +61,11 @@
import jdk.nashorn.internal.ir.LabelNode;
import jdk.nashorn.internal.ir.LexicalContext;
import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
import jdk.nashorn.internal.ir.LiteralNode.PrimitiveLiteralNode;
import jdk.nashorn.internal.ir.LoopNode;
import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
import jdk.nashorn.internal.ir.ReturnNode;
import jdk.nashorn.internal.ir.RuntimeNode;
import jdk.nashorn.internal.ir.Statement;
@@ -70,6 +73,7 @@
import jdk.nashorn.internal.ir.Symbol;
import jdk.nashorn.internal.ir.ThrowNode;
import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.ir.VarNode;
import jdk.nashorn.internal.ir.WhileNode;
import jdk.nashorn.internal.ir.WithNode;
@@ -78,6 +82,8 @@
import jdk.nashorn.internal.parser.Token;
import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.logging.DebugLogger;
@@ -98,6 +104,7 @@
private final DebugLogger log;
private final boolean es6;
+ private final Source source;
// Conservative pattern to test if element names consist of characters valid for identifiers.
// This matches any non-zero length alphanumeric string including _ and $ and not starting with a digit.
@@ -146,6 +153,7 @@
this.log = initLogger(compiler.getContext());
this.es6 = compiler.getScriptEnvironment()._es6;
+ this.source = compiler.getSource();
}
@Override
@@ -241,6 +249,10 @@
}
}
+ if (es6 && expressionStatement.destructuringDeclarationType() != null) {
+ throwNotImplementedYet("es6.destructuring", expressionStatement);
+ }
+
return addStatement(node);
}
@@ -250,6 +262,14 @@
}
@Override
+ public boolean enterForNode(final ForNode forNode) {
+ if (es6 && (forNode.getInit() instanceof ObjectNode || forNode.getInit() instanceof ArrayLiteralNode)) {
+ throwNotImplementedYet("es6.destructuring", forNode);
+ }
+ return super.enterForNode(forNode);
+ }
+
+ @Override
public Node leaveForNode(final ForNode forNode) {
ForNode newForNode = forNode;
@@ -270,6 +290,37 @@
}
@Override
+ public boolean enterFunctionNode(final FunctionNode functionNode) {
+ if (es6) {
+ if (functionNode.getKind() == FunctionNode.Kind.MODULE) {
+ throwNotImplementedYet("es6.module", functionNode);
+ }
+
+ if (functionNode.getKind() == FunctionNode.Kind.GENERATOR) {
+ throwNotImplementedYet("es6.generator", functionNode);
+ }
+ if (functionNode.usesSuper()) {
+ throwNotImplementedYet("es6.super", functionNode);
+ }
+
+ final int numParams = functionNode.getNumOfParams();
+ if (numParams > 0) {
+ final IdentNode lastParam = functionNode.getParameter(numParams - 1);
+ if (lastParam.isRestParameter()) {
+ throwNotImplementedYet("es6.rest.param", lastParam);
+ }
+ }
+ for (final IdentNode param : functionNode.getParameters()) {
+ if (param.isDestructuredParameter()) {
+ throwNotImplementedYet("es6.destructuring", functionNode);
+ }
+ }
+ }
+
+ return super.enterFunctionNode(functionNode);
+ }
+
+ @Override
public Node leaveFunctionNode(final FunctionNode functionNode) {
log.info("END FunctionNode: ", functionNode.getName());
return functionNode;
@@ -578,6 +629,29 @@
}
@Override
+ public boolean enterUnaryNode(final UnaryNode unaryNode) {
+ if (es6) {
+ if (unaryNode.isTokenType(TokenType.YIELD) ||
+ unaryNode.isTokenType(TokenType.YIELD_STAR)) {
+ throwNotImplementedYet("es6.yield", unaryNode);
+ } else if (unaryNode.isTokenType(TokenType.SPREAD_ARGUMENT) ||
+ unaryNode.isTokenType(TokenType.SPREAD_ARRAY)) {
+ throwNotImplementedYet("es6.spread", unaryNode);
+ }
+ }
+
+ return super.enterUnaryNode(unaryNode);
+ }
+
+ @Override
+ public boolean enterASSIGN(BinaryNode binaryNode) {
+ if (es6 && (binaryNode.lhs() instanceof ObjectNode || binaryNode.lhs() instanceof ArrayLiteralNode)) {
+ throwNotImplementedYet("es6.destructuring", binaryNode);
+ }
+ return super.enterASSIGN(binaryNode);
+ }
+
+ @Override
public Node leaveVarNode(final VarNode varNode) {
addStatement(varNode);
if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION)
@@ -608,6 +682,12 @@
return addStatement(withNode);
}
+ @Override
+ public boolean enterClassNode(final ClassNode classNode) {
+ throwNotImplementedYet("es6.class", classNode);
+ return super.enterClassNode(classNode);
+ }
+
/**
* Given a function node that is a callee in a CallNode, replace it with
* the appropriate marker function. This is used by {@link CodeGenerator}
@@ -766,4 +846,13 @@
}
return false;
}
+
+ private void throwNotImplementedYet(final String msgId, final Node node) {
+ final long token = node.getToken();
+ final int line = source.getLine(node.getStart());
+ final int column = source.getColumn(node.getStart());
+ final String message = ECMAErrors.getMessage("unimplemented." + msgId);
+ final String formatted = ErrorManager.format(message, source, line, column, token);
+ throw new RuntimeException(formatted);
+ }
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Mon Nov 07 16:08:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Wed Jul 05 22:25:59 2017 +0200
@@ -45,7 +45,7 @@
}
@Override
- public final boolean enterUnaryNode(final UnaryNode unaryNode) {
+ public boolean enterUnaryNode(final UnaryNode unaryNode) {
switch (unaryNode.tokenType()) {
case ADD:
return enterADD(unaryNode);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Mon Nov 07 16:08:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Wed Jul 05 22:25:59 2017 +0200
@@ -1962,6 +1962,18 @@
switch (type) {
case SEMICOLON:
// for (init; test; modify)
+ if (varDeclList != null) {
+ assert init == null;
+ init = varDeclList.init;
+ // late check for missing assignment, now we know it's a for (init; test; modify) loop
+ if (varDeclList.missingAssignment != null) {
+ if (varDeclList.missingAssignment instanceof IdentNode) {
+ throw error(AbstractParser.message("missing.const.assignment", ((IdentNode)varDeclList.missingAssignment).getName()));
+ } else {
+ throw error(AbstractParser.message("missing.destructuring.assignment"), varDeclList.missingAssignment.getToken());
+ }
+ }
+ }
// for each (init; test; modify) is invalid
if ((flags & ForNode.IS_FOR_EACH) != 0) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties Mon Nov 07 16:08:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties Wed Jul 05 22:25:59 2017 +0200
@@ -214,6 +214,7 @@
syntax.error.strict.cant.delete=cannot delete "{0}" in strict mode
syntax.error.redeclare.variable=Variable "{0}" has already been declared
syntax.error.unprotected.switch.declaration=Unsupported {0} declaration in unprotected switch statement
+syntax.error.duplicate.parameter=Duplicate parameter name "{0}"
io.error.cant.write=cannot write "{0}"
@@ -222,3 +223,12 @@
uri.error.bad.uri=Bad URI "{0}" near offset {1}
list.adapter.null.global=Attempted to create the adapter from outside a JavaScript execution context.
+
+unimplemented.es6.module=ES6 modules are not yet implemented
+unimplemented.es6.rest.param=ES6 function rest parameter declaration is not yet implemented
+unimplemented.es6.yield=ES6 yield and yield* are not yet implemented
+unimplemented.es6.spread=ES6 spread operator is not yet implemented
+unimplemented.es6.class=ES6 class declarations and expressions are not yet implemented
+unimplemented.es6.destructuring=ES6 destructuring is not yet implemented
+unimplemented.es6.generator=ES6 generator is not yet implemented
+unimplemented.es6.super=ES6 super keyword is not yet implemented
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/class.js Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * Class declaration is not implemented
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+try {
+ eval("class Foo {}");
+} catch (e) {
+ print(String(e).replace(/\\/g, "/"))
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/class.js.EXPECTED Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,3 @@
+java.lang.RuntimeException: test/script/basic/es6/class.js#33:3<eval>:1:0 ES6 class declarations and expressions are not yet implemented
+class Foo {}
+^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/destructuring.js Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+/**
+ * Destructuring is not implemented
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+
+function check(code) {
+ try {
+ eval(code);
+ } catch (e) {
+ print(String(e).replace(/\\/g, "/"))
+ }
+}
+
+check("var { x: y } = obj;");
+check("let { x: y } = obj;");
+check("const { x: y } = obj;");
+check("({ x: y }) = obj;");
+check("for (var { x: y } of obj) ;");
+check("for (let { x: y } of obj) ;");
+check("var { x, y } = obj;");
+check("let { x, y } = obj;");
+check("const { x, y } = obj;");
+check("({ x, y }) = obj;");
+check("for (var { x, y } of obj) ;");
+check("for (let { x, y } of obj) ;");
+check("var [a, b] = obj;");
+check("let [a, b] = obj;");
+check("const [a, b] = obj;");
+check("[a, b] = obj;");
+check("for ([a, b] of obj) ;");
+check("for (var [a, b] of obj) ;");
+check("for (let [a, b] of obj) ;");
+check("(function({ x: y }) { return x; })()");
+check("(function({ x }) { return x; })()");
+check("(function([x]) { return x; })()");
+check("for (var [[x, y, z] = [4, 5, 6]] = [7, 8, 9]; iterCount < 1; ) ;");
+check("for ([ arrow = () => {} ] of [[]]) ;");
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/destructuring.js.EXPECTED Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,72 @@
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:4 ES6 destructuring is not yet implemented
+var { x: y } = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:4 ES6 destructuring is not yet implemented
+let { x: y } = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:6 ES6 destructuring is not yet implemented
+const { x: y } = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:1 ES6 destructuring is not yet implemented
+({ x: y }) = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:0 ES6 destructuring is not yet implemented
+for (var { x: y } of obj) ;
+^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:0 ES6 destructuring is not yet implemented
+for (let { x: y } of obj) ;
+^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:4 ES6 destructuring is not yet implemented
+var { x, y } = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:4 ES6 destructuring is not yet implemented
+let { x, y } = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:6 ES6 destructuring is not yet implemented
+const { x, y } = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:1 ES6 destructuring is not yet implemented
+({ x, y }) = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:0 ES6 destructuring is not yet implemented
+for (var { x, y } of obj) ;
+^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:0 ES6 destructuring is not yet implemented
+for (let { x, y } of obj) ;
+^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:4 ES6 destructuring is not yet implemented
+var [a, b] = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:4 ES6 destructuring is not yet implemented
+let [a, b] = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:6 ES6 destructuring is not yet implemented
+const [a, b] = obj;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:0 ES6 destructuring is not yet implemented
+[a, b] = obj;
+^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:0 ES6 destructuring is not yet implemented
+for ([a, b] of obj) ;
+^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:0 ES6 destructuring is not yet implemented
+for (var [a, b] of obj) ;
+^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:0 ES6 destructuring is not yet implemented
+for (let [a, b] of obj) ;
+^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:9 ES6 destructuring is not yet implemented
+(function({ x: y }) { return x; })()
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:9 ES6 destructuring is not yet implemented
+(function({ x }) { return x; })()
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:9 ES6 destructuring is not yet implemented
+(function([x]) { return x; })()
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:9 ES6 destructuring is not yet implemented
+for (var [[x, y, z] = [4, 5, 6]] = [7, 8, 9]; iterCount < 1; ) ;
+ ^
+java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:0 ES6 destructuring is not yet implemented
+for ([ arrow = () => {} ] of [[]]) ;
+^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/generator.js Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * Generators are not implemented
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+function check(code) {
+ try {
+ eval(code);
+ } catch (e) {
+ print(String(e).replace(/\\/g, "/"))
+ }
+}
+
+check("function* func() { yield 1; }");
+check("({ * generatorMethod() { yield 1; } })");
+check("var func = function*() { yield 1; }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/generator.js.EXPECTED Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,9 @@
+java.lang.RuntimeException: test/script/basic/es6/generator.js#34:6<eval>:1:17 ES6 generator is not yet implemented
+function* func() { yield 1; }
+ ^
+java.lang.RuntimeException: test/script/basic/es6/generator.js#34:6<eval>:1:23 ES6 generator is not yet implemented
+({ * generatorMethod() { yield 1; } })
+ ^
+java.lang.RuntimeException: test/script/basic/es6/generator.js#34:6<eval>:1:23 ES6 generator is not yet implemented
+var func = function*() { yield 1; }
+ ^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/restparam.js Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * ES6 rest params are not implemented
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+
+function check(code) {
+ try {
+ eval(code);
+ } catch (e) {
+ print(String(e).replace(/\\/g, "/"))
+ }
+}
+
+check("function func(...args) {}");
+check("function func(x, y, ...args) {}");
+check("({ meth(...args) {} })");
+check("({ meth(x, y, ...args) {} })");
+check("({ meth(x = 0, x) {} })");
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/restparam.js.EXPECTED Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,15 @@
+java.lang.RuntimeException: test/script/basic/es6/restparam.js#35:6<eval>:1:17 ES6 function rest parameter declaration is not yet implemented
+function func(...args) {}
+ ^
+java.lang.RuntimeException: test/script/basic/es6/restparam.js#35:6<eval>:1:23 ES6 function rest parameter declaration is not yet implemented
+function func(x, y, ...args) {}
+ ^
+java.lang.RuntimeException: test/script/basic/es6/restparam.js#35:6<eval>:1:11 ES6 function rest parameter declaration is not yet implemented
+({ meth(...args) {} })
+ ^
+java.lang.RuntimeException: test/script/basic/es6/restparam.js#35:6<eval>:1:17 ES6 function rest parameter declaration is not yet implemented
+({ meth(x, y, ...args) {} })
+ ^
+SyntaxError: test/script/basic/es6/restparam.js#35:6<eval>:1:15 Duplicate parameter name "x"
+({ meth(x = 0, x) {} })
+ ^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/spread.js Wed Jul 05 22:25:59 2017 +0200
@@ -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.
+ *
+ * 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.
+ */
+
+/**
+ * ES6 spread operator is not implemented
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+function check(code) {
+ try {
+ eval(code);
+ } catch (e) {
+ print(String(e).replace(/\\/g, "/"))
+ }
+}
+
+check("var x = [...args]");
+check("var x = [1, 2, ...args]");
+check("var x = [...args, 3, 5]");
+check("var r = func(...arr)");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/spread.js.EXPECTED Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,12 @@
+java.lang.RuntimeException: test/script/basic/es6/spread.js#34:8<eval>:1:9 ES6 spread operator is not yet implemented
+var x = [...args]
+ ^
+java.lang.RuntimeException: test/script/basic/es6/spread.js#34:8<eval>:1:15 ES6 spread operator is not yet implemented
+var x = [1, 2, ...args]
+ ^
+java.lang.RuntimeException: test/script/basic/es6/spread.js#34:8<eval>:1:9 ES6 spread operator is not yet implemented
+var x = [...args, 3, 5]
+ ^
+java.lang.RuntimeException: test/script/basic/es6/spread.js#34:8<eval>:1:13 ES6 spread operator is not yet implemented
+var r = func(...arr)
+ ^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/super.js Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * ES6 super keyword is not implemented
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+function check(code) {
+ try {
+ eval(code);
+ } catch (e) {
+ print(String(e).replace(/\\/g, "/"))
+ }
+}
+
+check("({ meth() { x = super.x } })");
+check("({ meth() { x = super.x() } })");
+check("({ meth() { x = super['x'] } })");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/super.js.EXPECTED Wed Jul 05 22:25:59 2017 +0200
@@ -0,0 +1,9 @@
+java.lang.RuntimeException: test/script/basic/es6/super.js#34:8<eval>:1:10 ES6 super keyword is not yet implemented
+({ meth() { x = super.x } })
+ ^
+java.lang.RuntimeException: test/script/basic/es6/super.js#34:8<eval>:1:10 ES6 super keyword is not yet implemented
+({ meth() { x = super.x() } })
+ ^
+java.lang.RuntimeException: test/script/basic/es6/super.js#34:8<eval>:1:10 ES6 super keyword is not yet implemented
+({ meth() { x = super['x'] } })
+ ^
--- a/test/make/TestJavaCompilation.gmk Mon Nov 07 16:08:18 2016 +0000
+++ b/test/make/TestJavaCompilation.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -202,9 +202,9 @@
DEPENDENCIES := $(OUTPUT_DIR)/_jar3_created, \
SRCS := $(JAR3_SRC_ROOT1) $(JAR3_SRC_ROOT2), \
EXTRA_FILES := extra-file \
- dir2/file$$$$foo.dollar \
+ dir2/file$$foo.dollar \
$(JAR3_SRC_ROOT2)/extra-file-abs, \
- EXCLUDE_FILES := dir1/file1$$$$foo.class, \
+ EXCLUDE_FILES := dir1/file1$$foo.class, \
JAR := $(JAR3_FILE), \
))
--- a/test/make/TestMakeBase.gmk Mon Nov 07 16:08:18 2016 +0000
+++ b/test/make/TestMakeBase.gmk Wed Jul 05 22:25:59 2017 +0200
@@ -209,9 +209,9 @@
test ! -e $(VARDEP_FLAG_FILE)
#
# Test including some problematic characters
- $(MAKE) -f $(THIS_FILE) VARDEP_TEST_VAR='value4 \$$$$ORIGIN' $(VARDEP_TARGET_FILE)
+ $(MAKE) -f $(THIS_FILE) VARDEP_TEST_VAR='value4 \$$ORIGIN' $(VARDEP_TARGET_FILE)
$(RM) $(VARDEP_FLAG_FILE)
- $(MAKE) -f $(THIS_FILE) VARDEP_TEST_VAR='value4 \$$$$ORIGIN' $(VARDEP_TARGET_FILE)
+ $(MAKE) -f $(THIS_FILE) VARDEP_TEST_VAR='value4 \$$ORIGIN' $(VARDEP_TARGET_FILE)
test ! -e $(VARDEP_FLAG_FILE)
# Test specifying a specific value file to store variable in