# HG changeset patch # User dfuchs # Date 1521830687 0 # Node ID 514c68575523f0dc49c380df61c8b6f1fecccd52 # Parent eb72d194235c4d24167b33b8a42998d1b81bc547# Parent 73da889306b7e5d0d7d51231a2915c244979ed98 Merge diff -r eb72d194235c -r 514c68575523 .hgtags --- a/.hgtags Fri Mar 23 18:01:52 2018 +0000 +++ b/.hgtags Fri Mar 23 18:44:47 2018 +0000 @@ -476,3 +476,4 @@ 1fd4d6068f54561cfc67d54fc9ca84af7212c4f8 jdk-11+3 e59941f7247d451fa7df9eaef3fce0f492f8420c jdk-11+4 d5c43e9f08fb9a7c74aae0d48daf17f2ad2afaef jdk-11+5 +3acb379b86725c47e7f33358cb22efa8752ae532 jdk-11+6 diff -r eb72d194235c -r 514c68575523 doc/testing.html --- a/doc/testing.html Fri Mar 23 18:01:52 2018 +0000 +++ b/doc/testing.html Fri Mar 23 18:44:47 2018 +0000 @@ -40,7 +40,7 @@ $ make run-test-jdk_lang JTREG="JOBS=8" $ make run-test TEST=jdk_lang $ make run-test-only TEST="gtest:LogTagSet gtest:LogTagSetDescriptions" GTEST="REPEAT=-1" -$ make run-test TEST="hotspot/test:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OTIONS=-XshowSettings -Xlog:gc+ref=debug" +$ make run-test TEST="hotspot/test:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug" $ make run-test TEST="jtreg:hotspot/test:hotspot_gc hotspot/test/native_sanity/JniVersion.java" $ make exploded-run-test TEST=hotspot_tier1

Configuration

@@ -77,8 +77,8 @@

Test suite control

It is possible to control various aspects of the test suites using make control variables.

These variables use a keyword=value approach to allow multiple values to be set. So, for instance, JTREG="JOBS=1;TIMEOUT=8" will set the JTReg concurrency level to 1 and the timeout factor to 8. This is equivalent to setting JTREG_JOBS=1 JTREG_TIMEOUT=8, but using the keyword format means that the JTREG variable is parsed and verified for correctness, so JTREG="TMIEOUT=8" would give an error, while JTREG_TMIEOUT=8 would just pass unnoticed.

-

To separate multiple keyword=value pairs, use ; (semicolon). Since the shell normally eats ;, the recommended usage is to write the assignment inside qoutes, e.g. JTREG="...;...". This will also make sure spaces are preserved, as in JTREG="VM_OTIONS=-XshowSettings -Xlog:gc+ref=debug".

-

(Other ways are possible, e.g. using backslash: JTREG=JOBS=1\;TIMEOUT=8. Also, as a special technique, the string %20 will be replaced with space for certain options, e.g. JTREG=VM_OTIONS=-XshowSettings%20-Xlog:gc+ref=debug. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)

+

To separate multiple keyword=value pairs, use ; (semicolon). Since the shell normally eats ;, the recommended usage is to write the assignment inside qoutes, e.g. JTREG="...;...". This will also make sure spaces are preserved, as in JTREG="VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug".

+

(Other ways are possible, e.g. using backslash: JTREG=JOBS=1\;TIMEOUT=8. Also, as a special technique, the string %20 will be replaced with space for certain options, e.g. JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)

As far as possible, the names of the keywords have been standardized between test suites.

JTReg keywords

JOBS

diff -r eb72d194235c -r 514c68575523 doc/testing.md --- a/doc/testing.md Fri Mar 23 18:01:52 2018 +0000 +++ b/doc/testing.md Fri Mar 23 18:44:47 2018 +0000 @@ -18,7 +18,7 @@ $ make run-test-jdk_lang JTREG="JOBS=8" $ make run-test TEST=jdk_lang $ make run-test-only TEST="gtest:LogTagSet gtest:LogTagSetDescriptions" GTEST="REPEAT=-1" - $ make run-test TEST="hotspot/test:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OTIONS=-XshowSettings -Xlog:gc+ref=debug" + $ make run-test TEST="hotspot/test:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug" $ make run-test TEST="jtreg:hotspot/test:hotspot_gc hotspot/test/native_sanity/JniVersion.java" $ make exploded-run-test TEST=hotspot_tier1 @@ -140,11 +140,11 @@ To separate multiple keyword=value pairs, use `;` (semicolon). Since the shell normally eats `;`, the recommended usage is to write the assignment inside qoutes, e.g. `JTREG="...;..."`. This will also make sure spaces are preserved, -as in `JTREG="VM_OTIONS=-XshowSettings -Xlog:gc+ref=debug"`. +as in `JTREG="VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"`. (Other ways are possible, e.g. using backslash: `JTREG=JOBS=1\;TIMEOUT=8`. Also, as a special technique, the string `%20` will be replaced with space for -certain options, e.g. `JTREG=VM_OTIONS=-XshowSettings%20-Xlog:gc+ref=debug`. +certain options, e.g. `JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug`. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.) diff -r eb72d194235c -r 514c68575523 make/lib/SoundLibraries.gmk --- a/make/lib/SoundLibraries.gmk Fri Mar 23 18:01:52 2018 +0000 +++ b/make/lib/SoundLibraries.gmk Fri Mar 23 18:44:47 2018 +0000 @@ -23,101 +23,50 @@ # questions. # -LIBJSOUND_SRC_DIRS := \ +LIBJSOUND_SRC_DIRS := $(wildcard \ $(TOPDIR)/src/java.desktop/share/native/libjsound \ - $(TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libjsound \ - # + $(TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS)/native/libjsound \ + ) + LIBJSOUND_CFLAGS := \ -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \ $(LIBJAVA_HEADER_FLAGS) \ $(foreach dir, $(LIBJSOUND_SRC_DIRS), -I$(dir)) \ + -DUSE_PORTS=TRUE \ + -DUSE_DAUDIO=TRUE \ # -LIBJSOUND_SRC_FILES := Utilities.c Platform.c - -EXTRA_SOUND_JNI_LIBS := - -LIBJSOUND_MIDIFILES := \ - MidiInDevice.c \ - MidiInDeviceProvider.c \ - MidiOutDevice.c \ - MidiOutDeviceProvider.c \ - PlatformMidi.c - -# files needed for ports -LIBJSOUND_PORTFILES := \ - PortMixerProvider.c \ - PortMixer.c - -# files needed for direct audio -LIBJSOUND_DAUDIOFILES := \ - DirectAudioDeviceProvider.c \ - DirectAudioDevice.c +ifneq ($(OPENJDK_TARGET_OS), solaris) + LIBJSOUND_CFLAGS += \ + -DUSE_PLATFORM_MIDI_OUT=TRUE \ + -DUSE_PLATFORM_MIDI_IN=TRUE \ + # +endif ifeq ($(OPENJDK_TARGET_OS), windows) - EXTRA_SOUND_JNI_LIBS += jsoundds - LIBJSOUND_CFLAGS += -DX_PLATFORM=X_WINDOWS \ - -DUSE_PLATFORM_MIDI_OUT=TRUE \ - -DUSE_PLATFORM_MIDI_IN=TRUE \ - -DUSE_PORTS=TRUE - LIBJSOUND_SRC_FILES += \ - PLATFORM_API_WinOS_Charset_Util.cpp \ - PLATFORM_API_WinOS_MidiIn.cpp \ - PLATFORM_API_WinOS_MidiOut.c \ - PLATFORM_API_WinOS_Util.c \ - PLATFORM_API_WinOS_Ports.c - LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES) - LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES) -endif # OPENJDK_TARGET_OS windows + LIBJSOUND_CFLAGS += -DX_PLATFORM=X_WINDOWS +endif ifeq ($(OPENJDK_TARGET_OS), linux) - EXTRA_SOUND_JNI_LIBS += jsoundalsa LIBJSOUND_CFLAGS += -DX_PLATFORM=X_LINUX -endif # OPENJDK_TARGET_OS linux +endif ifeq ($(OPENJDK_TARGET_OS), aix) LIBJSOUND_CFLAGS += -DX_PLATFORM=X_AIX -endif # OPENJDK_TARGET_OS aix +endif ifeq ($(OPENJDK_TARGET_OS), macosx) LIBJSOUND_TOOLCHAIN := TOOLCHAIN_LINK_CXX - LIBJSOUND_CFLAGS += -DX_PLATFORM=X_MACOSX \ - -DUSE_PORTS=TRUE \ - -DUSE_DAUDIO=TRUE \ - -DUSE_PLATFORM_MIDI_OUT=TRUE \ - -DUSE_PLATFORM_MIDI_IN=TRUE - LIBJSOUND_SRC_DIRS += $(TOPDIR)/src/java.desktop/macosx/native/libjsound - LIBJSOUND_SRC_FILES += \ - PLATFORM_API_MacOSX_Utils.cpp \ - PLATFORM_API_MacOSX_PCM.cpp \ - PLATFORM_API_MacOSX_Ports.cpp \ - PLATFORM_API_MacOSX_MidiIn.c \ - PLATFORM_API_MacOSX_MidiOut.c \ - PLATFORM_API_MacOSX_MidiUtils.c - LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES) - LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES) - LIBJSOUND_SRC_FILES += $(LIBJSOUND_DAUDIOFILES) -endif # OPENJDK_TARGET_OS macosx + LIBJSOUND_CFLAGS += -DX_PLATFORM=X_MACOSX +endif ifeq ($(OPENJDK_TARGET_OS), solaris) - LIBJSOUND_CFLAGS += -DX_PLATFORM=X_SOLARIS \ - -DUSE_PORTS=TRUE \ - -DUSE_DAUDIO=TRUE - LIBJSOUND_SRC_FILES += \ - PLATFORM_API_SolarisOS_Utils.c \ - PLATFORM_API_SolarisOS_Ports.c \ - PLATFORM_API_SolarisOS_PCM.c - LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES) - LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES) - LIBJSOUND_SRC_FILES += $(LIBJSOUND_DAUDIOFILES) -endif # OPENJDK_TARGET_OS solaris - -LIBJSOUND_CFLAGS += -DEXTRA_SOUND_JNI_LIBS='"$(EXTRA_SOUND_JNI_LIBS)"' + LIBJSOUND_CFLAGS += -DX_PLATFORM=X_SOLARIS +endif $(eval $(call SetupJdkLibrary, BUILD_LIBJSOUND, \ NAME := jsound, \ SRC := $(LIBJSOUND_SRC_DIRS), \ - INCLUDE_FILES := $(LIBJSOUND_SRC_FILES), \ TOOLCHAIN := $(LIBJSOUND_TOOLCHAIN), \ OPTIMIZATION := LOW, \ CFLAGS := $(CFLAGS_JDKLIB) \ @@ -127,10 +76,11 @@ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ LIBS_unix := -ljava -ljvm, \ + LIBS_linux := $(ALSA_LIBS), \ LIBS_macosx := -framework CoreAudio -framework CoreFoundation \ - -framework CoreServices -framework AudioUnit $(LIBCXX) \ - -framework CoreMIDI -framework AudioToolbox, \ - LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib winmm.lib, \ + -framework CoreServices -framework AudioUnit \ + -framework CoreMIDI -framework AudioToolbox $(LIBCXX), \ + LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib dsound.lib winmm.lib user32.lib ole32.lib, \ )) $(BUILD_LIBJSOUND): $(call FindLib, java.base, java) @@ -138,61 +88,3 @@ TARGETS += $(BUILD_LIBJSOUND) ########################################################################################## - -ifneq ($(filter jsoundalsa, $(EXTRA_SOUND_JNI_LIBS)), ) - - $(eval $(call SetupJdkLibrary, BUILD_LIBJSOUNDALSA, \ - NAME := jsoundalsa, \ - SRC := $(LIBJSOUND_SRC_DIRS), \ - INCLUDE_FILES := Utilities.c $(LIBJSOUND_MIDIFILES) $(LIBJSOUND_PORTFILES) \ - $(LIBJSOUND_DAUDIOFILES) \ - PLATFORM_API_LinuxOS_ALSA_CommonUtils.c \ - PLATFORM_API_LinuxOS_ALSA_PCM.c \ - PLATFORM_API_LinuxOS_ALSA_PCMUtils.c \ - PLATFORM_API_LinuxOS_ALSA_MidiIn.c \ - PLATFORM_API_LinuxOS_ALSA_MidiOut.c \ - PLATFORM_API_LinuxOS_ALSA_MidiUtils.c \ - PLATFORM_API_LinuxOS_ALSA_Ports.c, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(ALSA_CFLAGS) \ - $(LIBJSOUND_CFLAGS) \ - -DUSE_DAUDIO=TRUE \ - -DUSE_PORTS=TRUE \ - -DUSE_PLATFORM_MIDI_OUT=TRUE \ - -DUSE_PLATFORM_MIDI_IN=TRUE, \ - MAPFILE := $(TOPDIR)/make/mapfiles/libjsoundalsa/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LIBS := $(ALSA_LIBS) -ljava -ljvm, \ - )) - - $(BUILD_LIBJSOUNDALSA): $(call FindLib, java.base, java) - - TARGETS += $(BUILD_LIBJSOUNDALSA) - -endif - -########################################################################################## - -ifneq ($(filter jsoundds, $(EXTRA_SOUND_JNI_LIBS)), ) - - $(eval $(call SetupJdkLibrary, BUILD_LIBJSOUNDDS, \ - NAME := jsoundds, \ - SRC := $(LIBJSOUND_SRC_DIRS), \ - INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \ - PLATFORM_API_WinOS_Charset_Util.cpp \ - PLATFORM_API_WinOS_DirectSound.cpp, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(LIBJSOUND_CFLAGS) \ - -DUSE_DAUDIO=TRUE, \ - LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LIBS := $(JDKLIB_LIBS) dsound.lib winmm.lib user32.lib ole32.lib, \ - )) - - $(BUILD_LIBJSOUNDDS): $(call FindLib, java.base, java) - - TARGETS += $(BUILD_LIBJSOUNDDS) - -endif diff -r eb72d194235c -r 514c68575523 make/mapfiles/libjsound/mapfile-vers --- a/make/mapfiles/libjsound/mapfile-vers Fri Mar 23 18:01:52 2018 +0000 +++ b/make/mapfiles/libjsound/mapfile-vers Fri Mar 23 18:44:47 2018 +0000 @@ -65,8 +65,6 @@ Java_com_sun_media_sound_MidiOutDeviceProvider_nGetNumDevices; Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVendor; Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVersion; - Java_com_sun_media_sound_Platform_nGetExtraLibraries; - Java_com_sun_media_sound_Platform_nGetLibraryForFeature; Java_com_sun_media_sound_Platform_nIsBigEndian; Java_com_sun_media_sound_PortMixer_nClose; Java_com_sun_media_sound_PortMixer_nControlGetFloatValue; diff -r eb72d194235c -r 514c68575523 make/mapfiles/libjsoundalsa/mapfile-vers --- a/make/mapfiles/libjsoundalsa/mapfile-vers Fri Mar 23 18:01:52 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -# -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# Define library interface. - -SUNWprivate_1.1 { - global: - Java_com_sun_media_sound_DirectAudioDeviceProvider_nGetNumDevices; - Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo; - Java_com_sun_media_sound_DirectAudioDevice_nAvailable; - Java_com_sun_media_sound_DirectAudioDevice_nClose; - Java_com_sun_media_sound_DirectAudioDevice_nFlush; - Java_com_sun_media_sound_DirectAudioDevice_nGetBufferSize; - Java_com_sun_media_sound_DirectAudioDevice_nGetBytePosition; - Java_com_sun_media_sound_DirectAudioDevice_nGetFormats; - Java_com_sun_media_sound_DirectAudioDevice_nIsStillDraining; - Java_com_sun_media_sound_DirectAudioDevice_nOpen; - Java_com_sun_media_sound_DirectAudioDevice_nRead; - Java_com_sun_media_sound_DirectAudioDevice_nRequiresServicing; - Java_com_sun_media_sound_DirectAudioDevice_nService; - Java_com_sun_media_sound_DirectAudioDevice_nSetBytePosition; - Java_com_sun_media_sound_DirectAudioDevice_nStart; - Java_com_sun_media_sound_DirectAudioDevice_nStop; - Java_com_sun_media_sound_DirectAudioDevice_nWrite; - Java_com_sun_media_sound_MidiInDeviceProvider_nGetDescription; - Java_com_sun_media_sound_MidiInDeviceProvider_nGetName; - Java_com_sun_media_sound_MidiInDeviceProvider_nGetNumDevices; - Java_com_sun_media_sound_MidiInDeviceProvider_nGetVendor; - Java_com_sun_media_sound_MidiInDeviceProvider_nGetVersion; - Java_com_sun_media_sound_MidiInDevice_nClose; - Java_com_sun_media_sound_MidiInDevice_nGetMessages; - Java_com_sun_media_sound_MidiInDevice_nGetTimeStamp; - Java_com_sun_media_sound_MidiInDevice_nOpen; - Java_com_sun_media_sound_MidiInDevice_nStart; - Java_com_sun_media_sound_MidiInDevice_nStop; - Java_com_sun_media_sound_MidiOutDeviceProvider_nGetDescription; - Java_com_sun_media_sound_MidiOutDeviceProvider_nGetName; - Java_com_sun_media_sound_MidiOutDeviceProvider_nGetNumDevices; - Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVendor; - Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVersion; - Java_com_sun_media_sound_MidiOutDevice_nClose; - Java_com_sun_media_sound_MidiOutDevice_nGetTimeStamp; - Java_com_sun_media_sound_MidiOutDevice_nOpen; - Java_com_sun_media_sound_MidiOutDevice_nSendLongMessage; - Java_com_sun_media_sound_MidiOutDevice_nSendShortMessage; - Java_com_sun_media_sound_PortMixerProvider_nGetNumDevices; - Java_com_sun_media_sound_PortMixerProvider_nNewPortMixerInfo; - Java_com_sun_media_sound_PortMixer_nClose; - Java_com_sun_media_sound_PortMixer_nControlGetFloatValue; - Java_com_sun_media_sound_PortMixer_nControlGetIntValue; - Java_com_sun_media_sound_PortMixer_nControlSetFloatValue; - Java_com_sun_media_sound_PortMixer_nControlSetIntValue; - Java_com_sun_media_sound_PortMixer_nGetControls; - Java_com_sun_media_sound_PortMixer_nGetPortCount; - Java_com_sun_media_sound_PortMixer_nGetPortName; - Java_com_sun_media_sound_PortMixer_nGetPortType; - Java_com_sun_media_sound_PortMixer_nOpen; - local: - *; -}; diff -r eb72d194235c -r 514c68575523 make/mapfiles/libnio/mapfile-linux --- a/make/mapfiles/libnio/mapfile-linux Fri Mar 23 18:01:52 2018 +0000 +++ b/make/mapfiles/libnio/mapfile-linux Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2018, 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 @@ -37,23 +37,12 @@ Java_sun_nio_ch_DatagramDispatcher_readv0; Java_sun_nio_ch_DatagramDispatcher_write0; Java_sun_nio_ch_DatagramDispatcher_writev0; - Java_sun_nio_ch_EPollArrayWrapper_epollCreate; - Java_sun_nio_ch_EPollArrayWrapper_epollCtl; - Java_sun_nio_ch_EPollArrayWrapper_epollWait; - Java_sun_nio_ch_EPollArrayWrapper_init; - Java_sun_nio_ch_EPollArrayWrapper_interrupt; - Java_sun_nio_ch_EPollArrayWrapper_offsetofData; - Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent; Java_sun_nio_ch_EPoll_eventSize; Java_sun_nio_ch_EPoll_eventsOffset; Java_sun_nio_ch_EPoll_dataOffset; - Java_sun_nio_ch_EPoll_epollCreate; - Java_sun_nio_ch_EPoll_epollCtl; - Java_sun_nio_ch_EPoll_epollWait; - Java_sun_nio_ch_EPollPort_close0; - Java_sun_nio_ch_EPollPort_drain1; - Java_sun_nio_ch_EPollPort_interrupt; - Java_sun_nio_ch_EPollPort_socketpair; + Java_sun_nio_ch_EPoll_create; + Java_sun_nio_ch_EPoll_ctl; + Java_sun_nio_ch_EPoll_wait; Java_sun_nio_ch_FileChannelImpl_initIDs; Java_sun_nio_ch_FileChannelImpl_map0; Java_sun_nio_ch_FileChannelImpl_position0; @@ -95,6 +84,7 @@ Java_sun_nio_ch_IOUtil_makePipe; Java_sun_nio_ch_IOUtil_randomBytes; Java_sun_nio_ch_IOUtil_setfdVal; + Java_sun_nio_ch_IOUtil_write1; Java_sun_nio_ch_NativeThread_current; Java_sun_nio_ch_NativeThread_init; Java_sun_nio_ch_NativeThread_signal; diff -r eb72d194235c -r 514c68575523 make/mapfiles/libnio/mapfile-macosx --- a/make/mapfiles/libnio/mapfile-macosx Fri Mar 23 18:01:52 2018 +0000 +++ b/make/mapfiles/libnio/mapfile-macosx Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2018, 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 @@ -42,7 +42,7 @@ Java_sun_nio_ch_FileChannelImpl_position0; Java_sun_nio_ch_FileChannelImpl_transferTo0; Java_sun_nio_ch_FileChannelImpl_unmap0; - Java_sun_nio_ch_FileDispatcherImpl_allocate0; + Java_sun_nio_ch_FileDispatcherImpl_allocate0; Java_sun_nio_ch_FileDispatcherImpl_close0; Java_sun_nio_ch_FileDispatcherImpl_closeIntFD; Java_sun_nio_ch_FileDispatcherImpl_force0; @@ -71,117 +71,115 @@ Java_sun_nio_ch_IOUtil_configureBlocking; Java_sun_nio_ch_IOUtil_drain; Java_sun_nio_ch_IOUtil_fdVal; + Java_sun_nio_ch_IOUtil_fdLimit; Java_sun_nio_ch_IOUtil_initIDs; + Java_sun_nio_ch_IOUtil_iovMax; Java_sun_nio_ch_IOUtil_makePipe; Java_sun_nio_ch_IOUtil_randomBytes; Java_sun_nio_ch_IOUtil_setfdVal; - Java_sun_nio_ch_IOUtil_iovMax; - Java_sun_nio_ch_KQueue_kqueue; - Java_sun_nio_ch_KQueue_keventRegister; - Java_sun_nio_ch_KQueue_keventPoll; - Java_sun_nio_ch_KQueue_keventSize; - Java_sun_nio_ch_KQueue_identOffset; - Java_sun_nio_ch_KQueue_filterOffset; - Java_sun_nio_ch_KQueue_flagsOffset; - Java_sun_nio_ch_KQueuePort_socketpair; - Java_sun_nio_ch_KQueuePort_interrupt; - Java_sun_nio_ch_KQueuePort_drain1; - Java_sun_nio_ch_KQueuePort_close0; - Java_sun_nio_ch_NativeThread_current; - Java_sun_nio_ch_NativeThread_init; - Java_sun_nio_ch_NativeThread_signal; - Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0; - Java_sun_nio_ch_Net_canJoin6WithIPv4Group0; - Java_sun_nio_ch_Net_socket0; - Java_sun_nio_ch_Net_bind0; - Java_sun_nio_ch_Net_connect0; - Java_sun_nio_ch_Net_listen; - Java_sun_nio_ch_Net_localPort; - Java_sun_nio_ch_Net_localInetAddress; - Java_sun_nio_ch_Net_getIntOption0; - Java_sun_nio_ch_Net_setIntOption0; + Java_sun_nio_ch_IOUtil_write1; + Java_sun_nio_ch_KQueue_create; + Java_sun_nio_ch_KQueue_register; + Java_sun_nio_ch_KQueue_poll; + Java_sun_nio_ch_KQueue_keventSize; + Java_sun_nio_ch_KQueue_identOffset; + Java_sun_nio_ch_KQueue_filterOffset; + Java_sun_nio_ch_KQueue_flagsOffset; + Java_sun_nio_ch_NativeThread_current; + Java_sun_nio_ch_NativeThread_init; + Java_sun_nio_ch_NativeThread_signal; + Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0; + Java_sun_nio_ch_Net_canJoin6WithIPv4Group0; + Java_sun_nio_ch_Net_socket0; + Java_sun_nio_ch_Net_bind0; + Java_sun_nio_ch_Net_connect0; + Java_sun_nio_ch_Net_listen; + Java_sun_nio_ch_Net_localPort; + Java_sun_nio_ch_Net_localInetAddress; + Java_sun_nio_ch_Net_getIntOption0; + Java_sun_nio_ch_Net_setIntOption0; Java_sun_nio_ch_Net_initIDs; Java_sun_nio_ch_Net_isIPv6Available0; Java_sun_nio_ch_Net_isReusePortAvailable0; - Java_sun_nio_ch_Net_joinOrDrop4; - Java_sun_nio_ch_Net_blockOrUnblock4; - Java_sun_nio_ch_Net_joinOrDrop6; - Java_sun_nio_ch_Net_blockOrUnblock6; - Java_sun_nio_ch_Net_setInterface4; - Java_sun_nio_ch_Net_getInterface4; - Java_sun_nio_ch_Net_setInterface6; - Java_sun_nio_ch_Net_getInterface6; - Java_sun_nio_ch_Net_shutdown; - Java_sun_nio_ch_Net_poll; - Java_sun_nio_ch_Net_pollinValue; - Java_sun_nio_ch_Net_polloutValue; - Java_sun_nio_ch_Net_pollerrValue; - Java_sun_nio_ch_Net_pollhupValue; - Java_sun_nio_ch_Net_pollnvalValue; - Java_sun_nio_ch_Net_pollconnValue; + Java_sun_nio_ch_Net_joinOrDrop4; + Java_sun_nio_ch_Net_blockOrUnblock4; + Java_sun_nio_ch_Net_joinOrDrop6; + Java_sun_nio_ch_Net_blockOrUnblock6; + Java_sun_nio_ch_Net_setInterface4; + Java_sun_nio_ch_Net_getInterface4; + Java_sun_nio_ch_Net_setInterface6; + Java_sun_nio_ch_Net_getInterface6; + Java_sun_nio_ch_Net_shutdown; + Java_sun_nio_ch_Net_poll; + Java_sun_nio_ch_Net_pollinValue; + Java_sun_nio_ch_Net_polloutValue; + Java_sun_nio_ch_Net_pollerrValue; + Java_sun_nio_ch_Net_pollhupValue; + Java_sun_nio_ch_Net_pollnvalValue; + Java_sun_nio_ch_Net_pollconnValue; Java_sun_nio_ch_Net_isExclusiveBindAvailable; Java_sun_nio_ch_PollArrayWrapper_interrupt; Java_sun_nio_ch_PollArrayWrapper_poll0; Java_sun_nio_ch_ServerSocketChannelImpl_accept0; Java_sun_nio_ch_ServerSocketChannelImpl_initIDs; Java_sun_nio_ch_SocketChannelImpl_checkConnect; - Java_sun_nio_ch_SocketChannelImpl_sendOutOfBandData; - Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0; - Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs; - Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect; - Java_sun_nio_fs_BsdNativeDispatcher_initIDs; - Java_sun_nio_fs_BsdNativeDispatcher_getfsstat; - Java_sun_nio_fs_BsdNativeDispatcher_fsstatEntry; - Java_sun_nio_fs_BsdNativeDispatcher_endfsstat; - Java_sun_nio_fs_UnixNativeDispatcher_init; - Java_sun_nio_fs_UnixNativeDispatcher_getcwd; - Java_sun_nio_fs_UnixNativeDispatcher_strerror; - Java_sun_nio_fs_UnixNativeDispatcher_dup; - Java_sun_nio_fs_UnixNativeDispatcher_access0; - Java_sun_nio_fs_UnixNativeDispatcher_exists0; - Java_sun_nio_fs_UnixNativeDispatcher_stat0; + Java_sun_nio_ch_SocketChannelImpl_sendOutOfBandData; + Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0; + Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs; + Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect; + Java_sun_nio_fs_BsdNativeDispatcher_initIDs; + Java_sun_nio_fs_BsdNativeDispatcher_getfsstat; + Java_sun_nio_fs_BsdNativeDispatcher_fsstatEntry; + Java_sun_nio_fs_BsdNativeDispatcher_endfsstat; + Java_sun_nio_fs_UnixNativeDispatcher_init; + Java_sun_nio_fs_UnixNativeDispatcher_getcwd; + Java_sun_nio_fs_UnixNativeDispatcher_strerror; + Java_sun_nio_fs_UnixNativeDispatcher_dup; + Java_sun_nio_fs_UnixNativeDispatcher_access0; + Java_sun_nio_fs_UnixNativeDispatcher_exists0; + Java_sun_nio_fs_UnixNativeDispatcher_stat0; Java_sun_nio_fs_UnixNativeDispatcher_stat1; - Java_sun_nio_fs_UnixNativeDispatcher_lstat0; - Java_sun_nio_fs_UnixNativeDispatcher_fstat; - Java_sun_nio_fs_UnixNativeDispatcher_fstatat0; - Java_sun_nio_fs_UnixNativeDispatcher_chmod0; - Java_sun_nio_fs_UnixNativeDispatcher_fchmod; - Java_sun_nio_fs_UnixNativeDispatcher_chown0; - Java_sun_nio_fs_UnixNativeDispatcher_lchown0; - Java_sun_nio_fs_UnixNativeDispatcher_fchown; - Java_sun_nio_fs_UnixNativeDispatcher_utimes0; - Java_sun_nio_fs_UnixNativeDispatcher_futimes; - Java_sun_nio_fs_UnixNativeDispatcher_open0; - Java_sun_nio_fs_UnixNativeDispatcher_openat0; - Java_sun_nio_fs_UnixNativeDispatcher_close0; - Java_sun_nio_fs_UnixNativeDispatcher_read; - Java_sun_nio_fs_UnixNativeDispatcher_write; - Java_sun_nio_fs_UnixNativeDispatcher_fopen0; - Java_sun_nio_fs_UnixNativeDispatcher_fclose; - Java_sun_nio_fs_UnixNativeDispatcher_opendir0; - Java_sun_nio_fs_UnixNativeDispatcher_fdopendir; - Java_sun_nio_fs_UnixNativeDispatcher_readdir; - Java_sun_nio_fs_UnixNativeDispatcher_closedir; - Java_sun_nio_fs_UnixNativeDispatcher_link0; - Java_sun_nio_fs_UnixNativeDispatcher_unlink0; - Java_sun_nio_fs_UnixNativeDispatcher_unlinkat0; - Java_sun_nio_fs_UnixNativeDispatcher_rename0; - Java_sun_nio_fs_UnixNativeDispatcher_renameat0; - Java_sun_nio_fs_UnixNativeDispatcher_mkdir0; - Java_sun_nio_fs_UnixNativeDispatcher_rmdir0; - Java_sun_nio_fs_UnixNativeDispatcher_symlink0; - Java_sun_nio_fs_UnixNativeDispatcher_readlink0; - Java_sun_nio_fs_UnixNativeDispatcher_realpath0; - Java_sun_nio_fs_UnixNativeDispatcher_statvfs0; - Java_sun_nio_fs_UnixNativeDispatcher_pathconf0; - Java_sun_nio_fs_UnixNativeDispatcher_fpathconf; - Java_sun_nio_fs_UnixNativeDispatcher_mknod0; - Java_sun_nio_fs_UnixNativeDispatcher_getpwuid; - Java_sun_nio_fs_UnixNativeDispatcher_getgrgid; - Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0; - Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0; - Java_sun_nio_fs_UnixCopyFile_transfer; - handleSocketError; + Java_sun_nio_fs_UnixNativeDispatcher_lstat0; + Java_sun_nio_fs_UnixNativeDispatcher_fstat; + Java_sun_nio_fs_UnixNativeDispatcher_fstatat0; + Java_sun_nio_fs_UnixNativeDispatcher_chmod0; + Java_sun_nio_fs_UnixNativeDispatcher_fchmod; + Java_sun_nio_fs_UnixNativeDispatcher_chown0; + Java_sun_nio_fs_UnixNativeDispatcher_lchown0; + Java_sun_nio_fs_UnixNativeDispatcher_fchown; + Java_sun_nio_fs_UnixNativeDispatcher_utimes0; + Java_sun_nio_fs_UnixNativeDispatcher_futimes; + Java_sun_nio_fs_UnixNativeDispatcher_open0; + Java_sun_nio_fs_UnixNativeDispatcher_openat0; + Java_sun_nio_fs_UnixNativeDispatcher_close0; + Java_sun_nio_fs_UnixNativeDispatcher_read; + Java_sun_nio_fs_UnixNativeDispatcher_write; + Java_sun_nio_fs_UnixNativeDispatcher_fopen0; + Java_sun_nio_fs_UnixNativeDispatcher_fclose; + Java_sun_nio_fs_UnixNativeDispatcher_opendir0; + Java_sun_nio_fs_UnixNativeDispatcher_fdopendir; + Java_sun_nio_fs_UnixNativeDispatcher_readdir; + Java_sun_nio_fs_UnixNativeDispatcher_closedir; + Java_sun_nio_fs_UnixNativeDispatcher_link0; + Java_sun_nio_fs_UnixNativeDispatcher_unlink0; + Java_sun_nio_fs_UnixNativeDispatcher_unlinkat0; + Java_sun_nio_fs_UnixNativeDispatcher_rename0; + Java_sun_nio_fs_UnixNativeDispatcher_renameat0; + Java_sun_nio_fs_UnixNativeDispatcher_mkdir0; + Java_sun_nio_fs_UnixNativeDispatcher_rmdir0; + Java_sun_nio_fs_UnixNativeDispatcher_symlink0; + Java_sun_nio_fs_UnixNativeDispatcher_readlink0; + Java_sun_nio_fs_UnixNativeDispatcher_realpath0; + Java_sun_nio_fs_UnixNativeDispatcher_statvfs0; + Java_sun_nio_fs_UnixNativeDispatcher_pathconf0; + Java_sun_nio_fs_UnixNativeDispatcher_fpathconf; + Java_sun_nio_fs_UnixNativeDispatcher_mknod0; + Java_sun_nio_fs_UnixNativeDispatcher_getpwuid; + Java_sun_nio_fs_UnixNativeDispatcher_getgrgid; + Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0; + Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0; + Java_sun_nio_fs_UnixCopyFile_transfer; + handleSocketError; local: *; diff -r eb72d194235c -r 514c68575523 make/mapfiles/libnio/mapfile-solaris --- a/make/mapfiles/libnio/mapfile-solaris Fri Mar 23 18:01:52 2018 +0000 +++ b/make/mapfiles/libnio/mapfile-solaris Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2018, 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,6 @@ Java_sun_nio_ch_DatagramDispatcher_write0; Java_sun_nio_ch_DatagramDispatcher_writev0; Java_sun_nio_ch_DevPollArrayWrapper_init; - Java_sun_nio_ch_DevPollArrayWrapper_interrupt; Java_sun_nio_ch_DevPollArrayWrapper_poll0; Java_sun_nio_ch_DevPollArrayWrapper_register; Java_sun_nio_ch_DevPollArrayWrapper_registerMultiple; @@ -83,6 +82,7 @@ Java_sun_nio_ch_IOUtil_makePipe; Java_sun_nio_ch_IOUtil_randomBytes; Java_sun_nio_ch_IOUtil_setfdVal; + Java_sun_nio_ch_IOUtil_write1; Java_sun_nio_ch_NativeThread_current; Java_sun_nio_ch_NativeThread_init; Java_sun_nio_ch_NativeThread_signal; diff -r eb72d194235c -r 514c68575523 make/scripts/compare.sh --- a/make/scripts/compare.sh Fri Mar 23 18:01:52 2018 +0000 +++ b/make/scripts/compare.sh Fri Mar 23 18:44:47 2018 +0000 @@ -1298,22 +1298,37 @@ # Find the common images to compare, prioritizing later build stages if [ -d "$THIS/install/jdk" ] && [ -d "$OTHER/install/jdk" ]; then THIS_JDK="$THIS/install/jdk" - THIS_JRE="$THIS/install/jre" OTHER_JDK="$OTHER/install/jdk" - OTHER_JRE="$OTHER/install/jre" - echo "Selecting install images for compare" + echo "Selecting install images for JDK compare" + if [ -d "$THIS/install/jre" ] && [ -d "$OTHER/install/jre" ]; then + THIS_JRE="$THIS/install/jre" + OTHER_JRE="$OTHER/install/jre" + echo "Also selecting install images for JRE compare" + else + echo "No install JRE image found" + fi elif [ -d "$THIS/images/jdk" ] && [ -d "$OTHER/deploy/images/jdk" ]; then THIS_JDK="$THIS/images/jdk" - THIS_JRE="$THIS/images/jre" OTHER_JDK="$OTHER/deploy/images/jdk" - OTHER_JRE="$OTHER/deploy/images/jre" - echo "Selecting deploy images for compare" + echo "Selecting deploy images for JDK compare" + if [ -d "$THIS/images/jre" ] && [ -d "$OTHER/deploy/images/jre" ]; then + THIS_JRE="$THIS/images/jre" + OTHER_JRE="$OTHER/deploy/images/jre" + echo "Selecting deploy images for JRE compare" + else + echo "No deploy JRE image found" + fi elif [ -d "$THIS/images/jdk" ] && [ -d "$OTHER/images/jdk" ]; then THIS_JDK="$THIS/images/jdk" - THIS_JRE="$THIS/images/jre" OTHER_JDK="$OTHER/images/jdk" - OTHER_JRE="$OTHER/images/jre" - echo "Selecting jdk images for compare" + echo "Selecting normal images for JDK compare" + if [ -d "$THIS/images/jre" ] && [ -d "$OTHER/images/jre" ]; then + THIS_JRE="$THIS/images/jre" + OTHER_JRE="$OTHER/images/jre" + echo "Selecting normal images for JRE compare" + else + echo "No normal JRE image found" + fi elif [ -d "$(ls -d $THIS/licensee-src/build/*/images/jdk 2> /dev/null)" ] \ && [ -d "$(ls -d $OTHER/licensee-src/build/*/images/jdk 2> /dev/null)" ] then @@ -1406,9 +1421,11 @@ else OTHER_SEC_DIR="$OTHER/tmp" fi - OTHER_SEC_BIN="$OTHER_SEC_DIR/sec-bin.zip" - THIS_SEC_DIR="$THIS/images" - THIS_SEC_BIN="$THIS_SEC_DIR/sec-bin.zip" + if [ -f "$THIS_SEC_DIR/sec-bin.zip" ]; then + OTHER_SEC_BIN="$OTHER_SEC_DIR/sec-bin.zip" + THIS_SEC_DIR="$THIS/images" + THIS_SEC_BIN="$THIS_SEC_DIR/sec-bin.zip" + fi if [ "$OPENJDK_TARGET_OS" = "windows" ]; then if [ "$OPENJDK_TARGET_CPU" = "x86_64" ]; then JGSS_WINDOWS_BIN="jgss-windows-x64-bin.zip" @@ -1437,11 +1454,12 @@ if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then echo -n "JDK " compare_dirs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk + echo -n "JDK " + compare_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk + fi + if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then echo -n "JRE " compare_dirs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre - - echo -n "JDK " - compare_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk echo -n "JRE " compare_files $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre fi @@ -1480,49 +1498,38 @@ fi fi -if [ "$CMP_PERMS" = "true" ]; then +if [ "$CMP_LIBS" = "true" ]; then if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then echo -n "JDK " - compare_permissions $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk - echo -n "JRE " - compare_permissions $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre + compare_all_libs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk fi if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then - compare_permissions $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir + compare_all_libs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then echo -n "JavaAppletPlugin " - compare_permissions $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + compare_all_libs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin fi if [ -n "$THIS_SPARKLE_DIR" ] && [ -n "$OTHER_SPARKLE_DIR" ]; then echo -n "Sparkle.framework " - compare_permissions $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle + compare_all_libs $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle fi fi -if [ "$CMP_TYPES" = "true" ]; then +if [ "$CMP_EXECS" = "true" ]; then if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then - echo -n "JDK " - compare_file_types $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk - echo -n "JRE " - compare_file_types $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre - fi - if [ -n "$THIS_JDK_BUNDLE" ] && [ -n "$OTHER_JDK_BUNDLE" ]; then - echo -n "JDK Bundle " - compare_file_types $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle - echo -n "JRE Bundle " - compare_file_types $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle + compare_all_execs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk fi if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then - compare_file_types $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir + compare_all_execs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then echo -n "JavaAppletPlugin " - compare_file_types $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + compare_all_execs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin fi if [ -n "$THIS_SPARKLE_DIR" ] && [ -n "$OTHER_SPARKLE_DIR" ]; then echo -n "Sparkle.framework " - compare_file_types $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle + compare_all_execs $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle fi fi @@ -1530,6 +1537,8 @@ if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then echo -n "JDK " compare_general_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk + fi + if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then echo -n "JRE " compare_general_files $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre fi @@ -1601,46 +1610,53 @@ fi fi -if [ "$CMP_LIBS" = "true" ]; then +if [ "$CMP_PERMS" = "true" ]; then if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then echo -n "JDK " - compare_all_libs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk - if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then - echo -n "JRE " - compare_all_libs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre - fi + compare_permissions $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk + fi + if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then + echo -n "JRE " + compare_permissions $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre fi if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then - compare_all_libs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir + compare_permissions $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then echo -n "JavaAppletPlugin " - compare_all_libs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + compare_permissions $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin fi if [ -n "$THIS_SPARKLE_DIR" ] && [ -n "$OTHER_SPARKLE_DIR" ]; then echo -n "Sparkle.framework " - compare_all_libs $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle + compare_permissions $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle fi fi -if [ "$CMP_EXECS" = "true" ]; then +if [ "$CMP_TYPES" = "true" ]; then if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then - compare_all_execs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk - if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then - echo -n "JRE " - compare_all_execs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre - fi + echo -n "JDK " + compare_file_types $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk + fi + if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then + echo -n "JRE " + compare_file_types $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre + fi + if [ -n "$THIS_JDK_BUNDLE" ] && [ -n "$OTHER_JDK_BUNDLE" ]; then + echo -n "JDK Bundle " + compare_file_types $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle + echo -n "JRE Bundle " + compare_file_types $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle fi if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then - compare_all_execs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir + compare_file_types $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then echo -n "JavaAppletPlugin " - compare_all_execs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + compare_file_types $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin fi if [ -n "$THIS_SPARKLE_DIR" ] && [ -n "$OTHER_SPARKLE_DIR" ]; then echo -n "Sparkle.framework " - compare_all_execs $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle + compare_file_types $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle fi fi diff -r eb72d194235c -r 514c68575523 make/scripts/compare_exceptions.sh.incl --- a/make/scripts/compare_exceptions.sh.incl Fri Mar 23 18:01:52 2018 +0000 +++ b/make/scripts/compare_exceptions.sh.incl Fri Mar 23 18:44:47 2018 +0000 @@ -339,7 +339,7 @@ DIS_DIFF_FILTER="$SED \ -e 's/^[0-9a-f]\{16\}/:/' \ - -e 's/^ *[0-9a-f]\{3,8\}:/ :/' \ + -e 's/^ *[0-9a-f]\{3,12\}:/ :/' \ -e 's/: [0-9a-f][0-9a-f]\( [0-9a-f][0-9a-f]\)\{2,10\}/: /' \ -e 's/\$[a-zA-Z0-9_\$]\{15\}\././' \ -e 's/, [0-9a-fx\-]\{1,8\}/, /g' \ diff -r eb72d194235c -r 514c68575523 src/java.base/linux/classes/sun/nio/ch/EPoll.java --- a/src/java.base/linux/classes/sun/nio/ch/EPoll.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/linux/classes/sun/nio/ch/EPoll.java Fri Mar 23 18:44:47 2018 +0000 @@ -109,11 +109,11 @@ private static native int dataOffset(); - static native int epollCreate() throws IOException; + static native int create() throws IOException; - static native int epollCtl(int epfd, int opcode, int fd, int events); + static native int ctl(int epfd, int opcode, int fd, int events); - static native int epollWait(int epfd, long pollAddress, int numfds) + static native int wait(int epfd, long pollAddress, int numfds, int timeout) throws IOException; static { diff -r eb72d194235c -r 514c68575523 src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java --- a/src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java Fri Mar 23 18:01:52 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,309 +0,0 @@ -/* - * Copyright (c) 2005, 2018, 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.nio.ch; - -import java.io.IOException; -import java.security.AccessController; -import java.util.BitSet; -import java.util.HashMap; -import java.util.Map; -import sun.security.action.GetIntegerAction; - -/** - * Manipulates a native array of epoll_event structs on Linux: - * - * typedef union epoll_data { - * void *ptr; - * int fd; - * __uint32_t u32; - * __uint64_t u64; - * } epoll_data_t; - * - * struct epoll_event { - * __uint32_t events; - * epoll_data_t data; - * }; - * - * The system call to wait for I/O events is epoll_wait(2). It populates an - * array of epoll_event structures that are passed to the call. The data - * member of the epoll_event structure contains the same data as was set - * when the file descriptor was registered to epoll via epoll_ctl(2). In - * this implementation we set data.fd to be the file descriptor that we - * register. That way, we have the file descriptor available when we - * process the events. - */ - -class EPollArrayWrapper { - // EPOLL_EVENTS - private static final int EPOLLIN = 0x001; - - // opcodes - private static final int EPOLL_CTL_ADD = 1; - private static final int EPOLL_CTL_DEL = 2; - private static final int EPOLL_CTL_MOD = 3; - - // Miscellaneous constants - private static final int SIZE_EPOLLEVENT = sizeofEPollEvent(); - private static final int EVENT_OFFSET = 0; - private static final int DATA_OFFSET = offsetofData(); - private static final int FD_OFFSET = DATA_OFFSET; - private static final int OPEN_MAX = IOUtil.fdLimit(); - private static final int NUM_EPOLLEVENTS = Math.min(OPEN_MAX, 8192); - - // Special value to indicate that an update should be ignored - private static final byte KILLED = (byte)-1; - - // Initial size of arrays for fd registration changes - private static final int INITIAL_PENDING_UPDATE_SIZE = 64; - - // maximum size of updatesLow - private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged( - new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024))); - - // The fd of the epoll driver - private final int epfd; - - // The epoll_event array for results from epoll_wait - private final AllocatedNativeObject pollArray; - - // Base address of the epoll_event array - private final long pollArrayAddress; - - // The fd of the interrupt line going out - private final int outgoingInterruptFD; - - // Number of updated pollfd entries - private int updated; - - // object to synchronize fd registration changes - private final Object updateLock = new Object(); - - // number of file descriptors with registration changes pending - private int updateCount; - - // file descriptors with registration changes pending - private int[] updateDescriptors = new int[INITIAL_PENDING_UPDATE_SIZE]; - - // events for file descriptors with registration changes pending, indexed - // by file descriptor and stored as bytes for efficiency reasons. For - // file descriptors higher than MAX_UPDATE_ARRAY_SIZE (unlimited case at - // least) then the update is stored in a map. - private final byte[] eventsLow = new byte[MAX_UPDATE_ARRAY_SIZE]; - private final Map eventsHigh = new HashMap<>(); - - // Used by release and updateRegistrations to track whether a file - // descriptor is registered with epoll. - private final BitSet registered = new BitSet(); - - - EPollArrayWrapper(int fd0, int fd1) throws IOException { - // creates the epoll file descriptor - epfd = epollCreate(); - - // the epoll_event array passed to epoll_wait - int allocationSize = NUM_EPOLLEVENTS * SIZE_EPOLLEVENT; - pollArray = new AllocatedNativeObject(allocationSize, true); - pollArrayAddress = pollArray.address(); - - outgoingInterruptFD = fd1; - epollCtl(epfd, EPOLL_CTL_ADD, fd0, EPOLLIN); - } - - void putEventOps(int i, int event) { - int offset = SIZE_EPOLLEVENT * i + EVENT_OFFSET; - pollArray.putInt(offset, event); - } - - void putDescriptor(int i, int fd) { - int offset = SIZE_EPOLLEVENT * i + FD_OFFSET; - pollArray.putInt(offset, fd); - } - - int getEventOps(int i) { - int offset = SIZE_EPOLLEVENT * i + EVENT_OFFSET; - return pollArray.getInt(offset); - } - - int getDescriptor(int i) { - int offset = SIZE_EPOLLEVENT * i + FD_OFFSET; - return pollArray.getInt(offset); - } - - /** - * Returns {@code true} if updates for the given key (file - * descriptor) are killed. - */ - private boolean isEventsHighKilled(Integer key) { - assert key >= MAX_UPDATE_ARRAY_SIZE; - Byte value = eventsHigh.get(key); - return (value != null && value == KILLED); - } - - /** - * Sets the pending update events for the given file descriptor. This - * method has no effect if the update events is already set to KILLED, - * unless {@code force} is {@code true}. - */ - private void setUpdateEvents(int fd, byte events, boolean force) { - if (fd < MAX_UPDATE_ARRAY_SIZE) { - if ((eventsLow[fd] != KILLED) || force) { - eventsLow[fd] = events; - } - } else { - Integer key = Integer.valueOf(fd); - if (!isEventsHighKilled(key) || force) { - eventsHigh.put(key, Byte.valueOf(events)); - } - } - } - - /** - * Returns the pending update events for the given file descriptor. - */ - private byte getUpdateEvents(int fd) { - if (fd < MAX_UPDATE_ARRAY_SIZE) { - return eventsLow[fd]; - } else { - Byte result = eventsHigh.get(Integer.valueOf(fd)); - // result should never be null - return result.byteValue(); - } - } - - /** - * Update the events for a given file descriptor - */ - void setInterest(int fd, int mask) { - synchronized (updateLock) { - // record the file descriptor and events - int oldCapacity = updateDescriptors.length; - if (updateCount == oldCapacity) { - int newCapacity = oldCapacity + INITIAL_PENDING_UPDATE_SIZE; - int[] newDescriptors = new int[newCapacity]; - System.arraycopy(updateDescriptors, 0, newDescriptors, 0, oldCapacity); - updateDescriptors = newDescriptors; - } - updateDescriptors[updateCount++] = fd; - - // events are stored as bytes for efficiency reasons - byte b = (byte)mask; - assert (b == mask) && (b != KILLED); - setUpdateEvents(fd, b, false); - } - } - - /** - * Add a file descriptor - */ - void add(int fd) { - // force the initial update events to 0 as it may be KILLED by a - // previous registration. - synchronized (updateLock) { - assert !registered.get(fd); - setUpdateEvents(fd, (byte)0, true); - } - } - - /** - * Remove a file descriptor - */ - void remove(int fd) { - synchronized (updateLock) { - // kill pending and future update for this file descriptor - setUpdateEvents(fd, KILLED, false); - - // remove from epoll - if (registered.get(fd)) { - epollCtl(epfd, EPOLL_CTL_DEL, fd, 0); - registered.clear(fd); - } - } - } - - /** - * Close epoll file descriptor and free poll array - */ - void close() throws IOException { - FileDispatcherImpl.closeIntFD(epfd); - pollArray.free(); - } - - int poll(long timeout) throws IOException { - updateRegistrations(); - return epollWait(pollArrayAddress, NUM_EPOLLEVENTS, timeout, epfd); - } - - /** - * Update the pending registrations. - */ - private void updateRegistrations() { - synchronized (updateLock) { - int j = 0; - while (j < updateCount) { - int fd = updateDescriptors[j]; - short events = getUpdateEvents(fd); - boolean isRegistered = registered.get(fd); - int opcode = 0; - - if (events != KILLED) { - if (isRegistered) { - opcode = (events != 0) ? EPOLL_CTL_MOD : EPOLL_CTL_DEL; - } else { - opcode = (events != 0) ? EPOLL_CTL_ADD : 0; - } - if (opcode != 0) { - epollCtl(epfd, opcode, fd, events); - if (opcode == EPOLL_CTL_ADD) { - registered.set(fd); - } else if (opcode == EPOLL_CTL_DEL) { - registered.clear(fd); - } - } - } - j++; - } - updateCount = 0; - } - } - - public void interrupt() { - interrupt(outgoingInterruptFD); - } - - static { - IOUtil.load(); - init(); - } - - private native int epollCreate(); - private native void epollCtl(int epfd, int opcode, int fd, int events); - private native int epollWait(long pollAddress, int numfds, long timeout, - int epfd) throws IOException; - private static native int sizeofEPollEvent(); - private static native int offsetofData(); - private static native void interrupt(int fd); - private static native void init(); -} diff -r eb72d194235c -r 514c68575523 src/java.base/linux/classes/sun/nio/ch/EPollPort.java --- a/src/java.base/linux/classes/sun/nio/ch/EPollPort.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/linux/classes/sun/nio/ch/EPollPort.java Fri Mar 23 18:44:47 2018 +0000 @@ -30,7 +30,13 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicInteger; -import static sun.nio.ch.EPoll.*; + +import static sun.nio.ch.EPoll.EPOLLIN; +import static sun.nio.ch.EPoll.EPOLLONESHOT; +import static sun.nio.ch.EPoll.EPOLL_CTL_ADD; +import static sun.nio.ch.EPoll.EPOLL_CTL_DEL; +import static sun.nio.ch.EPoll.EPOLL_CTL_MOD; + /** * AsynchronousChannelGroup implementation based on the Linux epoll facility. @@ -48,6 +54,9 @@ // epoll file descriptor private final int epfd; + // address of the poll array passed to epoll_wait + private final long address; + // true if epoll closed private boolean closed; @@ -57,9 +66,6 @@ // number of wakeups pending private final AtomicInteger wakeupCount = new AtomicInteger(); - // address of the poll array passed to epoll_wait - private final long address; - // encapsulates an event for a channel static class Event { final PollableChannel channel; @@ -85,23 +91,21 @@ { super(provider, pool); - // open epoll - this.epfd = epollCreate(); + this.epfd = EPoll.create(); + this.address = EPoll.allocatePollArray(MAX_EPOLL_EVENTS); // create socket pair for wakeup mechanism - int[] sv = new int[2]; try { - socketpair(sv); - // register one end with epoll - epollCtl(epfd, EPOLL_CTL_ADD, sv[0], EPOLLIN); - } catch (IOException x) { - close0(epfd); - throw x; + long fds = IOUtil.makePipe(true); + this.sp = new int[]{(int) (fds >>> 32), (int) fds}; + } catch (IOException ioe) { + EPoll.freePollArray(address); + FileDispatcherImpl.closeIntFD(epfd); + throw ioe; } - this.sp = sv; - // allocate the poll array - this.address = allocatePollArray(MAX_EPOLL_EVENTS); + // register one end with epoll + EPoll.ctl(epfd, EPOLL_CTL_ADD, sp[0], EPOLLIN); // create the queue and offer the special event to ensure that the first // threads polls @@ -123,17 +127,17 @@ return; closed = true; } - freePollArray(address); - close0(sp[0]); - close0(sp[1]); - close0(epfd); + try { FileDispatcherImpl.closeIntFD(epfd); } catch (IOException ioe) { } + try { FileDispatcherImpl.closeIntFD(sp[0]); } catch (IOException ioe) { } + try { FileDispatcherImpl.closeIntFD(sp[1]); } catch (IOException ioe) { } + EPoll.freePollArray(address); } private void wakeup() { if (wakeupCount.incrementAndGet() == 1) { // write byte to socketpair to force wakeup try { - interrupt(sp[1]); + IOUtil.write1(sp[1], (byte)0); } catch (IOException x) { throw new AssertionError(x); } @@ -171,9 +175,9 @@ @Override void startPoll(int fd, int events) { // update events (or add to epoll on first usage) - int err = epollCtl(epfd, EPOLL_CTL_MOD, fd, (events | EPOLLONESHOT)); + int err = EPoll.ctl(epfd, EPOLL_CTL_MOD, fd, (events | EPOLLONESHOT)); if (err == ENOENT) - err = epollCtl(epfd, EPOLL_CTL_ADD, fd, (events | EPOLLONESHOT)); + err = EPoll.ctl(epfd, EPOLL_CTL_ADD, fd, (events | EPOLLONESHOT)); if (err != 0) throw new AssertionError(); // should not happen } @@ -191,7 +195,11 @@ private Event poll() throws IOException { try { for (;;) { - int n = epollWait(epfd, address, MAX_EPOLL_EVENTS); + int n; + do { + n = EPoll.wait(epfd, address, MAX_EPOLL_EVENTS, -1); + } while (n == IOStatus.INTERRUPTED); + /* * 'n' events have been read. Here we map them to their * corresponding channel in batch and queue n-1 so that @@ -201,14 +209,14 @@ fdToChannelLock.readLock().lock(); try { while (n-- > 0) { - long eventAddress = getEvent(address, n); - int fd = getDescriptor(eventAddress); + long eventAddress = EPoll.getEvent(address, n); + int fd = EPoll.getDescriptor(eventAddress); // wakeup if (fd == sp[0]) { if (wakeupCount.decrementAndGet() == 0) { // no more wakeups so drain pipe - drain1(sp[0]); + IOUtil.drain(sp[0]); } // queue special event if there are more events @@ -222,7 +230,7 @@ PollableChannel channel = fdToChannel.get(fd); if (channel != null) { - int events = getEvents(eventAddress); + int events = EPoll.getEvents(eventAddress); Event ev = new Event(channel, events); // n-1 events are queued; This thread handles @@ -306,18 +314,4 @@ } } } - - // -- Native methods -- - - private static native void socketpair(int[] sv) throws IOException; - - private static native void interrupt(int fd) throws IOException; - - private static native void drain1(int fd) throws IOException; - - private static native void close0(int fd); - - static { - IOUtil.load(); - } } diff -r eb72d194235c -r 514c68575523 src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java --- a/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java Fri Mar 23 18:44:47 2018 +0000 @@ -26,33 +26,59 @@ package sun.nio.ch; import java.io.IOException; -import java.nio.channels.*; -import java.nio.channels.spi.*; -import java.util.*; +import java.nio.channels.ClosedSelectorException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.spi.SelectorProvider; +import java.util.ArrayDeque; +import java.util.BitSet; +import java.util.Deque; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static sun.nio.ch.EPoll.EPOLLIN; +import static sun.nio.ch.EPoll.EPOLL_CTL_ADD; +import static sun.nio.ch.EPoll.EPOLL_CTL_DEL; +import static sun.nio.ch.EPoll.EPOLL_CTL_MOD; + /** - * An implementation of Selector for Linux 2.6+ kernels that uses - * the epoll event notification facility. + * Linux epoll based Selector implementation */ -class EPollSelectorImpl - extends SelectorImpl -{ - // File descriptors used for interrupt + +class EPollSelectorImpl extends SelectorImpl { + + // maximum number of events to poll in one call to epoll_wait + private static final int NUM_EPOLLEVENTS = Math.min(IOUtil.fdLimit(), 1024); + + // epoll file descriptor + private final int epfd; + + // address of poll array when polling with epoll_wait + private final long pollArrayAddress; + + // file descriptors used for interrupt private final int fd0; private final int fd1; - // The poll object - private final EPollArrayWrapper pollWrapper; + // maps file descriptor to selection key, synchronize on selector + private final Map fdToKey = new HashMap<>(); - // Maps from file descriptors to keys - private final Map fdToKey; + // file descriptors registered with epoll, synchronize on selector + private final BitSet registered = new BitSet(); - // True if this Selector has been closed - private volatile boolean closed; + // pending new registrations/updates, queued by implRegister and putEventOps + private final Object updateLock = new Object(); + private final Deque newKeys = new ArrayDeque<>(); + private final Deque updateKeys = new ArrayDeque<>(); + private final Deque updateOps = new ArrayDeque<>(); - // Lock for interrupt triggering and clearing + // interrupt triggering and clearing private final Object interruptLock = new Object(); - private boolean interruptTriggered = false; + private boolean interruptTriggered; /** * Package private constructor called by factory method in @@ -60,40 +86,57 @@ */ EPollSelectorImpl(SelectorProvider sp) throws IOException { super(sp); - long pipeFds = IOUtil.makePipe(false); - fd0 = (int) (pipeFds >>> 32); - fd1 = (int) pipeFds; + + this.epfd = EPoll.create(); + this.pollArrayAddress = EPoll.allocatePollArray(NUM_EPOLLEVENTS); + try { - pollWrapper = new EPollArrayWrapper(fd0, fd1); - fdToKey = new HashMap<>(); - } catch (Throwable t) { - try { - FileDispatcherImpl.closeIntFD(fd0); - } catch (IOException ioe0) { - t.addSuppressed(ioe0); - } - try { - FileDispatcherImpl.closeIntFD(fd1); - } catch (IOException ioe1) { - t.addSuppressed(ioe1); - } - throw t; + long fds = IOUtil.makePipe(false); + this.fd0 = (int) (fds >>> 32); + this.fd1 = (int) fds; + } catch (IOException ioe) { + EPoll.freePollArray(pollArrayAddress); + FileDispatcherImpl.closeIntFD(epfd); + throw ioe; } + + // register one end of the socket pair for wakeups + EPoll.ctl(epfd, EPOLL_CTL_ADD, fd0, EPOLLIN); } private void ensureOpen() { - if (closed) + if (!isOpen()) throw new ClosedSelectorException(); } @Override protected int doSelect(long timeout) throws IOException { - ensureOpen(); + assert Thread.holdsLock(this); + int numEntries; + processUpdateQueue(); processDeregisterQueue(); try { begin(); - numEntries = pollWrapper.poll(timeout); + + // epoll_wait timeout is int + int to = (int) Math.min(timeout, Integer.MAX_VALUE); + boolean timedPoll = (to > 0); + do { + long startTime = timedPoll ? System.nanoTime() : 0; + numEntries = EPoll.wait(epfd, pollArrayAddress, NUM_EPOLLEVENTS, to); + if (numEntries == IOStatus.INTERRUPTED && timedPoll) { + // timed poll interrupted so need to adjust timeout + long adjust = System.nanoTime() - startTime; + to -= TimeUnit.MILLISECONDS.convert(adjust, TimeUnit.NANOSECONDS); + if (to <= 0) { + // timeout expired so no retry + numEntries = 0; + } + } + } while (numEntries == IOStatus.INTERRUPTED); + assert IOStatus.check(numEntries); + } finally { end(); } @@ -102,20 +145,69 @@ } /** + * Process new registrations and changes to the interest ops. + */ + private void processUpdateQueue() { + assert Thread.holdsLock(this); + + synchronized (updateLock) { + SelectionKeyImpl ski; + + // new registrations + while ((ski = newKeys.pollFirst()) != null) { + if (ski.isValid()) { + SelChImpl ch = ski.channel; + int fd = ch.getFDVal(); + SelectionKeyImpl previous = fdToKey.put(fd, ski); + assert previous == null; + assert registered.get(fd) == false; + } + } + + // changes to interest ops + assert updateKeys.size() == updateOps.size(); + while ((ski = updateKeys.pollFirst()) != null) { + int ops = updateOps.pollFirst(); + int fd = ski.channel.getFDVal(); + if (ski.isValid() && fdToKey.containsKey(fd)) { + if (registered.get(fd)) { + if (ops == 0) { + // remove from epoll + EPoll.ctl(epfd, EPOLL_CTL_DEL, fd, 0); + registered.clear(fd); + } else { + // modify events + EPoll.ctl(epfd, EPOLL_CTL_MOD, fd, ops); + } + } else if (ops != 0) { + // add to epoll + EPoll.ctl(epfd, EPOLL_CTL_ADD, fd, ops); + registered.set(fd); + } + } + } + } + } + + /** * Update the keys whose fd's have been selected by the epoll. * Add the ready keys to the ready queue. */ private int updateSelectedKeys(int numEntries) throws IOException { + assert Thread.holdsLock(this); + assert Thread.holdsLock(nioSelectedKeys()); + boolean interrupted = false; int numKeysUpdated = 0; for (int i=0; i= 0); - SelChImpl ch = ski.channel; - int fd = ch.getFDVal(); - fdToKey.remove(Integer.valueOf(fd)); - pollWrapper.remove(fd); - ski.setIndex(-1); + assert !ski.isValid(); + assert Thread.holdsLock(this); + assert Thread.holdsLock(nioKeys()); + assert Thread.holdsLock(nioSelectedKeys()); + + int fd = ski.channel.getFDVal(); + fdToKey.remove(fd); + if (registered.get(fd)) { + EPoll.ctl(epfd, EPOLL_CTL_DEL, fd, 0); + registered.clear(fd); + } + + selectedKeys.remove(ski); keys.remove(ski); - selectedKeys.remove(ski); + + // remove from channel's key set deregister(ski); + SelectableChannel selch = ski.channel(); if (!selch.isOpen() && !selch.isRegistered()) - ((SelChImpl)selch).kill(); + ((SelChImpl) selch).kill(); } @Override public void putEventOps(SelectionKeyImpl ski, int ops) { ensureOpen(); - SelChImpl ch = ski.channel; - pollWrapper.setInterest(ch.getFDVal(), ops); + synchronized (updateLock) { + updateOps.addLast(ops); // ops first in case adding the key fails + updateKeys.addLast(ski); + } } @Override public Selector wakeup() { synchronized (interruptLock) { if (!interruptTriggered) { - pollWrapper.interrupt(); + try { + IOUtil.write1(fd1, (byte)0); + } catch (IOException ioe) { + throw new InternalError(ioe); + } interruptTriggered = true; } } diff -r eb72d194235c -r 514c68575523 src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java --- a/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, 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 @@ -103,8 +103,8 @@ @Override FileTypeDetector getFileTypeDetector() { String userHome = GetPropertyAction.privilegedGetProperty("user.home"); - Path userMimeTypes = Paths.get(userHome, ".mime.types"); - Path etcMimeTypes = Paths.get("/etc/mime.types"); + Path userMimeTypes = Path.of(userHome, ".mime.types"); + Path etcMimeTypes = Path.of("/etc/mime.types"); return chain(new MimeTypesFileTypeDetector(userMimeTypes), new MimeTypesFileTypeDetector(etcMimeTypes)); diff -r eb72d194235c -r 514c68575523 src/java.base/linux/native/libnio/ch/EPoll.c --- a/src/java.base/linux/native/libnio/ch/EPoll.c Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/linux/native/libnio/ch/EPoll.c Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, 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,53 +23,51 @@ * questions. */ + #include + #include + #include + #include + #include "jni.h" #include "jni_util.h" #include "jvm.h" #include "jlong.h" +#include "nio.h" #include "nio_util.h" #include "sun_nio_ch_EPoll.h" -#include -#include -#include -#include - JNIEXPORT jint JNICALL -Java_sun_nio_ch_EPoll_eventSize(JNIEnv* env, jclass this) +Java_sun_nio_ch_EPoll_eventSize(JNIEnv* env, jclass clazz) { return sizeof(struct epoll_event); } JNIEXPORT jint JNICALL -Java_sun_nio_ch_EPoll_eventsOffset(JNIEnv* env, jclass this) +Java_sun_nio_ch_EPoll_eventsOffset(JNIEnv* env, jclass clazz) { return offsetof(struct epoll_event, events); } JNIEXPORT jint JNICALL -Java_sun_nio_ch_EPoll_dataOffset(JNIEnv* env, jclass this) +Java_sun_nio_ch_EPoll_dataOffset(JNIEnv* env, jclass clazz) { return offsetof(struct epoll_event, data); } JNIEXPORT jint JNICALL -Java_sun_nio_ch_EPoll_epollCreate(JNIEnv *env, jclass c) { - /* - * epoll_create expects a size as a hint to the kernel about how to - * dimension internal structures. We can't predict the size in advance. - */ +Java_sun_nio_ch_EPoll_create(JNIEnv *env, jclass clazz) { + /* size hint not used in modern kernels */ int epfd = epoll_create(256); if (epfd < 0) { - JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed"); + JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed"); } return epfd; } JNIEXPORT jint JNICALL -Java_sun_nio_ch_EPoll_epollCtl(JNIEnv *env, jclass c, jint epfd, - jint opcode, jint fd, jint events) +Java_sun_nio_ch_EPoll_ctl(JNIEnv *env, jclass clazz, jint epfd, + jint opcode, jint fd, jint events) { struct epoll_event event; int res; @@ -77,21 +75,23 @@ event.events = events; event.data.fd = fd; - RESTARTABLE(epoll_ctl(epfd, (int)opcode, (int)fd, &event), res); - + res = epoll_ctl(epfd, (int)opcode, (int)fd, &event); return (res == 0) ? 0 : errno; } JNIEXPORT jint JNICALL -Java_sun_nio_ch_EPoll_epollWait(JNIEnv *env, jclass c, - jint epfd, jlong address, jint numfds) +Java_sun_nio_ch_EPoll_wait(JNIEnv *env, jclass clazz, jint epfd, + jlong address, jint numfds, jint timeout) { struct epoll_event *events = jlong_to_ptr(address); - int res; - - RESTARTABLE(epoll_wait(epfd, events, numfds, -1), res); + int res = epoll_wait(epfd, events, numfds, timeout); if (res < 0) { - JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed"); + if (errno == EINTR) { + return IOS_INTERRUPTED; + } else { + JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed"); + return IOS_THROWN; + } } return res; } diff -r eb72d194235c -r 514c68575523 src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c --- a/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c Fri Mar 23 18:01:52 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -/* - * 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. 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 "jni.h" -#include "jni_util.h" -#include "jvm.h" -#include "jlong.h" - -#include "sun_nio_ch_EPollArrayWrapper.h" - -#include -#include -#include - -#define RESTARTABLE(_cmd, _result) do { \ - do { \ - _result = _cmd; \ - } while((_result == -1) && (errno == EINTR)); \ -} while(0) - - -static int -iepoll(int epfd, struct epoll_event *events, int numfds, jlong timeout) -{ - jlong start, now; - int remaining = timeout; - struct timeval t; - int diff; - - gettimeofday(&t, NULL); - start = t.tv_sec * 1000 + t.tv_usec / 1000; - - for (;;) { - int res = epoll_wait(epfd, events, numfds, remaining); - if (res < 0 && errno == EINTR) { - if (remaining >= 0) { - gettimeofday(&t, NULL); - now = t.tv_sec * 1000 + t.tv_usec / 1000; - diff = now - start; - remaining -= diff; - if (diff < 0 || remaining <= 0) { - return 0; - } - start = now; - } - } else { - return res; - } - } -} - -JNIEXPORT void JNICALL -Java_sun_nio_ch_EPollArrayWrapper_init(JNIEnv *env, jclass this) -{ -} - -JNIEXPORT jint JNICALL -Java_sun_nio_ch_EPollArrayWrapper_epollCreate(JNIEnv *env, jobject this) -{ - /* - * epoll_create expects a size as a hint to the kernel about how to - * dimension internal structures. We can't predict the size in advance. - */ - int epfd = epoll_create(256); - if (epfd < 0) { - JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed"); - } - return epfd; -} - -JNIEXPORT jint JNICALL -Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent(JNIEnv* env, jclass this) -{ - return sizeof(struct epoll_event); -} - -JNIEXPORT jint JNICALL -Java_sun_nio_ch_EPollArrayWrapper_offsetofData(JNIEnv* env, jclass this) -{ - return offsetof(struct epoll_event, data); -} - -JNIEXPORT void JNICALL -Java_sun_nio_ch_EPollArrayWrapper_epollCtl(JNIEnv *env, jobject this, jint epfd, - jint opcode, jint fd, jint events) -{ - struct epoll_event event; - int res; - - event.events = events; - event.data.fd = fd; - - RESTARTABLE(epoll_ctl(epfd, (int)opcode, (int)fd, &event), res); - - /* - * A channel may be registered with several Selectors. When each Selector - * is polled a EPOLL_CTL_DEL op will be inserted into its pending update - * list to remove the file descriptor from epoll. The "last" Selector will - * close the file descriptor which automatically unregisters it from each - * epoll descriptor. To avoid costly synchronization between Selectors we - * allow pending updates to be processed, ignoring errors. The errors are - * harmless as the last update for the file descriptor is guaranteed to - * be EPOLL_CTL_DEL. - */ - if (res < 0 && errno != EBADF && errno != ENOENT && errno != EPERM) { - JNU_ThrowIOExceptionWithLastError(env, "epoll_ctl failed"); - } -} - -JNIEXPORT jint JNICALL -Java_sun_nio_ch_EPollArrayWrapper_epollWait(JNIEnv *env, jobject this, - jlong address, jint numfds, - jlong timeout, jint epfd) -{ - struct epoll_event *events = jlong_to_ptr(address); - int res; - - if (timeout <= 0) { /* Indefinite or no wait */ - RESTARTABLE(epoll_wait(epfd, events, numfds, timeout), res); - } else { /* Bounded wait; bounded restarts */ - res = iepoll(epfd, events, numfds, timeout); - } - - if (res < 0) { - JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed"); - } - return res; -} - -JNIEXPORT void JNICALL -Java_sun_nio_ch_EPollArrayWrapper_interrupt(JNIEnv *env, jobject this, jint fd) -{ - int fakebuf[1]; - fakebuf[0] = 1; - if (write(fd, fakebuf, 1) < 0) { - JNU_ThrowIOExceptionWithLastError(env,"write to interrupt fd failed"); - } -} diff -r eb72d194235c -r 514c68575523 src/java.base/linux/native/libnio/ch/EPollPort.c --- a/src/java.base/linux/native/libnio/ch/EPollPort.c Fri Mar 23 18:01:52 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 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 "jni.h" -#include "jni_util.h" -#include "jvm.h" -#include "jlong.h" -#include "nio_util.h" - -#include "sun_nio_ch_EPollPort.h" - -#include -#include -#include - -JNIEXPORT void JNICALL -Java_sun_nio_ch_EPollPort_socketpair(JNIEnv* env, jclass clazz, jintArray sv) { - int sp[2]; - if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) == -1) { - JNU_ThrowIOExceptionWithLastError(env, "socketpair failed"); - } else { - jint res[2]; - res[0] = (jint)sp[0]; - res[1] = (jint)sp[1]; - (*env)->SetIntArrayRegion(env, sv, 0, 2, &res[0]); - } -} - -JNIEXPORT void JNICALL -Java_sun_nio_ch_EPollPort_interrupt(JNIEnv *env, jclass c, jint fd) { - int res; - int buf[1]; - buf[0] = 1; - RESTARTABLE(write(fd, buf, 1), res); - if (res < 0) { - JNU_ThrowIOExceptionWithLastError(env, "write failed"); - } -} - -JNIEXPORT void JNICALL -Java_sun_nio_ch_EPollPort_drain1(JNIEnv *env, jclass cl, jint fd) { - int res; - char buf[1]; - RESTARTABLE(read(fd, buf, 1), res); - if (res < 0) { - JNU_ThrowIOExceptionWithLastError(env, "drain1 failed"); - } -} - -JNIEXPORT void JNICALL -Java_sun_nio_ch_EPollPort_close0(JNIEnv *env, jclass c, jint fd) { - int res; - RESTARTABLE(close(fd), res); -} diff -r eb72d194235c -r 514c68575523 src/java.base/macosx/classes/sun/nio/ch/KQueue.java --- a/src/java.base/macosx/classes/sun/nio/ch/KQueue.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/macosx/classes/sun/nio/ch/KQueue.java Fri Mar 23 18:44:47 2018 +0000 @@ -84,17 +84,17 @@ } /** - * Returns the file descriptor from a kevent (assuming to be in ident field) + * Returns the file descriptor from a kevent (assuming it is in the ident field) */ static int getDescriptor(long address) { return unsafe.getInt(address + OFFSET_IDENT); } - static int getFilter(long address) { + static short getFilter(long address) { return unsafe.getShort(address + OFFSET_FILTER); } - static int getFlags(long address) { + static short getFlags(long address) { return unsafe.getShort(address + OFFSET_FLAGS); } @@ -108,11 +108,11 @@ private static native int flagsOffset(); - static native int kqueue() throws IOException; + static native int create() throws IOException; - static native int keventRegister(int kqpfd, int fd, int filter, int flags); + static native int register(int kqfd, int fd, int filter, int flags); - static native int keventPoll(int kqpfd, long pollAddress, int nevents) + static native int poll(int kqfd, long pollAddress, int nevents, long timeout) throws IOException; static { diff -r eb72d194235c -r 514c68575523 src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java --- a/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Fri Mar 23 18:01:52 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2011, 2018, 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. - */ - -/* - * KQueueArrayWrapper.java - * Implementation of Selector using FreeBSD / Mac OS X kqueues - * Derived from Sun's DevPollArrayWrapper - */ - -package sun.nio.ch; - -import java.io.IOException; -import java.util.Iterator; -import java.util.LinkedList; -import sun.security.action.GetPropertyAction; - -/* - * struct kevent { // 32-bit 64-bit - * uintptr_t ident; // 4 8 - * short filter; // 2 2 - * u_short flags; // 2 2 - * u_int fflags; // 4 4 - * intptr_t data; // 4 8 - * void *udata; // 4 8 - * } // Total: 20 32 - * - * The implementation works in 32-bit and 64-bit world. We do this by calling a - * native function that actually sets the sizes and offsets of the fields based - * on which mode we're in. - */ - -class KQueueArrayWrapper { - // kevent filters - static short EVFILT_READ; - static short EVFILT_WRITE; - - // kevent struct - // These fields are now set by initStructSizes in the static initializer. - static short SIZEOF_KEVENT; - static short FD_OFFSET; - static short FILTER_OFFSET; - - // kevent array size - static final int NUM_KEVENTS = 128; - - // Are we in a 64-bit VM? - static boolean is64bit; - - // The kevent array (used for outcoming events only) - private final AllocatedNativeObject keventArray; - private final long keventArrayAddress; - - // The kqueue fd - private final int kq; - - // The fd of the interrupt line going out - private final int outgoingInterruptFD; - - - static { - IOUtil.load(); - initStructSizes(); - String datamodel = - GetPropertyAction.privilegedGetProperty("sun.arch.data.model"); - is64bit = "64".equals(datamodel); - } - - KQueueArrayWrapper(int fd0, int fd1) throws IOException { - int allocationSize = SIZEOF_KEVENT * NUM_KEVENTS; - keventArray = new AllocatedNativeObject(allocationSize, true); - keventArrayAddress = keventArray.address(); - kq = init(); - register0(kq, fd0, 1, 0); - outgoingInterruptFD = fd1; - } - - // Used to update file description registrations - private static class Update { - SelChImpl channel; - int events; - Update(SelChImpl channel, int events) { - this.channel = channel; - this.events = events; - } - } - - private LinkedList updateList = new LinkedList(); - - int getReventOps(int index) { - int result = 0; - int offset = SIZEOF_KEVENT*index + FILTER_OFFSET; - short filter = keventArray.getShort(offset); - - // This is all that's necessary based on inspection of usage: - // SinkChannelImpl, SourceChannelImpl, DatagramChannelImpl, - // ServerSocketChannelImpl, SocketChannelImpl - if (filter == EVFILT_READ) { - result |= Net.POLLIN; - } else if (filter == EVFILT_WRITE) { - result |= Net.POLLOUT; - } - - return result; - } - - int getDescriptor(int index) { - int offset = SIZEOF_KEVENT*index + FD_OFFSET; - /* The ident field is 8 bytes in 64-bit world, however the API wants us - * to return an int. Hence read the 8 bytes but return as an int. - */ - if (is64bit) { - long fd = keventArray.getLong(offset); - assert fd <= Integer.MAX_VALUE; - return (int) fd; - } else { - return keventArray.getInt(offset); - } - } - - void setInterest(SelChImpl channel, int events) { - synchronized (updateList) { - // update existing registration - updateList.add(new Update(channel, events)); - } - } - - void release(SelChImpl channel) { - synchronized (updateList) { - // flush any pending updates - for (Iterator it = updateList.iterator(); it.hasNext();) { - if (it.next().channel == channel) { - it.remove(); - } - } - - // remove - register0(kq, channel.getFDVal(), 0, 0); - } - } - - void updateRegistrations() { - synchronized (updateList) { - Update u; - while ((u = updateList.poll()) != null) { - SelChImpl ch = u.channel; - if (!ch.isOpen()) - continue; - - register0(kq, ch.getFDVal(), u.events & Net.POLLIN, u.events & Net.POLLOUT); - } - } - } - - void close() throws IOException { - FileDispatcherImpl.closeIntFD(kq); - keventArray.free(); - } - - int poll(long timeout) { - updateRegistrations(); - return kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout); - } - - void interrupt() { - interrupt(outgoingInterruptFD); - } - - private native int init(); - private static native void initStructSizes(); - - private native void register0(int kq, int fd, int read, int write); - private native int kevent0(int kq, long keventAddress, int keventCount, - long timeout); - private static native void interrupt(int fd); -} diff -r eb72d194235c -r 514c68575523 src/java.base/macosx/classes/sun/nio/ch/KQueuePort.java --- a/src/java.base/macosx/classes/sun/nio/ch/KQueuePort.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/macosx/classes/sun/nio/ch/KQueuePort.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, 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 @@ -30,7 +30,11 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicInteger; -import static sun.nio.ch.KQueue.*; + +import static sun.nio.ch.KQueue.EVFILT_READ; +import static sun.nio.ch.KQueue.EVFILT_WRITE; +import static sun.nio.ch.KQueue.EV_ADD; +import static sun.nio.ch.KQueue.EV_ONESHOT; /** * AsynchronousChannelGroup implementation based on the BSD kqueue facility. @@ -45,6 +49,9 @@ // kqueue file descriptor private final int kqfd; + // address of the poll array passed to kqueue_wait + private final long address; + // true if kqueue closed private boolean closed; @@ -54,9 +61,6 @@ // number of wakeups pending private final AtomicInteger wakeupCount = new AtomicInteger(); - // address of the poll array passed to kqueue_wait - private final long address; - // encapsulates an event for a channel static class Event { final PollableChannel channel; @@ -82,28 +86,25 @@ { super(provider, pool); - // open kqueue - this.kqfd = kqueue(); + this.kqfd = KQueue.create(); + this.address = KQueue.allocatePollArray(MAX_KEVENTS_TO_POLL); // create socket pair for wakeup mechanism - int[] sv = new int[2]; try { - socketpair(sv); + long fds = IOUtil.makePipe(true); + this.sp = new int[]{(int) (fds >>> 32), (int) fds}; + } catch (IOException ioe) { + KQueue.freePollArray(address); + FileDispatcherImpl.closeIntFD(kqfd); + throw ioe; + } - // register one end with kqueue - keventRegister(kqfd, sv[0], EVFILT_READ, EV_ADD); - } catch (IOException x) { - close0(kqfd); - throw x; - } - this.sp = sv; - - // allocate the poll array - this.address = allocatePollArray(MAX_KEVENTS_TO_POLL); + // register one end with kqueue + KQueue.register(kqfd, sp[0], EVFILT_READ, EV_ADD); // create the queue and offer the special event to ensure that the first // threads polls - this.queue = new ArrayBlockingQueue(MAX_KEVENTS_TO_POLL); + this.queue = new ArrayBlockingQueue<>(MAX_KEVENTS_TO_POLL); this.queue.offer(NEED_TO_POLL); } @@ -121,17 +122,18 @@ return; closed = true; } - freePollArray(address); - close0(sp[0]); - close0(sp[1]); - close0(kqfd); + + try { FileDispatcherImpl.closeIntFD(kqfd); } catch (IOException ioe) { } + try { FileDispatcherImpl.closeIntFD(sp[0]); } catch (IOException ioe) { } + try { FileDispatcherImpl.closeIntFD(sp[1]); } catch (IOException ioe) { } + KQueue.freePollArray(address); } private void wakeup() { if (wakeupCount.incrementAndGet() == 1) { // write byte to socketpair to force wakeup try { - interrupt(sp[1]); + IOUtil.write1(sp[1], (byte)0); } catch (IOException x) { throw new AssertionError(x); } @@ -173,9 +175,9 @@ int err = 0; int flags = (EV_ADD|EV_ONESHOT); if ((events & Net.POLLIN) > 0) - err = keventRegister(kqfd, fd, EVFILT_READ, flags); + err = KQueue.register(kqfd, fd, EVFILT_READ, flags); if (err == 0 && (events & Net.POLLOUT) > 0) - err = keventRegister(kqfd, fd, EVFILT_WRITE, flags); + err = KQueue.register(kqfd, fd, EVFILT_WRITE, flags); if (err != 0) throw new InternalError("kevent failed: " + err); // should not happen } @@ -193,7 +195,11 @@ private Event poll() throws IOException { try { for (;;) { - int n = keventPoll(kqfd, address, MAX_KEVENTS_TO_POLL); + int n; + do { + n = KQueue.poll(kqfd, address, MAX_KEVENTS_TO_POLL, -1L); + } while (n == IOStatus.INTERRUPTED); + /* * 'n' events have been read. Here we map them to their * corresponding channel in batch and queue n-1 so that @@ -203,14 +209,14 @@ fdToChannelLock.readLock().lock(); try { while (n-- > 0) { - long keventAddress = getEvent(address, n); - int fd = getDescriptor(keventAddress); + long keventAddress = KQueue.getEvent(address, n); + int fd = KQueue.getDescriptor(keventAddress); // wakeup if (fd == sp[0]) { if (wakeupCount.decrementAndGet() == 0) { // no more wakeups so drain pipe - drain1(sp[0]); + IOUtil.drain(sp[0]); } // queue special event if there are more events @@ -224,7 +230,7 @@ PollableChannel channel = fdToChannel.get(fd); if (channel != null) { - int filter = getFilter(keventAddress); + int filter = KQueue.getFilter(keventAddress); int events = 0; if (filter == EVFILT_READ) events = Net.POLLIN; @@ -314,18 +320,4 @@ } } } - - // -- Native methods -- - - private static native void socketpair(int[] sv) throws IOException; - - private static native void interrupt(int fd) throws IOException; - - private static native void drain1(int fd) throws IOException; - - private static native void close0(int fd); - - static { - IOUtil.load(); - } } diff -r eb72d194235c -r 514c68575523 src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java --- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Fri Mar 23 18:44:47 2018 +0000 @@ -23,11 +23,6 @@ * questions. */ -/* - * KQueueSelectorImpl.java - * Implementation of Selector using FreeBSD / Mac OS X kqueues - */ - package sun.nio.ch; import java.io.IOException; @@ -36,85 +31,111 @@ import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.spi.SelectorProvider; +import java.util.ArrayDeque; +import java.util.BitSet; +import java.util.Deque; import java.util.HashMap; import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.TimeUnit; -class KQueueSelectorImpl - extends SelectorImpl -{ - // File descriptors used for interrupt +import static sun.nio.ch.KQueue.EVFILT_READ; +import static sun.nio.ch.KQueue.EVFILT_WRITE; +import static sun.nio.ch.KQueue.EV_ADD; +import static sun.nio.ch.KQueue.EV_DELETE; + +/** + * KQueue based Selector implementation for macOS + */ + +class KQueueSelectorImpl extends SelectorImpl { + + // maximum number of events to poll in one call to kqueue + private static final int MAX_KEVENTS = 256; + + // kqueue file descriptor + private final int kqfd; + + // address of poll array (event list) when polling for pending events + private final long pollArrayAddress; + + // file descriptors used for interrupt private final int fd0; private final int fd1; - // The kqueue manipulator - private final KQueueArrayWrapper kqueueWrapper; + // maps file descriptor to selection key, synchronize on selector + private final Map fdToKey = new HashMap<>(); + + // file descriptors registered with kqueue, synchronize on selector + private final BitSet registeredReadFilter = new BitSet(); + private final BitSet registeredWriteFilter = new BitSet(); - // Map from a file descriptor to an entry containing the selection key - private final HashMap fdMap; + // pending new registrations/updates, queued by implRegister and putEventOps + private final Object updateLock = new Object(); + private final Deque newKeys = new ArrayDeque<>(); + private final Deque updateKeys = new ArrayDeque<>(); + private final Deque updateOps = new ArrayDeque<>(); - // True if this Selector has been closed - private boolean closed; - - // Lock for interrupt triggering and clearing + // interrupt triggering and clearing private final Object interruptLock = new Object(); private boolean interruptTriggered; // used by updateSelectedKeys to handle cases where the same file // descriptor is polled by more than one filter - private long updateCount; + private int pollCount; - // Used to map file descriptors to a selection key and "update count" - // (see updateSelectedKeys for usage). - private static class MapEntry { - SelectionKeyImpl ski; - long updateCount; - MapEntry(SelectionKeyImpl ski) { - this.ski = ski; - } - } - - /** - * Package private constructor called by factory method in - * the abstract superclass Selector. - */ KQueueSelectorImpl(SelectorProvider sp) throws IOException { super(sp); - long fds = IOUtil.makePipe(false); - fd0 = (int)(fds >>> 32); - fd1 = (int)fds; + + this.kqfd = KQueue.create(); + this.pollArrayAddress = KQueue.allocatePollArray(MAX_KEVENTS); + try { - kqueueWrapper = new KQueueArrayWrapper(fd0, fd1); - fdMap = new HashMap<>(); - } catch (Throwable t) { - try { - FileDispatcherImpl.closeIntFD(fd0); - } catch (IOException ioe0) { - t.addSuppressed(ioe0); - } - try { - FileDispatcherImpl.closeIntFD(fd1); - } catch (IOException ioe1) { - t.addSuppressed(ioe1); - } - throw t; + long fds = IOUtil.makePipe(false); + this.fd0 = (int) (fds >>> 32); + this.fd1 = (int) fds; + } catch (IOException ioe) { + KQueue.freePollArray(pollArrayAddress); + FileDispatcherImpl.closeIntFD(kqfd); + throw ioe; } + + // register one end of the socket pair for wakeups + KQueue.register(kqfd, fd0, EVFILT_READ, EV_ADD); } private void ensureOpen() { - if (closed) + if (!isOpen()) throw new ClosedSelectorException(); } @Override - protected int doSelect(long timeout) - throws IOException - { - ensureOpen(); + protected int doSelect(long timeout) throws IOException { + assert Thread.holdsLock(this); + int numEntries; + processUpdateQueue(); processDeregisterQueue(); try { begin(); - numEntries = kqueueWrapper.poll(timeout); + + long to = Math.min(timeout, Integer.MAX_VALUE); // max kqueue timeout + boolean timedPoll = (to > 0); + do { + long startTime = timedPoll ? System.nanoTime() : 0; + numEntries = KQueue.poll(kqfd, pollArrayAddress, MAX_KEVENTS, to); + if (numEntries == IOStatus.INTERRUPTED && timedPoll) { + // timed poll interrupted so need to adjust timeout + long adjust = System.nanoTime() - startTime; + to -= TimeUnit.MILLISECONDS.convert(adjust, TimeUnit.NANOSECONDS); + if (to <= 0) { + // timeout expired so no retry + numEntries = 0; + } + } + } while (numEntries == IOStatus.INTERRUPTED); + assert IOStatus.check(numEntries); + } finally { end(); } @@ -123,39 +144,100 @@ } /** + * Process new registrations and changes to the interest ops. + */ + private void processUpdateQueue() { + assert Thread.holdsLock(this); + + synchronized (updateLock) { + SelectionKeyImpl ski; + + // new registrations + while ((ski = newKeys.pollFirst()) != null) { + if (ski.isValid()) { + SelChImpl ch = ski.channel; + int fd = ch.getFDVal(); + SelectionKeyImpl previous = fdToKey.put(fd, ski); + assert previous == null; + assert registeredReadFilter.get(fd) == false; + assert registeredWriteFilter.get(fd) == false; + } + } + + // changes to interest ops + assert updateKeys.size() == updateOps.size(); + while ((ski = updateKeys.pollFirst()) != null) { + int ops = updateOps.pollFirst(); + int fd = ski.channel.getFDVal(); + if (ski.isValid() && fdToKey.containsKey(fd)) { + // add or delete interest in read events + if (registeredReadFilter.get(fd)) { + if ((ops & Net.POLLIN) == 0) { + KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE); + registeredReadFilter.clear(fd); + } + } else if ((ops & Net.POLLIN) != 0) { + KQueue.register(kqfd, fd, EVFILT_READ, EV_ADD); + registeredReadFilter.set(fd); + } + + // add or delete interest in write events + if (registeredWriteFilter.get(fd)) { + if ((ops & Net.POLLOUT) == 0) { + KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE); + registeredWriteFilter.clear(fd); + } + } else if ((ops & Net.POLLOUT) != 0) { + KQueue.register(kqfd, fd, EVFILT_WRITE, EV_ADD); + registeredWriteFilter.set(fd); + } + } + } + } + } + + /** * Update the keys whose fd's have been selected by kqueue. * Add the ready keys to the selected key set. * If the interrupt fd has been selected, drain it and clear the interrupt. */ - private int updateSelectedKeys(int numEntries) - throws IOException - { + private int updateSelectedKeys(int numEntries) throws IOException { + assert Thread.holdsLock(this); + assert Thread.holdsLock(nioSelectedKeys()); + int numKeysUpdated = 0; boolean interrupted = false; // A file descriptor may be registered with kqueue with more than one - // filter and so there may be more than one event for a fd. The update - // count in the MapEntry tracks when the fd was last updated and this - // ensures that the ready ops are updated rather than replaced by a - // second or subsequent event. - updateCount++; + // filter and so there may be more than one event for a fd. The poll + // count is incremented here and compared against the SelectionKey's + // "lastPolled" field. This ensures that the ready ops is updated rather + // than replaced when a file descriptor is polled by both the read and + // write filter. + pollCount++; for (int i = 0; i < numEntries; i++) { - int nextFD = kqueueWrapper.getDescriptor(i); - if (nextFD == fd0) { + long kevent = KQueue.getEvent(pollArrayAddress, i); + int fd = KQueue.getDescriptor(kevent); + if (fd == fd0) { interrupted = true; } else { - MapEntry me = fdMap.get(Integer.valueOf(nextFD)); - if (me != null) { - int rOps = kqueueWrapper.getReventOps(i); - SelectionKeyImpl ski = me.ski; + SelectionKeyImpl ski = fdToKey.get(fd); + if (ski != null) { + int rOps = 0; + short filter = KQueue.getFilter(kevent); + if (filter == EVFILT_READ) { + rOps |= Net.POLLIN; + } else if (filter == EVFILT_WRITE) { + rOps |= Net.POLLOUT; + } + if (selectedKeys.contains(ski)) { - // first time this file descriptor has been encountered on this - // update? - if (me.updateCount != updateCount) { + // file descriptor may be polled more than once per poll + if (ski.lastPolled != pollCount) { if (ski.channel.translateAndSetReadyOps(rOps, ski)) { numKeysUpdated++; - me.updateCount = updateCount; + ski.lastPolled = pollCount; } } else { // ready ops have already been set on this update @@ -166,7 +248,7 @@ if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) { selectedKeys.add(ski); numKeysUpdated++; - me.updateCount = updateCount; + ski.lastPolled = pollCount; } } } @@ -181,63 +263,90 @@ @Override protected void implClose() throws IOException { - if (!closed) { - closed = true; + assert !isOpen(); + assert Thread.holdsLock(this); + assert Thread.holdsLock(nioKeys()); - // prevent further wakeup - synchronized (interruptLock) { - interruptTriggered = true; - } + // prevent further wakeup + synchronized (interruptLock) { + interruptTriggered = true; + } + + FileDispatcherImpl.closeIntFD(kqfd); + KQueue.freePollArray(pollArrayAddress); - kqueueWrapper.close(); - FileDispatcherImpl.closeIntFD(fd0); - FileDispatcherImpl.closeIntFD(fd1); + FileDispatcherImpl.closeIntFD(fd0); + FileDispatcherImpl.closeIntFD(fd1); - // Deregister channels - Iterator i = keys.iterator(); - while (i.hasNext()) { - SelectionKeyImpl ski = (SelectionKeyImpl)i.next(); - deregister(ski); - SelectableChannel selch = ski.channel(); - if (!selch.isOpen() && !selch.isRegistered()) - ((SelChImpl)selch).kill(); - i.remove(); - } + // Deregister channels + Iterator i = keys.iterator(); + while (i.hasNext()) { + SelectionKeyImpl ski = (SelectionKeyImpl)i.next(); + deregister(ski); + SelectableChannel selch = ski.channel(); + if (!selch.isOpen() && !selch.isRegistered()) + ((SelChImpl)selch).kill(); + i.remove(); } } @Override protected void implRegister(SelectionKeyImpl ski) { + assert Thread.holdsLock(nioKeys()); ensureOpen(); - int fd = IOUtil.fdVal(ski.channel.getFD()); - fdMap.put(Integer.valueOf(fd), new MapEntry(ski)); + synchronized (updateLock) { + newKeys.addLast(ski); + } keys.add(ski); } @Override protected void implDereg(SelectionKeyImpl ski) throws IOException { + assert !ski.isValid(); + assert Thread.holdsLock(this); + assert Thread.holdsLock(nioKeys()); + assert Thread.holdsLock(nioSelectedKeys()); + int fd = ski.channel.getFDVal(); - fdMap.remove(Integer.valueOf(fd)); - kqueueWrapper.release(ski.channel); + fdToKey.remove(fd); + if (registeredReadFilter.get(fd)) { + KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE); + registeredReadFilter.clear(fd); + } + if (registeredWriteFilter.get(fd)) { + KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE); + registeredWriteFilter.clear(fd); + } + + selectedKeys.remove(ski); keys.remove(ski); - selectedKeys.remove(ski); + + // remove from channel's key set deregister(ski); + SelectableChannel selch = ski.channel(); if (!selch.isOpen() && !selch.isRegistered()) - ((SelChImpl)selch).kill(); + ((SelChImpl) selch).kill(); } @Override public void putEventOps(SelectionKeyImpl ski, int ops) { ensureOpen(); - kqueueWrapper.setInterest(ski.channel, ops); + synchronized (updateLock) { + updateOps.addLast(ops); // ops first in case adding the key fails + updateKeys.addLast(ski); + } } @Override public Selector wakeup() { synchronized (interruptLock) { if (!interruptTriggered) { - kqueueWrapper.interrupt(); + try { + IOUtil.write1(fd1, (byte)0); + } catch (IOException ioe) { + throw new InternalError(ioe); + } interruptTriggered = true; } } diff -r eb72d194235c -r 514c68575523 src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java --- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java Fri Mar 23 18:44:47 2018 +0000 @@ -23,17 +23,10 @@ * questions. */ -/* - * KQueueSelectorProvider.java - * Implementation of Selector using FreeBSD / Mac OS X kqueues - * Derived from Sun's DevPollSelectorProvider - */ - package sun.nio.ch; import java.io.IOException; -import java.nio.channels.*; -import java.nio.channels.spi.*; +import java.nio.channels.spi.AbstractSelector; public class KQueueSelectorProvider extends SelectorProviderImpl diff -r eb72d194235c -r 514c68575523 src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java --- a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, 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 @@ -26,7 +26,6 @@ package sun.nio.fs; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.spi.FileTypeDetector; import sun.security.action.GetPropertyAction; @@ -46,7 +45,7 @@ @Override FileTypeDetector getFileTypeDetector() { - Path userMimeTypes = Paths.get(GetPropertyAction + Path userMimeTypes = Path.of(GetPropertyAction .privilegedGetProperty("user.home"), ".mime.types"); return chain(new MimeTypesFileTypeDetector(userMimeTypes), diff -r eb72d194235c -r 514c68575523 src/java.base/macosx/native/libnio/ch/KQueue.c --- a/src/java.base/macosx/native/libnio/ch/KQueue.c Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/macosx/native/libnio/ch/KQueue.c Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, 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,76 +23,91 @@ * questions. */ -#include "jni.h" -#include "jni_util.h" -#include "jvm.h" -#include "jlong.h" -#include "nio_util.h" - -#include "sun_nio_ch_KQueue.h" - #include #include #include #include +#include "jni.h" +#include "jni_util.h" +#include "jlong.h" +#include "nio.h" +#include "nio_util.h" + +#include "sun_nio_ch_KQueue.h" + JNIEXPORT jint JNICALL -Java_sun_nio_ch_KQueue_keventSize(JNIEnv* env, jclass this) +Java_sun_nio_ch_KQueue_keventSize(JNIEnv* env, jclass clazz) { return sizeof(struct kevent); } JNIEXPORT jint JNICALL -Java_sun_nio_ch_KQueue_identOffset(JNIEnv* env, jclass this) +Java_sun_nio_ch_KQueue_identOffset(JNIEnv* env, jclass clazz) { return offsetof(struct kevent, ident); } JNIEXPORT jint JNICALL -Java_sun_nio_ch_KQueue_filterOffset(JNIEnv* env, jclass this) +Java_sun_nio_ch_KQueue_filterOffset(JNIEnv* env, jclass clazz) { return offsetof(struct kevent, filter); } JNIEXPORT jint JNICALL -Java_sun_nio_ch_KQueue_flagsOffset(JNIEnv* env, jclass this) +Java_sun_nio_ch_KQueue_flagsOffset(JNIEnv* env, jclass clazz) { return offsetof(struct kevent, flags); } JNIEXPORT jint JNICALL -Java_sun_nio_ch_KQueue_kqueue(JNIEnv *env, jclass c) { +Java_sun_nio_ch_KQueue_create(JNIEnv *env, jclass clazz) { int kqfd = kqueue(); if (kqfd < 0) { JNU_ThrowIOExceptionWithLastError(env, "kqueue failed"); + return IOS_THROWN; } return kqfd; } JNIEXPORT jint JNICALL -Java_sun_nio_ch_KQueue_keventRegister(JNIEnv *env, jclass c, jint kqfd, - jint fd, jint filter, jint flags) +Java_sun_nio_ch_KQueue_register(JNIEnv *env, jclass clazz, jint kqfd, + jint fd, jint filter, jint flags) { struct kevent changes[1]; - struct timespec timeout = {0, 0}; int res; EV_SET(&changes[0], fd, filter, flags, 0, 0, 0); - RESTARTABLE(kevent(kqfd, &changes[0], 1, NULL, 0, &timeout), res); + RESTARTABLE(kevent(kqfd, &changes[0], 1, NULL, 0, NULL), res); return (res == -1) ? errno : 0; } JNIEXPORT jint JNICALL -Java_sun_nio_ch_KQueue_keventPoll(JNIEnv *env, jclass c, - jint kqfd, jlong address, jint nevents) +Java_sun_nio_ch_KQueue_poll(JNIEnv *env, jclass clazz, jint kqfd, jlong address, + jint nevents, jlong timeout) { struct kevent *events = jlong_to_ptr(address); int res; + struct timespec ts; + struct timespec *tsp; - RESTARTABLE(kevent(kqfd, NULL, 0, events, nevents, NULL), res); + if (timeout >= 0) { + ts.tv_sec = timeout / 1000; + ts.tv_nsec = (timeout % 1000) * 1000000; + tsp = &ts; + } else { + tsp = NULL; + } + + res = kevent(kqfd, NULL, 0, events, nevents, tsp); if (res < 0) { - JNU_ThrowIOExceptionWithLastError(env, "kqueue failed"); + if (errno == EINTR) { + return IOS_INTERRUPTED; + } else { + JNU_ThrowIOExceptionWithLastError(env, "kqueue failed"); + return IOS_THROWN; + } } return res; } diff -r eb72d194235c -r 514c68575523 src/java.base/macosx/native/libnio/ch/KQueueArrayWrapper.c --- a/src/java.base/macosx/native/libnio/ch/KQueueArrayWrapper.c Fri Mar 23 18:01:52 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2011, 2018, 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. - */ - -/* - * KQueueArrayWrapper.c - * Implementation of Selector using FreeBSD / Mac OS X kqueues - * Derived from Sun's DevPollArrayWrapper - */ - - -#include "jni.h" -#include "jni_util.h" -#include "jvm.h" -#include "jlong.h" -#include "nio_util.h" - -#include -#include -#include - -JNIEXPORT void JNICALL -Java_sun_nio_ch_KQueueArrayWrapper_initStructSizes(JNIEnv *env, jclass clazz) -{ -#define CHECK_EXCEPTION() { \ - if ((*env)->ExceptionCheck(env)) { \ - goto exceptionOccurred; \ - } \ -} - -#define CHECK_ERROR_AND_EXCEPTION(_field) { \ - if (_field == NULL) { \ - goto badField; \ - } \ - CHECK_EXCEPTION(); \ -} - - - jfieldID field; - - field = (*env)->GetStaticFieldID(env, clazz, "EVFILT_READ", "S"); - CHECK_ERROR_AND_EXCEPTION(field); - (*env)->SetStaticShortField(env, clazz, field, EVFILT_READ); - CHECK_EXCEPTION(); - - field = (*env)->GetStaticFieldID(env, clazz, "EVFILT_WRITE", "S"); - CHECK_ERROR_AND_EXCEPTION(field); - (*env)->SetStaticShortField(env, clazz, field, EVFILT_WRITE); - CHECK_EXCEPTION(); - - field = (*env)->GetStaticFieldID(env, clazz, "SIZEOF_KEVENT", "S"); - CHECK_ERROR_AND_EXCEPTION(field); - (*env)->SetStaticShortField(env, clazz, field, (short) sizeof(struct kevent)); - CHECK_EXCEPTION(); - - field = (*env)->GetStaticFieldID(env, clazz, "FD_OFFSET", "S"); - CHECK_ERROR_AND_EXCEPTION(field); - (*env)->SetStaticShortField(env, clazz, field, (short) offsetof(struct kevent, ident)); - CHECK_EXCEPTION(); - - field = (*env)->GetStaticFieldID(env, clazz, "FILTER_OFFSET", "S"); - CHECK_ERROR_AND_EXCEPTION(field); - (*env)->SetStaticShortField(env, clazz, field, (short) offsetof(struct kevent, filter)); - CHECK_EXCEPTION(); - return; - -badField: - return; - -exceptionOccurred: - return; - -#undef CHECK_EXCEPTION -#undef CHECK_ERROR_AND_EXCEPTION -} - -JNIEXPORT jint JNICALL -Java_sun_nio_ch_KQueueArrayWrapper_init(JNIEnv *env, jobject this) -{ - int kq = kqueue(); - if (kq < 0) { - JNU_ThrowIOExceptionWithLastError(env, "KQueueArrayWrapper: kqueue() failed"); - } - return kq; -} - - -JNIEXPORT void JNICALL -Java_sun_nio_ch_KQueueArrayWrapper_register0(JNIEnv *env, jobject this, - jint kq, jint fd, jint r, jint w) -{ - struct kevent changes[2]; - struct kevent errors[2]; - struct timespec dontBlock = {0, 0}; - - // if (r) then { register for read } else { unregister for read } - // if (w) then { register for write } else { unregister for write } - // Ignore errors - they're probably complaints about deleting non- - // added filters - but provide an error array anyway because - // kqueue behaves erratically if some of its registrations fail. - EV_SET(&changes[0], fd, EVFILT_READ, r ? EV_ADD : EV_DELETE, 0, 0, 0); - EV_SET(&changes[1], fd, EVFILT_WRITE, w ? EV_ADD : EV_DELETE, 0, 0, 0); - kevent(kq, changes, 2, errors, 2, &dontBlock); -} - -JNIEXPORT jint JNICALL -Java_sun_nio_ch_KQueueArrayWrapper_kevent0(JNIEnv *env, jobject this, jint kq, - jlong kevAddr, jint kevCount, - jlong timeout) -{ - struct kevent *kevs = (struct kevent *)jlong_to_ptr(kevAddr); - struct timespec ts; - struct timespec *tsp; - int result; - - // Java timeout is in milliseconds. Convert to struct timespec. - // Java timeout == -1 : wait forever : timespec timeout of NULL - // Java timeout == 0 : return immediately : timespec timeout of zero - if (timeout >= 0) { - // For some indeterminate reason kevent(2) has been found to fail with - // an EINVAL error for timeout values greater than or equal to - // 100000001000L. To avoid this problem, clamp the timeout arbitrarily - // to the maximum value of a 32-bit signed integer which is - // approximately 25 days in milliseconds. - const jlong timeoutMax = 0x7fffffff; // java.lang.Integer.MAX_VALUE - if (timeout > timeoutMax) { - timeout = timeoutMax; - } - ts.tv_sec = timeout / 1000; - ts.tv_nsec = (timeout % 1000) * 1000000; //nanosec = 1 million millisec - tsp = &ts; - } else { - tsp = NULL; - } - - RESTARTABLE(kevent(kq, NULL, 0, kevs, kevCount, tsp), result); - if (result < 0) { - JNU_ThrowIOExceptionWithLastError(env, - "KQueueArrayWrapper: kevent poll failed"); - } - - return result; -} - - -JNIEXPORT void JNICALL -Java_sun_nio_ch_KQueueArrayWrapper_interrupt(JNIEnv *env, jclass cls, jint fd) -{ - char c = 1; - if (1 != write(fd, &c, 1)) { - JNU_ThrowIOExceptionWithLastError(env, "KQueueArrayWrapper: interrupt failed"); - } -} - diff -r eb72d194235c -r 514c68575523 src/java.base/macosx/native/libnio/ch/KQueuePort.c --- a/src/java.base/macosx/native/libnio/ch/KQueuePort.c Fri Mar 23 18:01:52 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. 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 "jni.h" -#include "jni_util.h" -#include "jvm.h" -#include "jlong.h" -#include "nio_util.h" - -#include "sun_nio_ch_KQueuePort.h" - -#include -#include -#include - -JNIEXPORT void JNICALL -Java_sun_nio_ch_KQueuePort_socketpair(JNIEnv* env, jclass clazz, jintArray sv) { - int sp[2]; - if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) == -1) { - JNU_ThrowIOExceptionWithLastError(env, "socketpair failed"); - } else { - jint res[2]; - res[0] = (jint)sp[0]; - res[1] = (jint)sp[1]; - (*env)->SetIntArrayRegion(env, sv, 0, 2, &res[0]); - } -} - -JNIEXPORT void JNICALL -Java_sun_nio_ch_KQueuePort_interrupt(JNIEnv *env, jclass c, jint fd) { - int res; - int buf[1]; - buf[0] = 1; - RESTARTABLE(write(fd, buf, 1), res); - if (res < 0) { - JNU_ThrowIOExceptionWithLastError(env, "write failed"); - } -} - -JNIEXPORT void JNICALL -Java_sun_nio_ch_KQueuePort_drain1(JNIEnv *env, jclass cl, jint fd) { - int res; - char buf[1]; - RESTARTABLE(read(fd, buf, 1), res); - if (res < 0) { - JNU_ThrowIOExceptionWithLastError(env, "drain1 failed"); - } -} - -JNIEXPORT void JNICALL -Java_sun_nio_ch_KQueuePort_close0(JNIEnv *env, jclass c, jint fd) { - int res; - RESTARTABLE(close(fd), res); -} diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/io/ByteArrayInputStream.java --- a/src/java.base/share/classes/java/io/ByteArrayInputStream.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/io/ByteArrayInputStream.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,15 @@ package java.io; +import java.util.Arrays; +import java.util.Objects; + /** - * A ByteArrayInputStream contains + * A {@code ByteArrayInputStream} contains * an internal buffer that contains bytes that * may be read from the stream. An internal * counter keeps track of the next byte to - * be supplied by the read method. + * be supplied by the {@code read} method. *

* Closing a {@code ByteArrayInputStream} has no effect. The methods in * this class can be called after the stream has been closed without @@ -40,15 +43,14 @@ * @see java.io.StringBufferInputStream * @since 1.0 */ -public -class ByteArrayInputStream extends InputStream { +public class ByteArrayInputStream extends InputStream { /** * An array of bytes that was provided - * by the creator of the stream. Elements buf[0] - * through buf[count-1] are the + * by the creator of the stream. Elements {@code buf[0]} + * through {@code buf[count-1]} are the * only bytes that can ever be read from the - * stream; element buf[pos] is + * stream; element {@code buf[pos]} is * the next byte to be read. */ protected byte buf[]; @@ -56,9 +58,9 @@ /** * The index of the next character to read from the input stream buffer. * This value should always be nonnegative - * and not larger than the value of count. + * and not larger than the value of {@code count}. * The next byte to be read from the input stream buffer - * will be buf[pos]. + * will be {@code buf[pos]}. */ protected int pos; @@ -66,9 +68,9 @@ * The currently marked position in the stream. * ByteArrayInputStream objects are marked at position zero by * default when constructed. They may be marked at another - * position within the buffer by the mark() method. + * position within the buffer by the {@code mark()} method. * The current buffer position is set to this point by the - * reset() method. + * {@code reset()} method. *

* If no mark has been set, then the value of mark is the offset * passed to the constructor (or 0 if the offset was not supplied). @@ -81,22 +83,22 @@ * The index one greater than the last valid character in the input * stream buffer. * This value should always be nonnegative - * and not larger than the length of buf. + * and not larger than the length of {@code buf}. * It is one greater than the position of - * the last byte within buf that + * the last byte within {@code buf} that * can ever be read from the input stream buffer. */ protected int count; /** - * Creates a ByteArrayInputStream - * so that it uses buf as its + * Creates a {@code ByteArrayInputStream} + * so that it uses {@code buf} as its * buffer array. * The buffer array is not copied. - * The initial value of pos - * is 0 and the initial value - * of count is the length of - * buf. + * The initial value of {@code pos} + * is {@code 0} and the initial value + * of {@code count} is the length of + * {@code buf}. * * @param buf the input buffer. */ @@ -107,12 +109,12 @@ } /** - * Creates ByteArrayInputStream - * that uses buf as its - * buffer array. The initial value of pos - * is offset and the initial value - * of count is the minimum of offset+length - * and buf.length. + * Creates {@code ByteArrayInputStream} + * that uses {@code buf} as its + * buffer array. The initial value of {@code pos} + * is {@code offset} and the initial value + * of {@code count} is the minimum of {@code offset+length} + * and {@code buf.length}. * The buffer array is not copied. The buffer's mark is * set to the specified offset. * @@ -129,15 +131,15 @@ /** * Reads the next byte of data from this input stream. The value - * byte is returned as an int in the range - * 0 to 255. If no byte is available + * byte is returned as an {@code int} in the range + * {@code 0} to {@code 255}. If no byte is available * because the end of the stream has been reached, the value - * -1 is returned. + * {@code -1} is returned. *

- * This read method + * This {@code read} method * cannot block. * - * @return the next byte of data, or -1 if the end of the + * @return the next byte of data, or {@code -1} if the end of the * stream has been reached. */ public synchronized int read() { @@ -145,40 +147,30 @@ } /** - * Reads up to len bytes of data into an array of bytes - * from this input stream. - * If pos equals count, - * then -1 is returned to indicate - * end of file. Otherwise, the number k - * of bytes read is equal to the smaller of - * len and count-pos. - * If k is positive, then bytes - * buf[pos] through buf[pos+k-1] - * are copied into b[off] through - * b[off+k-1] in the manner performed - * by System.arraycopy. The - * value k is added into pos - * and k is returned. + * Reads up to {@code len} bytes of data into an array of bytes from this + * input stream. If {@code pos} equals {@code count}, then {@code -1} is + * returned to indicate end of file. Otherwise, the number {@code k} of + * bytes read is equal to the smaller of {@code len} and {@code count-pos}. + * If {@code k} is positive, then bytes {@code buf[pos]} through + * {@code buf[pos+k-1]} are copied into {@code b[off]} through + * {@code b[off+k-1]} in the manner performed by {@code System.arraycopy}. + * The value {@code k} is added into {@code pos} and {@code k} is returned. *

- * This read method cannot block. + * This {@code read} method cannot block. * * @param b the buffer into which the data is read. - * @param off the start offset in the destination array b + * @param off the start offset in the destination array {@code b} * @param len the maximum number of bytes read. * @return the total number of bytes read into the buffer, or - * -1 if there is no more data because the end of + * {@code -1} if there is no more data because the end of * the stream has been reached. - * @exception NullPointerException If b is null. - * @exception IndexOutOfBoundsException If off is negative, - * len is negative, or len is greater than - * b.length - off + * @throws NullPointerException If {@code b} is {@code null}. + * @throws IndexOutOfBoundsException If {@code off} is negative, + * {@code len} is negative, or {@code len} is greater than + * {@code b.length - off} */ public synchronized int read(byte b[], int off, int len) { - if (b == null) { - throw new NullPointerException(); - } else if (off < 0 || len < 0 || len > b.length - off) { - throw new IndexOutOfBoundsException(); - } + Objects.checkFromIndexSize(off, len, b.length); if (pos >= count) { return -1; @@ -196,14 +188,32 @@ return len; } + public synchronized byte[] readAllBytes() { + byte[] result = Arrays.copyOfRange(buf, pos, count); + pos = count; + return result; + } + + public int readNBytes(byte[] b, int off, int len) { + int n = read(b, off, len); + return n == -1 ? 0 : n; + } + + public synchronized long transferTo(OutputStream out) throws IOException { + int len = count - pos; + out.write(buf, pos, len); + pos = count; + return len; + } + /** - * Skips n bytes of input from this input stream. Fewer + * Skips {@code n} bytes of input from this input stream. Fewer * bytes might be skipped if the end of the input stream is reached. - * The actual number k + * The actual number {@code k} * of bytes to be skipped is equal to the smaller - * of n and count-pos. - * The value k is added into pos - * and k is returned. + * of {@code n} and {@code count-pos}. + * The value {@code k} is added into {@code pos} + * and {@code k} is returned. * * @param n the number of bytes to be skipped. * @return the actual number of bytes skipped. @@ -222,7 +232,7 @@ * Returns the number of remaining bytes that can be read (or skipped over) * from this input stream. *

- * The value returned is count - pos, + * The value returned is {@code count - pos}, * which is the number of bytes remaining to be read from the input buffer. * * @return the number of remaining bytes that can be read (or skipped @@ -233,9 +243,9 @@ } /** - * Tests if this InputStream supports mark/reset. The - * markSupported method of ByteArrayInputStream - * always returns true. + * Tests if this {@code InputStream} supports mark/reset. The + * {@code markSupported} method of {@code ByteArrayInputStream} + * always returns {@code true}. * * @since 1.1 */ @@ -253,7 +263,7 @@ * offset passed to the constructor (or 0 if the offset was not * supplied). * - *

Note: The readAheadLimit for this class + *

Note: The {@code readAheadLimit} for this class * has no meaning. * * @since 1.1 diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/lang/invoke/ProxyClassesDumper.java --- a/src/java.base/share/classes/java/lang/invoke/ProxyClassesDumper.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/lang/invoke/ProxyClassesDumper.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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 @@ -30,7 +30,6 @@ import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; -import java.nio.file.Paths; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Objects; @@ -63,7 +62,7 @@ } try { path = path.trim(); - final Path dir = Paths.get(path.length() == 0 ? "." : path); + final Path dir = Path.of(path.length() == 0 ? "." : path); AccessController.doPrivileged(new PrivilegedAction<>() { @Override public Void run() { diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java --- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2018, 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 @@ -34,7 +34,6 @@ import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; @@ -346,11 +345,11 @@ int i = name.lastIndexOf('.'); Path path; if (i > 0) { - Path dir = Paths.get(name.substring(0, i).replace('.', File.separatorChar)); + Path dir = Path.of(name.substring(0, i).replace('.', File.separatorChar)); Files.createDirectories(dir); path = dir.resolve(name.substring(i+1, name.length()) + ".class"); } else { - path = Paths.get(name + ".class"); + path = Path.of(name + ".class"); } Files.write(path, classFile); return null; diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/nio/StringCharBuffer.java --- a/src/java.base/share/classes/java/nio/StringCharBuffer.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/nio/StringCharBuffer.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, 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 @@ -149,7 +149,7 @@ that, that.position(), Math.min(this.remaining(), that.remaining())); if (i >= 0) { - return Character.compare(this.get(this.position() + i), that.get(this.position() + i)); + return Character.compare(this.get(this.position() + i), that.get(that.position() + i)); } return this.remaining() - that.remaining(); } diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/nio/X-Buffer.java.template --- a/src/java.base/share/classes/java/nio/X-Buffer.java.template Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/nio/X-Buffer.java.template Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, 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 @@ -1337,7 +1337,7 @@ that, that.position(), Math.min(this.remaining(), that.remaining())); if (i >= 0) { - return compare(this.get(this.position() + i), that.get(this.position() + i)); + return compare(this.get(this.position() + i), that.get(that.position() + i)); } return this.remaining() - that.remaining(); } diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/nio/channels/DatagramChannel.java --- a/src/java.base/share/classes/java/nio/channels/DatagramChannel.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/nio/channels/DatagramChannel.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, 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 @@ -279,6 +279,9 @@ * * @return This datagram channel * + * @throws AlreadyConnectedException + * If this channel is already connected + * * @throws ClosedChannelException * If this channel is closed * @@ -292,6 +295,12 @@ * closing the channel and setting the current thread's * interrupt status * + * @throws UnresolvedAddressException + * If the given remote address is not fully resolved + * + * @throws UnsupportedAddressTypeException + * If the type of the given remote address is not supported + * * @throws SecurityException * If a security manager has been installed * and it does not permit access to the given remote address @@ -444,6 +453,10 @@ * zero if there was insufficient room for the datagram in the * underlying output buffer * + * @throws AlreadyConnectedException + * If this channel is connected to a different address + * from that specified by {@code target} + * * @throws ClosedChannelException * If this channel is closed * @@ -457,6 +470,12 @@ * closing the channel and setting the current thread's * interrupt status * + * @throws UnresolvedAddressException + * If the given remote address is not fully resolved + * + * @throws UnsupportedAddressTypeException + * If the type of the given remote address is not supported + * * @throws SecurityException * If a security manager has been installed * and it does not permit datagrams to be sent diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/nio/file/Path.java --- a/src/java.base/share/classes/java/nio/file/Path.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/nio/file/Path.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, 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 @@ -28,6 +28,7 @@ import java.io.File; import java.io.IOException; import java.net.URI; +import java.nio.file.spi.FileSystemProvider; import java.util.Iterator; import java.util.NoSuchElementException; @@ -93,13 +94,125 @@ * multiple concurrent threads. * * @since 1.7 - * @see Paths */ public interface Path extends Comparable, Iterable, Watchable { /** + * Returns a {@code Path} by converting a path string, or a sequence of + * strings that when joined form a path string. If {@code more} does not + * specify any elements then the value of the {@code first} parameter is + * the path string to convert. If {@code more} specifies one or more + * elements then each non-empty string, including {@code first}, is + * considered to be a sequence of name elements and is joined to form a + * path string. The details as to how the Strings are joined is provider + * specific but typically they will be joined using the + * {@link FileSystem#getSeparator name-separator} as the separator. + * For example, if the name separator is "{@code /}" and + * {@code getPath("/foo","bar","gus")} is invoked, then the path string + * {@code "/foo/bar/gus"} is converted to a {@code Path}. A {@code Path} + * representing an empty path is returned if {@code first} is the empty + * string and {@code more} does not contain any non-empty strings. + * + *

The {@code Path} is obtained by invoking the {@link FileSystem#getPath + * getPath} method of the {@link FileSystems#getDefault default} {@link + * FileSystem}. + * + *

Note that while this method is very convenient, using it will imply + * an assumed reference to the default {@code FileSystem} and limit the + * utility of the calling code. Hence it should not be used in library code + * intended for flexible reuse. A more flexible alternative is to use an + * existing {@code Path} instance as an anchor, such as: + *

{@code
+     *     Path dir = ...
+     *     Path path = dir.resolve("file");
+     * }
+ * + * @param first + * the path string or initial part of the path string + * @param more + * additional strings to be joined to form the path string + * + * @return the resulting {@code Path} + * + * @throws InvalidPathException + * if the path string cannot be converted to a {@code Path} + * + * @see FileSystem#getPath + * + * @since 11 + */ + public static Path of(String first, String... more) { + return FileSystems.getDefault().getPath(first, more); + } + + /** + * Returns a {@code Path} by converting a URI. + * + *

This method iterates over the {@link FileSystemProvider#installedProviders() + * installed} providers to locate the provider that is identified by the + * URI {@link URI#getScheme scheme} of the given URI. URI schemes are + * compared without regard to case. If the provider is found then its {@link + * FileSystemProvider#getPath getPath} method is invoked to convert the + * URI. + * + *

In the case of the default provider, identified by the URI scheme + * "file", the given URI has a non-empty path component, and undefined query + * and fragment components. Whether the authority component may be present + * is platform specific. The returned {@code Path} is associated with the + * {@link FileSystems#getDefault default} file system. + * + *

The default provider provides a similar round-trip guarantee + * to the {@link java.io.File} class. For a given {@code Path} p it + * is guaranteed that + *

{@code + * Path.of(}p{@code .}{@link Path#toUri() toUri}{@code ()).equals(} + * p{@code .}{@link Path#toAbsolutePath() toAbsolutePath}{@code ())} + *
+ * so long as the original {@code Path}, the {@code URI}, and the new {@code + * Path} are all created in (possibly different invocations of) the same + * Java virtual machine. Whether other providers make any guarantees is + * provider specific and therefore unspecified. + * + * @param uri + * the URI to convert + * + * @return the resulting {@code Path} + * + * @throws IllegalArgumentException + * if preconditions on the {@code uri} parameter do not hold. The + * format of the URI is provider specific. + * @throws FileSystemNotFoundException + * The file system, identified by the URI, does not exist and + * cannot be created automatically, or the provider identified by + * the URI's scheme component is not installed + * @throws SecurityException + * if a security manager is installed and it denies an unspecified + * permission to access the file system + * + * @since 11 + */ + public static Path of(URI uri) { + String scheme = uri.getScheme(); + if (scheme == null) + throw new IllegalArgumentException("Missing scheme"); + + // check for default provider to avoid loading of installed providers + if (scheme.equalsIgnoreCase("file")) + return FileSystems.getDefault().provider().getPath(uri); + + // try to find provider + for (FileSystemProvider provider: FileSystemProvider.installedProviders()) { + if (provider.getScheme().equalsIgnoreCase(scheme)) { + return provider.getPath(uri); + } + } + + throw new FileSystemNotFoundException("Provider \"" + scheme + "\" not installed"); + } + + /** * Returns the file system that created this object. * * @return the file system that created this object @@ -527,7 +640,7 @@ * to the {@link java.io.File} class. For a given {@code Path} p it * is guaranteed that *
- * {@link Paths#get(URI) Paths.get}{@code (}p{@code .toUri()).equals(}p + * {@link Path#of(URI) Path.of}{@code (}p{@code .toUri()).equals(}p * {@code .}{@link #toAbsolutePath() toAbsolutePath}{@code ())} *
* so long as the original {@code Path}, the {@code URI}, and the new {@code diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/nio/file/Paths.java --- a/src/java.base/share/classes/java/nio/file/Paths.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/nio/file/Paths.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, 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 @@ -32,7 +32,13 @@ * This class consists exclusively of static methods that return a {@link Path} * by converting a path string or {@link URI}. * + * @apiNote + * It is recommended to obtain a {@code Path} via the {@code Path.of} methods + * instead of via the {@code get} methods defined in this class as this class + * may be deprecated in a future release. + * * @since 1.7 + * @see Path */ public final class Paths { @@ -40,33 +46,11 @@ /** * Converts a path string, or a sequence of strings that when joined form - * a path string, to a {@code Path}. If {@code more} does not specify any - * elements then the value of the {@code first} parameter is the path string - * to convert. If {@code more} specifies one or more elements then each - * non-empty string, including {@code first}, is considered to be a sequence - * of name elements (see {@link Path}) and is joined to form a path string. - * The details as to how the Strings are joined is provider specific but - * typically they will be joined using the {@link FileSystem#getSeparator - * name-separator} as the separator. For example, if the name separator is - * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the - * path string {@code "/foo/bar/gus"} is converted to a {@code Path}. - * A {@code Path} representing an empty path is returned if {@code first} - * is the empty string and {@code more} does not contain any non-empty - * strings. + * a path string, to a {@code Path}. * - *

The {@code Path} is obtained by invoking the {@link FileSystem#getPath - * getPath} method of the {@link FileSystems#getDefault default} {@link - * FileSystem}. - * - *

Note that while this method is very convenient, using it will imply - * an assumed reference to the default {@code FileSystem} and limit the - * utility of the calling code. Hence it should not be used in library code - * intended for flexible reuse. A more flexible alternative is to use an - * existing {@code Path} instance as an anchor, such as: - *

-     *     Path dir = ...
-     *     Path path = dir.resolve("file");
-     * 
+ * @implSpec + * This method simply invokes {@link Path#of(String,String...) + * Path.of(String, String...)} with the given parameters. * * @param first * the path string or initial part of the path string @@ -79,38 +63,17 @@ * if the path string cannot be converted to a {@code Path} * * @see FileSystem#getPath + * @see Path#of(String,String...) */ public static Path get(String first, String... more) { - return FileSystems.getDefault().getPath(first, more); + return Path.of(first, more); } /** * Converts the given URI to a {@link Path} object. * - *

This method iterates over the {@link FileSystemProvider#installedProviders() - * installed} providers to locate the provider that is identified by the - * URI {@link URI#getScheme scheme} of the given URI. URI schemes are - * compared without regard to case. If the provider is found then its {@link - * FileSystemProvider#getPath getPath} method is invoked to convert the - * URI. - * - *

In the case of the default provider, identified by the URI scheme - * "file", the given URI has a non-empty path component, and undefined query - * and fragment components. Whether the authority component may be present - * is platform specific. The returned {@code Path} is associated with the - * {@link FileSystems#getDefault default} file system. - * - *

The default provider provides a similar round-trip guarantee - * to the {@link java.io.File} class. For a given {@code Path} p it - * is guaranteed that - *

{@code - * Paths.get(}p{@code .}{@link Path#toUri() toUri}{@code ()).equals(} - * p{@code .}{@link Path#toAbsolutePath() toAbsolutePath}{@code ())} - *
- * so long as the original {@code Path}, the {@code URI}, and the new {@code - * Path} are all created in (possibly different invocations of) the same - * Java virtual machine. Whether other providers make any guarantees is - * provider specific and therefore unspecified. + * @implSpec + * This method simply invokes {@link Path#of(URI) * Path.of(URI)} with the given parameter. * * @param uri * the URI to convert @@ -127,23 +90,10 @@ * @throws SecurityException * if a security manager is installed and it denies an unspecified * permission to access the file system + * + * @see Path#of(URI) */ public static Path get(URI uri) { - String scheme = uri.getScheme(); - if (scheme == null) - throw new IllegalArgumentException("Missing scheme"); - - // check for default provider to avoid loading of installed providers - if (scheme.equalsIgnoreCase("file")) - return FileSystems.getDefault().provider().getPath(uri); - - // try to find provider - for (FileSystemProvider provider: FileSystemProvider.installedProviders()) { - if (provider.getScheme().equalsIgnoreCase(scheme)) { - return provider.getPath(uri); - } - } - - throw new FileSystemNotFoundException("Provider \"" + scheme + "\" not installed"); + return Path.of(uri); } } diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/nio/file/TempFileHelper.java --- a/src/java.base/share/classes/java/nio/file/TempFileHelper.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/nio/file/TempFileHelper.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2018, 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 @@ -46,7 +46,7 @@ // temporary directory location private static final Path tmpdir = - Paths.get(GetPropertyAction.privilegedGetProperty("java.io.tmpdir")); + Path.of(GetPropertyAction.privilegedGetProperty("java.io.tmpdir")); private static final boolean isPosix = FileSystems.getDefault().supportedFileAttributeViews().contains("posix"); diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/util/AbstractSet.java --- a/src/java.base/share/classes/java/util/AbstractSet.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/util/AbstractSet.java Fri Mar 23 18:44:47 2018 +0000 @@ -93,9 +93,7 @@ return false; try { return containsAll(c); - } catch (ClassCastException unused) { - return false; - } catch (NullPointerException unused) { + } catch (ClassCastException | NullPointerException unused) { return false; } } diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/util/ImmutableCollections.java --- a/src/java.base/share/classes/java/util/ImmutableCollections.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/util/ImmutableCollections.java Fri Mar 23 18:44:47 2018 +0000 @@ -70,46 +70,297 @@ static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); } - // ---------- List Implementations ---------- - - abstract static class AbstractImmutableList extends AbstractList - implements RandomAccess, Serializable { + static abstract class AbstractImmutableCollection extends AbstractCollection { + // all mutating methods throw UnsupportedOperationException @Override public boolean add(E e) { throw uoe(); } @Override public boolean addAll(Collection c) { throw uoe(); } - @Override public boolean addAll(int index, Collection c) { throw uoe(); } @Override public void clear() { throw uoe(); } @Override public boolean remove(Object o) { throw uoe(); } @Override public boolean removeAll(Collection c) { throw uoe(); } @Override public boolean removeIf(Predicate filter) { throw uoe(); } + @Override public boolean retainAll(Collection c) { throw uoe(); } + } + + // ---------- List Implementations ---------- + + @SuppressWarnings("unchecked") + static List emptyList() { + return (List) ListN.EMPTY_LIST; + } + + static abstract class AbstractImmutableList extends AbstractImmutableCollection + implements List, RandomAccess { + + // all mutating methods throw UnsupportedOperationException + @Override public void add(int index, E element) { throw uoe(); } + @Override public boolean addAll(int index, Collection c) { throw uoe(); } + @Override public E remove(int index) { throw uoe(); } @Override public void replaceAll(UnaryOperator operator) { throw uoe(); } - @Override public boolean retainAll(Collection c) { throw uoe(); } + @Override public E set(int index, E element) { throw uoe(); } @Override public void sort(Comparator c) { throw uoe(); } + + @Override + public List subList(int fromIndex, int toIndex) { + int size = size(); + subListRangeCheck(fromIndex, toIndex, size); + return SubList.fromList(this, fromIndex, toIndex); + } + + static void subListRangeCheck(int fromIndex, int toIndex, int size) { + if (fromIndex < 0) + throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); + if (toIndex > size) + throw new IndexOutOfBoundsException("toIndex = " + toIndex); + if (fromIndex > toIndex) + throw new IllegalArgumentException("fromIndex(" + fromIndex + + ") > toIndex(" + toIndex + ")"); + } + + @Override + public Iterator iterator() { + return new ListItr(this, size()); + } + + @Override + public ListIterator listIterator() { + return listIterator(0); + } + + @Override + public ListIterator listIterator(final int index) { + int size = size(); + if (index < 0 || index > size) { + throw outOfBounds(index); + } + return new ListItr(this, size, index); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + + if (!(o instanceof List)) { + return false; + } + + Iterator oit = ((List) o).iterator(); + for (int i = 0, s = size(); i < s; i++) { + if (!oit.hasNext() || !get(i).equals(oit.next())) { + return false; + } + } + return !oit.hasNext(); + } + + @Override + public int indexOf(Object o) { + Objects.requireNonNull(o); + for (int i = 0, s = size(); i < s; i++) { + if (o.equals(get(i))) { + return i; + } + } + return -1; + } + + @Override + public int lastIndexOf(Object o) { + Objects.requireNonNull(o); + for (int i = size() - 1; i >= 0; i--) { + if (o.equals(get(i))) { + return i; + } + } + return -1; + } + + @Override + public int hashCode() { + int hash = 1; + for (int i = 0, s = size(); i < s; i++) { + hash = 31 * hash + get(i).hashCode(); + } + return hash; + } + + @Override + public boolean contains(Object o) { + return indexOf(o) >= 0; + } + + IndexOutOfBoundsException outOfBounds(int index) { + return new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); + } } - static final class List0 extends AbstractImmutableList { - private static final List0 INSTANCE = new List0<>(); + static final class ListItr implements ListIterator { + + @Stable + private final List list; + + @Stable + private final int size; + + private int cursor; + + ListItr(List list, int size) { + this(list, size, 0); + } + + ListItr(List list, int size, int index) { + this.list = list; + this.size = size; + this.cursor = index; + } + + public boolean hasNext() { + return cursor != size; + } - @SuppressWarnings("unchecked") - static List0 instance() { - return (List0) INSTANCE; + public E next() { + try { + int i = cursor; + E next = list.get(i); + cursor = i + 1; + return next; + } catch (IndexOutOfBoundsException e) { + throw new NoSuchElementException(); + } + } + + public void remove() { + throw uoe(); + } + + public boolean hasPrevious() { + return cursor != 0; + } + + public E previous() { + try { + int i = cursor - 1; + E previous = list.get(i); + cursor = i; + return previous; + } catch (IndexOutOfBoundsException e) { + throw new NoSuchElementException(); + } + } + + public int nextIndex() { + return cursor; + } + + public int previousIndex() { + return cursor - 1; + } + + public void set(E e) { + throw uoe(); } - private List0() { } + public void add(E e) { + throw uoe(); + } + } + + static final class SubList extends AbstractImmutableList + implements RandomAccess { + + @Stable + private final List root; + + @Stable + private final int offset; + + @Stable + private final int size; + + private SubList(List root, int offset, int size) { + this.root = root; + this.offset = offset; + this.size = size; + } + + /** + * Constructs a sublist of another SubList. + */ + static SubList fromSubList(SubList parent, int fromIndex, int toIndex) { + return new SubList(parent.root, parent.offset + fromIndex, toIndex - fromIndex); + } + + /** + * Constructs a sublist of an arbitrary AbstractImmutableList, which is + * not a SubList itself. + */ + static SubList fromList(List list, int fromIndex, int toIndex) { + return new SubList(list, fromIndex, toIndex - fromIndex); + } + + public E get(int index) { + Objects.checkIndex(index, size); + return root.get(offset + index); + } + + public int size() { + return size; + } + + public Iterator iterator() { + return new ListItr(this, size()); + } + + public ListIterator listIterator(int index) { + rangeCheck(index); + return new ListItr(this, size(), index); + } + + public List subList(int fromIndex, int toIndex) { + subListRangeCheck(fromIndex, toIndex, size); + return SubList.fromSubList(this, fromIndex, toIndex); + } + + private void rangeCheck(int index) { + if (index < 0 || index > size) { + throw outOfBounds(index); + } + } + } + + static final class List12 extends AbstractImmutableList + implements Serializable { + + @Stable + private final E e0; + + @Stable + private final E e1; + + List12(E e0) { + this.e0 = Objects.requireNonNull(e0); + this.e1 = null; + } + + List12(E e0, E e1) { + this.e0 = Objects.requireNonNull(e0); + this.e1 = Objects.requireNonNull(e1); + } @Override public int size() { - return 0; + return e1 != null ? 2 : 1; } @Override public E get(int index) { - Objects.checkIndex(index, 0); // always throws IndexOutOfBoundsException - return null; // but the compiler doesn't know this - } - - @Override - public Iterator iterator() { - return Collections.emptyIterator(); + if (index == 0) { + return e0; + } else if (index == 1 && e1 != null) { + return e1; + } + throw outOfBounds(index); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { @@ -117,111 +368,20 @@ } private Object writeReplace() { - return new CollSer(CollSer.IMM_LIST); - } - - @Override - public boolean contains(Object o) { - Objects.requireNonNull(o); - return false; - } - - @Override - public boolean containsAll(Collection o) { - return o.isEmpty(); // implicit nullcheck of o - } - - @Override - public int hashCode() { - return 1; - } - } - - static final class List1 extends AbstractImmutableList { - @Stable - private final E e0; - - List1(E e0) { - this.e0 = Objects.requireNonNull(e0); - } - - @Override - public int size() { - return 1; - } - - @Override - public E get(int index) { - Objects.checkIndex(index, 1); - return e0; - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - throw new InvalidObjectException("not serial proxy"); - } - - private Object writeReplace() { - return new CollSer(CollSer.IMM_LIST, e0); - } - - @Override - public boolean contains(Object o) { - return o.equals(e0); // implicit nullcheck of o - } - - @Override - public int hashCode() { - return 31 + e0.hashCode(); - } - } - - static final class List2 extends AbstractImmutableList { - @Stable - private final E e0; - @Stable - private final E e1; - - List2(E e0, E e1) { - this.e0 = Objects.requireNonNull(e0); - this.e1 = Objects.requireNonNull(e1); - } - - @Override - public int size() { - return 2; - } - - @Override - public E get(int index) { - Objects.checkIndex(index, 2); - if (index == 0) { - return e0; - } else { // index == 1 - return e1; + if (e1 == null) { + return new CollSer(CollSer.IMM_LIST, e0); + } else { + return new CollSer(CollSer.IMM_LIST, e0, e1); } } - @Override - public boolean contains(Object o) { - return o.equals(e0) || o.equals(e1); // implicit nullcheck of o - } - - @Override - public int hashCode() { - int hash = 31 + e0.hashCode(); - return 31 * hash + e1.hashCode(); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - throw new InvalidObjectException("not serial proxy"); - } - - private Object writeReplace() { - return new CollSer(CollSer.IMM_LIST, e0, e1); - } } - static final class ListN extends AbstractImmutableList { + static final class ListN extends AbstractImmutableList + implements Serializable { + + static final List EMPTY_LIST = new ListN<>(); + @Stable private final E[] elements; @@ -233,7 +393,12 @@ for (int i = 0; i < input.length; i++) { tmp[i] = Objects.requireNonNull(input[i]); } - this.elements = tmp; + elements = tmp; + } + + @Override + public boolean isEmpty() { + return size() == 0; } @Override @@ -243,29 +408,9 @@ @Override public E get(int index) { - Objects.checkIndex(index, elements.length); return elements[index]; } - @Override - public boolean contains(Object o) { - for (E e : elements) { - if (o.equals(e)) { // implicit nullcheck of o - return true; - } - } - return false; - } - - @Override - public int hashCode() { - int hash = 1; - for (E e : elements) { - hash = 31 * hash + e.hashCode(); - } - return hash; - } - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { throw new InvalidObjectException("not serial proxy"); } @@ -277,105 +422,52 @@ // ---------- Set Implementations ---------- - abstract static class AbstractImmutableSet extends AbstractSet implements Serializable { - @Override public boolean add(E e) { throw uoe(); } - @Override public boolean addAll(Collection c) { throw uoe(); } - @Override public void clear() { throw uoe(); } - @Override public boolean remove(Object o) { throw uoe(); } - @Override public boolean removeAll(Collection c) { throw uoe(); } - @Override public boolean removeIf(Predicate filter) { throw uoe(); } - @Override public boolean retainAll(Collection c) { throw uoe(); } - } - - static final class Set0 extends AbstractImmutableSet { - private static final Set0 INSTANCE = new Set0<>(); - - @SuppressWarnings("unchecked") - static Set0 instance() { - return (Set0) INSTANCE; - } - - private Set0() { } + static abstract class AbstractImmutableSet extends AbstractImmutableCollection + implements Set { @Override - public int size() { - return 0; - } + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (!(o instanceof Set)) { + return false; + } - @Override - public boolean contains(Object o) { - Objects.requireNonNull(o); - return false; - } - - @Override - public boolean containsAll(Collection o) { - return o.isEmpty(); // implicit nullcheck of o + Collection c = (Collection) o; + if (c.size() != size()) { + return false; + } + for (Object e : c) { + if (e == null || !contains(e)) { + return false; + } + } + return true; } @Override - public Iterator iterator() { - return Collections.emptyIterator(); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - throw new InvalidObjectException("not serial proxy"); - } - - private Object writeReplace() { - return new CollSer(CollSer.IMM_SET); - } - - @Override - public int hashCode() { - return 0; - } + public abstract int hashCode(); } - static final class Set1 extends AbstractImmutableSet { - @Stable - private final E e0; - - Set1(E e0) { - this.e0 = Objects.requireNonNull(e0); - } - - @Override - public int size() { - return 1; - } - - @Override - public boolean contains(Object o) { - return o.equals(e0); // implicit nullcheck of o - } - - @Override - public Iterator iterator() { - return Collections.singletonIterator(e0); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - throw new InvalidObjectException("not serial proxy"); - } - - private Object writeReplace() { - return new CollSer(CollSer.IMM_SET, e0); - } - - @Override - public int hashCode() { - return e0.hashCode(); - } + @SuppressWarnings("unchecked") + static Set emptySet() { + return (Set) SetN.EMPTY_SET; } - static final class Set2 extends AbstractImmutableSet { + static final class Set12 extends AbstractImmutableSet + implements Serializable { + @Stable final E e0; @Stable final E e1; - Set2(E e0, E e1) { + Set12(E e0) { + this.e0 = Objects.requireNonNull(e0); + this.e1 = null; + } + + Set12(E e0, E e1) { if (e0.equals(Objects.requireNonNull(e1))) { // implicit nullcheck of e0 throw new IllegalArgumentException("duplicate element: " + e0); } @@ -391,7 +483,7 @@ @Override public int size() { - return 2; + return (e1 == null) ? 1 : 2; } @Override @@ -401,26 +493,26 @@ @Override public int hashCode() { - return e0.hashCode() + e1.hashCode(); + return e0.hashCode() + (e1 == null ? 0 : e1.hashCode()); } @Override public Iterator iterator() { - return new Iterator() { - private int idx = 0; + return new Iterator<>() { + private int idx = size(); @Override public boolean hasNext() { - return idx < 2; + return idx > 0; } @Override public E next() { - if (idx == 0) { - idx = 1; + if (idx == 1) { + idx = 0; return e0; - } else if (idx == 1) { - idx = 2; + } else if (idx == 2) { + idx = 1; return e1; } else { throw new NoSuchElementException(); @@ -434,7 +526,11 @@ } private Object writeReplace() { - return new CollSer(CollSer.IMM_SET, e0, e1); + if (e1 == null) { + return new CollSer(CollSer.IMM_SET, e0); + } else { + return new CollSer(CollSer.IMM_SET, e0, e1); + } } } @@ -444,7 +540,11 @@ * least one null is always present. * @param the element type */ - static final class SetN extends AbstractImmutableSet { + static final class SetN extends AbstractImmutableSet + implements Serializable { + + static final Set EMPTY_SET = new SetN<>(); + @Stable final E[] elements; @Stable @@ -474,12 +574,13 @@ @Override public boolean contains(Object o) { - return probe(o) >= 0; // implicit nullcheck of o + Objects.requireNonNull(o); + return size > 0 && probe(o) >= 0; } @Override public Iterator iterator() { - return new Iterator() { + return new Iterator<>() { private int idx = 0; @Override @@ -549,6 +650,11 @@ // ---------- Map Implementations ---------- + @SuppressWarnings("unchecked") + static Map emptyMap() { + return (Map) MapN.EMPTY_MAP; + } + abstract static class AbstractImmutableMap extends AbstractMap implements Serializable { @Override public void clear() { throw uoe(); } @Override public V compute(K key, BiFunction rf) { throw uoe(); } @@ -565,47 +671,6 @@ @Override public void replaceAll(BiFunction f) { throw uoe(); } } - static final class Map0 extends AbstractImmutableMap { - private static final Map0 INSTANCE = new Map0<>(); - - @SuppressWarnings("unchecked") - static Map0 instance() { - return (Map0) INSTANCE; - } - - private Map0() { } - - @Override - public Set> entrySet() { - return Set.of(); - } - - @Override - public boolean containsKey(Object o) { - Objects.requireNonNull(o); - return false; - } - - @Override - public boolean containsValue(Object o) { - Objects.requireNonNull(o); - return false; - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - throw new InvalidObjectException("not serial proxy"); - } - - private Object writeReplace() { - return new CollSer(CollSer.IMM_MAP); - } - - @Override - public int hashCode() { - return 0; - } - } - static final class Map1 extends AbstractImmutableMap { @Stable private final K k0; @@ -656,8 +721,12 @@ * @param the value type */ static final class MapN extends AbstractImmutableMap { + + static final Map EMPTY_MAP = new MapN<>(); + @Stable final Object[] table; // pairs of key, value + @Stable final int size; // number of pairs @@ -689,14 +758,16 @@ @Override public boolean containsKey(Object o) { - return probe(o) >= 0; // implicit nullcheck of o + Objects.requireNonNull(o); + return size > 0 && probe(o) >= 0; } @Override public boolean containsValue(Object o) { + Objects.requireNonNull(o); for (int i = 1; i < table.length; i += 2) { Object v = table[i]; - if (v != null && o.equals(v)) { // implicit nullcheck of o + if (v != null && o.equals(v)) { return true; } } @@ -718,6 +789,10 @@ @Override @SuppressWarnings("unchecked") public V get(Object o) { + if (size == 0) { + Objects.requireNonNull(o); + return null; + } int i = probe(o); if (i >= 0) { return (V)table[i+1]; @@ -733,7 +808,7 @@ @Override public Set> entrySet() { - return new AbstractSet>() { + return new AbstractSet<>() { @Override public int size() { return MapN.this.size; @@ -741,7 +816,7 @@ @Override public Iterator> iterator() { - return new Iterator>() { + return new Iterator<>() { int idx = 0; @Override @@ -948,7 +1023,7 @@ return Set.of(array); case IMM_MAP: if (array.length == 0) { - return ImmutableCollections.Map0.instance(); + return ImmutableCollections.emptyMap(); } else if (array.length == 2) { return new ImmutableCollections.Map1<>(array[0], array[1]); } else { diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/util/List.java --- a/src/java.base/share/classes/java/util/List.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/util/List.java Fri Mar 23 18:44:47 2018 +0000 @@ -788,7 +788,7 @@ * @since 9 */ static List of() { - return ImmutableCollections.List0.instance(); + return ImmutableCollections.emptyList(); } /** @@ -804,7 +804,7 @@ * @since 9 */ static List of(E e1) { - return new ImmutableCollections.List1<>(e1); + return new ImmutableCollections.List12<>(e1); } /** @@ -821,7 +821,7 @@ * @since 9 */ static List of(E e1, E e2) { - return new ImmutableCollections.List2<>(e1, e2); + return new ImmutableCollections.List12<>(e1, e2); } /** @@ -1031,11 +1031,11 @@ static List of(E... elements) { switch (elements.length) { // implicit null check of elements case 0: - return ImmutableCollections.List0.instance(); + return ImmutableCollections.emptyList(); case 1: - return new ImmutableCollections.List1<>(elements[0]); + return new ImmutableCollections.List12<>(elements[0]); case 2: - return new ImmutableCollections.List2<>(elements[0], elements[1]); + return new ImmutableCollections.List12<>(elements[0], elements[1]); default: return new ImmutableCollections.ListN<>(elements); } diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/util/Map.java --- a/src/java.base/share/classes/java/util/Map.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/util/Map.java Fri Mar 23 18:44:47 2018 +0000 @@ -1287,7 +1287,7 @@ * @since 9 */ static Map of() { - return ImmutableCollections.Map0.instance(); + return ImmutableCollections.emptyMap(); } /** @@ -1604,11 +1604,11 @@ @SuppressWarnings("varargs") static Map ofEntries(Entry... entries) { if (entries.length == 0) { // implicit null check of entries array - return ImmutableCollections.Map0.instance(); + return ImmutableCollections.emptyMap(); } else if (entries.length == 1) { // implicit null check of the array slot return new ImmutableCollections.Map1<>(entries[0].getKey(), - entries[0].getValue()); + entries[0].getValue()); } else { Object[] kva = new Object[entries.length << 1]; int a = 0; diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/util/Scanner.java --- a/src/java.base/share/classes/java/util/Scanner.java Fri Mar 23 18:01:52 2018 +0000 +++ b/src/java.base/share/classes/java/util/Scanner.java Fri Mar 23 18:44:47 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, 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 @@ -2897,7 +2897,7 @@ * letters: * *
{@code
-     * try (Scanner sc = new Scanner(Paths.get("input.txt"))) {
+     * try (Scanner sc = new Scanner(Path.of("input.txt"))) {
      *     Pattern pat = Pattern.compile("[A-Z]{7,}");
      *     List capWords = sc.findAll(pat)
      *                               .map(MatchResult::group)
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/java/util/Set.java
--- a/src/java.base/share/classes/java/util/Set.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/java/util/Set.java	Fri Mar 23 18:44:47 2018 +0000
@@ -449,7 +449,7 @@
      * @since 9
      */
     static  Set of() {
-        return ImmutableCollections.Set0.instance();
+        return ImmutableCollections.emptySet();
     }
 
     /**
@@ -464,7 +464,7 @@
      * @since 9
      */
     static  Set of(E e1) {
-        return new ImmutableCollections.Set1<>(e1);
+        return new ImmutableCollections.Set12<>(e1);
     }
 
     /**
@@ -481,7 +481,7 @@
      * @since 9
      */
     static  Set of(E e1, E e2) {
-        return new ImmutableCollections.Set2<>(e1, e2);
+        return new ImmutableCollections.Set12<>(e1, e2);
     }
 
     /**
@@ -692,11 +692,11 @@
     static  Set of(E... elements) {
         switch (elements.length) { // implicit null check of elements
             case 0:
-                return ImmutableCollections.Set0.instance();
+                return ImmutableCollections.emptySet();
             case 1:
-                return new ImmutableCollections.Set1<>(elements[0]);
+                return new ImmutableCollections.Set12<>(elements[0]);
             case 2:
-                return new ImmutableCollections.Set2<>(elements[0], elements[1]);
+                return new ImmutableCollections.Set12<>(elements[0], elements[1]);
             default:
                 return new ImmutableCollections.SetN<>(elements);
         }
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/jdk/internal/loader/BootLoader.java
--- a/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -32,7 +32,6 @@
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Arrays;
@@ -243,8 +242,8 @@
                 mn = location.substring(5, location.length());
             } else if (location.startsWith("file:/")) {
                 // named module in exploded image
-                Path path = Paths.get(URI.create(location));
-                Path modulesDir = Paths.get(JAVA_HOME, "modules");
+                Path path = Path.of(URI.create(location));
+                Path modulesDir = Path.of(JAVA_HOME, "modules");
                 if (path.startsWith(modulesDir)) {
                     mn = path.getFileName().toString();
                 }
@@ -267,7 +266,7 @@
         private static URL toFileURL(String location) {
             return AccessController.doPrivileged(new PrivilegedAction<>() {
                 public URL run() {
-                    Path path = Paths.get(location);
+                    Path path = Path.of(location);
                     if (Files.isRegularFile(path)) {
                         try {
                             return path.toUri().toURL();
@@ -285,7 +284,7 @@
         private static Manifest getManifest(String location) {
             return AccessController.doPrivileged(new PrivilegedAction<>() {
                 public Manifest run() {
-                    Path jar = Paths.get(location);
+                    Path jar = Path.of(location);
                     try (InputStream in = Files.newInputStream(jar);
                          JarInputStream jis = new JarInputStream(in, false)) {
                         return jis.getManifest();
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java
--- a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -28,7 +28,7 @@
 import java.io.IOException;
 import java.net.URL;
 import java.nio.file.InvalidPathException;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.security.CodeSource;
 import java.security.PermissionCollection;
 import java.util.jar.Manifest;
@@ -223,7 +223,7 @@
             // Use an intermediate File object to construct a URI/URL without
             // authority component as URLClassPath can't handle URLs with a UNC
             // server name in the authority component.
-            return Paths.get(s).toRealPath().toFile().toURI().toURL();
+            return Path.of(s).toRealPath().toFile().toURI().toURL();
         } catch (InvalidPathException | IOException ignore) {
             // malformed path string or class path element does not exist
             return null;
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java
--- a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -34,7 +34,6 @@
 import java.lang.module.ResolvedModule;
 import java.net.URI;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -539,7 +538,7 @@
             Path[] paths = new Path[dirs.length];
             int i = 0;
             for (String dir: dirs) {
-                paths[i++] = Paths.get(dir);
+                paths[i++] = Path.of(dir);
             }
             return ModulePath.of(patcher, paths);
         }
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java
--- a/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -30,7 +30,6 @@
 import java.lang.module.ResolvedModule;
 import java.net.URI;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.ArrayDeque;
 import java.util.Collections;
 import java.util.Deque;
@@ -129,7 +128,7 @@
             () -> new InternalError("Selected module " + name + " not on module path"));
 
         URI uri = rm.reference().location().get();
-        Path path = Paths.get(uri);
+        Path path = Path.of(uri);
         String fn = path.getFileName().toString();
         if (!fn.endsWith(".jar") && !fn.endsWith(".jmod")) {
             throw new UnsupportedOperationException(path + " is not a modular JAR or jmod file");
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/jdk/internal/module/ModulePath.java
--- a/src/java.base/share/classes/jdk/internal/module/ModulePath.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/ModulePath.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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,6 @@
 import java.nio.file.Files;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -360,7 +359,7 @@
         URI uri = mref.location().orElse(null);
         if (uri != null) {
             if (uri.getScheme().equalsIgnoreCase("file")) {
-                Path file = Paths.get(uri);
+                Path file = Path.of(uri);
                 return file.getFileName().toString();
             } else {
                 return uri.toString();
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/jdk/internal/module/SystemModuleFinders.java
--- a/src/java.base/share/classes/jdk/internal/module/SystemModuleFinders.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/SystemModuleFinders.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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,6 @@
 import java.nio.ByteBuffer;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayDeque;
@@ -185,7 +184,7 @@
 
         // probe to see if this is an images build
         String home = System.getProperty("java.home");
-        Path modules = Paths.get(home, "lib", "modules");
+        Path modules = Path.of(home, "lib", "modules");
         if (Files.isRegularFile(modules)) {
             if (USE_FAST_PATH) {
                 SystemModules systemModules = allSystemModules();
@@ -205,7 +204,7 @@
         }
 
         // exploded build (do not cache module finder)
-        Path dir = Paths.get(home, "modules");
+        Path dir = Path.of(home, "modules");
         if (!Files.isDirectory(dir))
             throw new InternalError("Unable to detect the run-time image");
         ModuleFinder f = ModulePath.of(ModuleBootstrap.patcher(), dir);
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/jdk/internal/perf/PerfCounter.java
--- a/src/java.base/share/classes/jdk/internal/perf/PerfCounter.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/jdk/internal/perf/PerfCounter.java	Fri Mar 23 18:44:47 2018 +0000
@@ -133,10 +133,6 @@
         static final PerfCounter zfot  = newPerfCounter("sun.zip.zipFile.openTime");
     }
 
-    static class WindowsClientCounters {
-        static final PerfCounter d3dAvailable = newConstantPerfCounter("sun.java2d.d3d.available");
-    }
-
     /**
      * Number of findClass calls
      */
@@ -182,10 +178,4 @@
         return CoreCounters.zfot;
     }
 
-    /**
-     * D3D graphic pipeline available
-     */
-    public static PerfCounter getD3DAvailable() {
-        return WindowsClientCounters.d3dAvailable;
-    }
 }
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/module-info.java
--- a/src/java.base/share/classes/module-info.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/module-info.java	Fri Mar 23 18:44:47 2018 +0000
@@ -159,8 +159,6 @@
         jdk.scripting.nashorn;
     exports jdk.internal.org.objectweb.asm.signature to
         jdk.scripting.nashorn;
-    exports jdk.internal.math to
-        java.desktop;
     exports jdk.internal.misc to
         java.desktop,
         java.logging,
@@ -188,7 +186,6 @@
         jdk.jartool,
         jdk.jlink;
     exports jdk.internal.perf to
-        java.desktop,
         java.management,
         jdk.management.agent,
         jdk.internal.jvmstat;
@@ -235,7 +232,6 @@
         jdk.sctp,
         jdk.unsupported;
     exports sun.nio.cs to
-        java.desktop,
         jdk.charsets;
     exports sun.nio.fs to
         jdk.unsupported;
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Fri Mar 23 18:44:47 2018 +0000
@@ -508,8 +508,7 @@
                 if (remote != null) {
                     // connected
                     if (!target.equals(remote)) {
-                        throw new IllegalArgumentException(
-                            "Connected address not equal to target address");
+                        throw new AlreadyConnectedException();
                     }
                     do {
                         n = IOUtil.write(fd, src, -1, nd);
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/sun/nio/ch/IOUtil.java
--- a/src/java.base/share/classes/sun/nio/ch/IOUtil.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/IOUtil.java	Fri Mar 23 18:44:47 2018 +0000
@@ -397,7 +397,9 @@
      * The read end of the pipe is returned in the high 32 bits,
      * while the write end is returned in the low 32 bits.
      */
-    static native long makePipe(boolean blocking);
+    static native long makePipe(boolean blocking) throws IOException;
+
+    static native int write1(int fd, byte b) throws IOException;
 
     static native boolean drain(int fd) throws IOException;
 
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java	Fri Mar 23 18:44:47 2018 +0000
@@ -33,10 +33,10 @@
 
 
 /**
- * An implementation of SelectionKey for Solaris.
+ * An implementation of SelectionKey.
  */
 
-public class SelectionKeyImpl
+public final class SelectionKeyImpl
     extends AbstractSelectionKey
 {
 
@@ -54,12 +54,14 @@
         selector = sel;
     }
 
+    @Override
     public SelectableChannel channel() {
         return (SelectableChannel)channel;
     }
 
+    @Override
     public Selector selector() {
-        return selector;
+        return (Selector)selector;
     }
 
     int getIndex() {                                    // package-private
@@ -75,16 +77,19 @@
             throw new CancelledKeyException();
     }
 
+    @Override
     public int interestOps() {
         ensureValid();
         return interestOps;
     }
 
+    @Override
     public SelectionKey interestOps(int ops) {
         ensureValid();
         return nioInterestOps(ops);
     }
 
+    @Override
     public int readyOps() {
         ensureValid();
         return readyOps;
@@ -131,4 +136,6 @@
         return sb.toString();
     }
 
+    // used by Selector implementations to record when the key was selected
+    int lastPolled;
 }
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/sun/nio/ch/SelectorImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java	Fri Mar 23 18:44:47 2018 +0000
@@ -78,6 +78,16 @@
         return publicSelectedKeys;
     }
 
+    /**
+     * Returns the public view of the key sets
+     */
+    protected final Set nioKeys() {
+        return publicKeys;
+    }
+    protected final Set nioSelectedKeys() {
+        return publicSelectedKeys;
+    }
+
     protected abstract int doSelect(long timeout) throws IOException;
 
     private int lockAndDoSelect(long timeout) throws IOException {
@@ -125,8 +135,6 @@
 
     protected abstract void implClose() throws IOException;
 
-    public abstract void putEventOps(SelectionKeyImpl sk, int ops);
-
     @Override
     protected final SelectionKey register(AbstractSelectableChannel ch,
                                           int ops,
@@ -166,4 +174,9 @@
             }
         }
     }
+
+    /**
+     * Invoked to change the key's interest set
+     */
+    public abstract void putEventOps(SelectionKeyImpl ski, int ops);
 }
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Fri Mar 23 18:44:47 2018 +0000
@@ -210,25 +210,20 @@
 
     @Override
     public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException {
-        acceptLock.lock();
-        try {
-            synchronized (stateLock) {
-                ensureOpen();
-                if (localAddress != null)
-                    throw new AlreadyBoundException();
-                InetSocketAddress isa = (local == null)
-                                        ? new InetSocketAddress(0)
-                                        : Net.checkAddress(local);
-                SecurityManager sm = System.getSecurityManager();
-                if (sm != null)
-                    sm.checkListen(isa.getPort());
-                NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
-                Net.bind(fd, isa.getAddress(), isa.getPort());
-                Net.listen(fd, backlog < 1 ? 50 : backlog);
-                localAddress = Net.localAddress(fd);
-            }
-        } finally {
-            acceptLock.unlock();
+        synchronized (stateLock) {
+            ensureOpen();
+            if (localAddress != null)
+                throw new AlreadyBoundException();
+            InetSocketAddress isa = (local == null)
+                                    ? new InetSocketAddress(0)
+                                    : Net.checkAddress(local);
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null)
+                sm.checkListen(isa.getPort());
+            NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
+            Net.bind(fd, isa.getAddress(), isa.getPort());
+            Net.listen(fd, backlog < 1 ? 50 : backlog);
+            localAddress = Net.localAddress(fd);
         }
         return this;
     }
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/sun/security/provider/PolicyFile.java
--- a/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Fri Mar 23 18:44:47 2018 +0000
@@ -30,7 +30,7 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URI;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.*;
 import java.security.*;
 import java.security.cert.Certificate;
@@ -278,7 +278,7 @@
             public URL run() {
                 String sep = File.separator;
                 try {
-                    return Paths.get(System.getProperty("java.home"),
+                    return Path.of(System.getProperty("java.home"),
                                      "lib", "security",
                                      "default.policy").toUri().toURL();
                 } catch (MalformedURLException mue) {
diff -r eb72d194235c -r 514c68575523 src/java.base/share/classes/sun/security/tools/keytool/Main.java
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Fri Mar 23 18:44:47 2018 +0000
@@ -27,7 +27,7 @@
 
 import java.io.*;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.security.CodeSigner;
 import java.security.CryptoPrimitive;
 import java.security.KeyStore;
@@ -2189,7 +2189,7 @@
                 inplaceBackupName = srcksfname + ".old" + (n == 1 ? "" : n);
                 File bkFile = new File(inplaceBackupName);
                 if (!bkFile.exists()) {
-                    Files.copy(Paths.get(srcksfname), bkFile.toPath());
+                    Files.copy(Path.of(srcksfname), bkFile.toPath());
                     break;
                 }
             }
diff -r eb72d194235c -r 514c68575523 src/java.base/share/native/libjava/System.c
--- a/src/java.base/share/native/libjava/System.c	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/share/native/libjava/System.c	Fri Mar 23 18:44:47 2018 +0000
@@ -244,21 +244,8 @@
     PUTPROP(props, "line.separator", sprops->line_separator);
 
     /*
-     *  user.language
-     *  user.script, user.country, user.variant (if user's environment specifies them)
-     *  file.encoding
+     * file encoding for stdout and stderr
      */
-    PUTPROP(props, "user.language", sprops->language);
-    if (sprops->script) {
-        PUTPROP(props, "user.script", sprops->script);
-    }
-    if (sprops->country) {
-        PUTPROP(props, "user.country", sprops->country);
-    }
-    if (sprops->variant) {
-        PUTPROP(props, "user.variant", sprops->variant);
-    }
-    PUTPROP(props, "file.encoding", sprops->encoding);
     if (sprops->sun_stdout_encoding != NULL) {
         PUTPROP(props, "sun.stdout.encoding", sprops->sun_stdout_encoding);
     }
@@ -314,7 +301,7 @@
 #endif
 
     /* !!! DO NOT call PUTPROP_ForPlatformNString before this line !!!
-     * !!! I18n properties have not been set up yet !!!
+     * !!! The platform native encoding for strings has not been set up yet !!!
      */
     InitializeEncoding(env, sprops->sun_jnu_encoding);
 
@@ -379,17 +366,6 @@
         PUTPROP(props, "sun.desktop", sprops->desktop);
     }
 
-    /*
-     * unset "user.language", "user.script", "user.country", and "user.variant"
-     * in order to tell whether the command line option "-DXXXX=YYYY" is
-     * specified or not.  They will be reset in fillI18nProps() below.
-     */
-    REMOVEPROP(props, "user.language");
-    REMOVEPROP(props, "user.script");
-    REMOVEPROP(props, "user.country");
-    REMOVEPROP(props, "user.variant");
-    REMOVEPROP(props, "file.encoding");
-
     ret = JVM_InitProperties(env, props);
 
     /* reconstruct i18n related properties */
diff -r eb72d194235c -r 514c68575523 src/java.base/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java
--- a/src/java.base/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java	Fri Mar 23 18:44:47 2018 +0000
@@ -127,7 +127,7 @@
     // descriptor is registered with /dev/poll.
     private final BitSet registered = new BitSet();
 
-    DevPollArrayWrapper() {
+    DevPollArrayWrapper() throws IOException {
         int allocationSize = NUM_POLLFDS * SIZE_POLLFD;
         pollArray = new AllocatedNativeObject(allocationSize, true);
         pollArrayAddress = pollArray.address();
@@ -136,7 +136,7 @@
             eventsHigh = new HashMap<>();
     }
 
-    void initInterrupt(int fd0, int fd1) {
+    void initInterrupt(int fd0, int fd1) throws IOException {
         outgoingInterruptFD = fd1;
         incomingInterruptFD = fd0;
         register(wfd, fd0, POLLIN);
@@ -200,7 +200,7 @@
         }
     }
 
-    void release(int fd) {
+    void release(int fd) throws IOException {
         synchronized (updateLock) {
             // ignore any pending update for this file descriptor
             setUpdateEvents(fd, IGNORE);
@@ -297,7 +297,11 @@
     boolean interrupted = false;
 
     public void interrupt() {
-        interrupt(outgoingInterruptFD);
+        try {
+            IOUtil.write1(outgoingInterruptFD, (byte)0);
+        } catch (IOException ioe) {
+            throw new InternalError(ioe);
+        }
     }
 
     public int interruptedIndex() {
@@ -312,13 +316,12 @@
         interrupted = false;
     }
 
-    private native int init();
-    private native void register(int wfd, int fd, int mask);
+    private native int init() throws IOException;
+    private native void register(int wfd, int fd, int mask) throws IOException;
     private native void registerMultiple(int wfd, long address, int len)
         throws IOException;
-    private native int poll0(long pollAddress, int numfds, long timeout,
-                             int wfd);
-    private static native void interrupt(int fd);
+    private native int poll0(long pollAddress, int numfds, long timeout, int wfd)
+        throws IOException;
 
     static {
         IOUtil.load();
diff -r eb72d194235c -r 514c68575523 src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java
--- a/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java	Fri Mar 23 18:44:47 2018 +0000
@@ -61,7 +61,7 @@
      * Package private constructor called by factory method in
      * the abstract superclass Selector.
      */
-    DevPollSelectorImpl(SelectorProvider sp) {
+    DevPollSelectorImpl(SelectorProvider sp) throws IOException {
         super(sp);
         long pipeFds = IOUtil.makePipe(false);
         fd0 = (int) (pipeFds >>> 32);
diff -r eb72d194235c -r 514c68575523 src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java
--- a/src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, 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
@@ -181,12 +181,26 @@
         }
 
         // poll for events
-        int updated = port_getn(pfd, pollArrayAddress, POLL_MAX, timeout);
+        int numEntries;
+        long to = timeout;
+        boolean timedPoll = (to > 0);
+        do {
+            long startTime = timedPoll ? System.currentTimeMillis() : 0;
+            numEntries = port_getn(pfd, pollArrayAddress, POLL_MAX, timeout);
+            if (numEntries == IOStatus.INTERRUPTED && timedPoll) {
+                // timed poll interrupted so need to adjust timeout
+                to -= System.currentTimeMillis() - startTime;
+                if (to <= 0) {
+                    // timeout also expired so no retry
+                    numEntries = 0;
+                }
+            }
+        } while (numEntries == IOStatus.INTERRUPTED);
 
         // after polling we need to queue all polled file descriptors as they
         // are candidates to register for the next poll.
         synchronized (updateLock) {
-            for (int i=0; i
+#include 
+#include 
+#include 
+
 #include "jni.h"
 #include "jni_util.h"
 #include "jvm.h"
 #include "jlong.h"
+#include "nio.h"
 #include "nio_util.h"
 
-#include 
-#include 
-#include 
-#include 
-
 #include "sun_nio_ch_SolarisEventPort.h"
 
 JNIEXPORT jint JNICALL
@@ -51,8 +52,10 @@
 Java_sun_nio_ch_SolarisEventPort_port_1close
     (JNIEnv* env, jclass clazz, jint port)
 {
-    int res;
-    RESTARTABLE(close(port), res);
+    int res = close(port);
+    if (res < 0 && res != EINTR) {
+        JNU_ThrowIOExceptionWithLastError(env, "close failed");
+    }
 }
 
 JNIEXPORT jboolean JNICALL
@@ -93,17 +96,23 @@
     }
 }
 
-JNIEXPORT void JNICALL
+JNIEXPORT jint JNICALL
 Java_sun_nio_ch_SolarisEventPort_port_1get(JNIEnv* env, jclass clazz,
     jint port, jlong eventAddress)
 {
     int res;
     port_event_t* ev = (port_event_t*)jlong_to_ptr(eventAddress);
 
-    RESTARTABLE(port_get((int)port, ev, NULL), res);
+    res = port_get((int)port, ev, NULL);
     if (res == -1) {
-        JNU_ThrowIOExceptionWithLastError(env, "port_get");
+        if (errno == EINTR) {
+            return IOS_INTERRUPTED;
+        } else {
+            JNU_ThrowIOExceptionWithLastError(env, "port_get failed");
+            return IOS_THROWN;
+        }
     }
+    return res;
 }
 
 JNIEXPORT jint JNICALL
@@ -125,9 +134,13 @@
     }
 
     res = port_getn((int)port, list, (uint_t)max, &n, tsp);
-    if (res == -1) {
-        if (errno != ETIME && errno != EINTR)
-            JNU_ThrowIOExceptionWithLastError(env, "port_getn");
+    if (res == -1 && errno != ETIME) {
+        if (errno == EINTR) {
+            return IOS_INTERRUPTED;
+        } else {
+            JNU_ThrowIOExceptionWithLastError(env, "port_getn failed");
+            return IOS_THROWN;
+        }
     }
 
     return (jint)n;
diff -r eb72d194235c -r 514c68575523 src/java.base/unix/classes/module-info.java.extra
--- a/src/java.base/unix/classes/module-info.java.extra	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/unix/classes/module-info.java.extra	Fri Mar 23 18:44:47 2018 +0000
@@ -23,3 +23,4 @@
  * questions.
  */
 
+exports sun.nio.cs to java.desktop;
diff -r eb72d194235c -r 514c68575523 src/java.base/unix/classes/sun/nio/ch/PipeImpl.java
--- a/src/java.base/unix/classes/sun/nio/ch/PipeImpl.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/unix/classes/sun/nio/ch/PipeImpl.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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 @@
     private final SourceChannel source;
     private final SinkChannel sink;
 
-    PipeImpl(SelectorProvider sp) {
+    PipeImpl(SelectorProvider sp) throws IOException {
         long pipeFds = IOUtil.makePipe(true);
         int readFd = (int) (pipeFds >>> 32);
         int writeFd = (int) pipeFds;
diff -r eb72d194235c -r 514c68575523 src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java
--- a/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -51,7 +51,7 @@
      * Package private constructor called by factory method in
      * the abstract superclass Selector.
      */
-    PollSelectorImpl(SelectorProvider sp) {
+    PollSelectorImpl(SelectorProvider sp) throws IOException {
         super(sp, 1, 1);
         long pipeFds = IOUtil.makePipe(false);
         fd0 = (int) (pipeFds >>> 32);
diff -r eb72d194235c -r 514c68575523 src/java.base/unix/classes/sun/nio/ch/SocketDispatcher.java
--- a/src/java.base/unix/classes/sun/nio/ch/SocketDispatcher.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/unix/classes/sun/nio/ch/SocketDispatcher.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,15 @@
 
 package sun.nio.ch;
 
-import java.io.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
 
 /**
  * Allows different platforms to call different native methods
  * for read and write operations.
  */
 
-class SocketDispatcher extends NativeDispatcher
-{
+class SocketDispatcher extends NativeDispatcher {
 
     int read(FileDescriptor fd, long address, int len) throws IOException {
         return FileDispatcherImpl.read0(fd, address, len);
diff -r eb72d194235c -r 514c68575523 src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java
--- a/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -260,7 +260,7 @@
     private static Properties loadProperties() {
         Properties result = new Properties();
         String fstypes = System.getProperty("java.home") + "/lib/fstypes.properties";
-        Path file = Paths.get(fstypes);
+        Path file = Path.of(fstypes);
         try {
             try (ReadableByteChannel rbc = Files.newByteChannel(file)) {
                 result.load(Channels.newReader(rbc, "UTF-8"));
diff -r eb72d194235c -r 514c68575523 src/java.base/unix/native/libnio/ch/IOUtil.c
--- a/src/java.base/unix/native/libnio/ch/IOUtil.c	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.base/unix/native/libnio/ch/IOUtil.c	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -104,10 +104,19 @@
     return ((jlong) fd[0] << 32) | (jlong) fd[1];
 }
 
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_IOUtil_write1(JNIEnv *env, jclass cl, jint fd, jbyte b)
+{
+    char c = (char)b;
+    return convertReturnVal(env, write(fd, &c, 1), JNI_FALSE);
+}
+
+
 JNIEXPORT jboolean JNICALL
 Java_sun_nio_ch_IOUtil_drain(JNIEnv *env, jclass cl, jint fd)
 {
-    char buf[128];
+    char buf[16];
     int tn = 0;
 
     for (;;) {
diff -r eb72d194235c -r 514c68575523 src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+//#define USE_ERROR
+//#define USE_TRACE
+
+#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
+
+static void alsaDebugOutput(const char *file, int line, const char *function, int err, const char *fmt, ...) {
+#ifdef USE_ERROR
+    va_list args;
+    va_start(args, fmt);
+    printf("%s:%d function %s: error %d: %s\n", file, line, function, err, snd_strerror(err));
+    if (strlen(fmt) > 0) {
+        vprintf(fmt, args);
+    }
+    va_end(args);
+#endif
+}
+
+static int alsa_inited = 0;
+static int alsa_enumerate_pcm_subdevices = FALSE; // default: no
+static int alsa_enumerate_midi_subdevices = FALSE; // default: no
+
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+void initAlsaSupport() {
+    char* enumerate;
+    if (!alsa_inited) {
+        alsa_inited = TRUE;
+        snd_lib_error_set_handler(&alsaDebugOutput);
+
+        enumerate = getenv(ENV_ENUMERATE_PCM_SUBDEVICES);
+        if (enumerate != NULL && strlen(enumerate) > 0
+            && (enumerate[0] != 'f')   // false
+            && (enumerate[0] != 'F')   // False
+            && (enumerate[0] != 'n')   // no
+            && (enumerate[0] != 'N')) { // NO
+            alsa_enumerate_pcm_subdevices = TRUE;
+        }
+#ifdef ALSA_MIDI_ENUMERATE_SUBDEVICES
+        alsa_enumerate_midi_subdevices = TRUE;
+#endif
+    }
+}
+
+
+/* if true (non-zero), ALSA sub devices should be listed as separate devices
+ */
+int needEnumerateSubdevices(int isMidi) {
+    initAlsaSupport();
+    return isMidi ? alsa_enumerate_midi_subdevices
+                  : alsa_enumerate_pcm_subdevices;
+}
+
+
+/*
+ * deviceID contains packed card, device and subdevice numbers
+ * each number takes 10 bits
+ * "default" device has id == ALSA_DEFAULT_DEVICE_ID
+ */
+UINT32 encodeDeviceID(int card, int device, int subdevice) {
+    return (((card & 0x3FF) << 20) | ((device & 0x3FF) << 10)
+           | (subdevice & 0x3FF)) + 1;
+}
+
+
+void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
+                    int isMidi) {
+    deviceID--;
+    *card = (deviceID >> 20) & 0x3FF;
+    *device = (deviceID >> 10) & 0x3FF;
+    if (needEnumerateSubdevices(isMidi)) {
+        *subdevice = deviceID  & 0x3FF;
+    } else {
+        *subdevice = -1; // ALSA will choose any subdevices
+    }
+}
+
+
+void getDeviceString(char* buffer, int card, int device, int subdevice,
+                     int usePlugHw, int isMidi) {
+    if (needEnumerateSubdevices(isMidi)) {
+        sprintf(buffer, "%s:%d,%d,%d",
+                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
+                        card, device, subdevice);
+    } else {
+        sprintf(buffer, "%s:%d,%d",
+                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
+                        card, device);
+    }
+}
+
+
+void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
+                                 int usePlugHw, int isMidi) {
+    int card, device, subdevice;
+
+    if (deviceID == ALSA_DEFAULT_DEVICE_ID) {
+        strcpy(buffer, ALSA_DEFAULT_DEVICE_NAME);
+    } else {
+        decodeDeviceID(deviceID, &card, &device, &subdevice, isMidi);
+        getDeviceString(buffer, card, device, subdevice, usePlugHw, isMidi);
+    }
+}
+
+
+static int hasGottenALSAVersion = FALSE;
+#define ALSAVersionString_LENGTH 200
+static char ALSAVersionString[ALSAVersionString_LENGTH];
+
+void getALSAVersion(char* buffer, int len) {
+    if (!hasGottenALSAVersion) {
+        // get alsa version from proc interface
+        FILE* file;
+        int curr, len, totalLen, inVersionString;
+        file = fopen(ALSA_VERSION_PROC_FILE, "r");
+        ALSAVersionString[0] = 0;
+        if (file) {
+            if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) {
+                // parse for version number
+                totalLen = strlen(ALSAVersionString);
+                inVersionString = FALSE;
+                len = 0;
+                curr = 0;
+                while (curr < totalLen) {
+                    if (!inVersionString) {
+                        // is this char the beginning of a version string ?
+                        if (ALSAVersionString[curr] >= '0'
+                            && ALSAVersionString[curr] <= '9') {
+                            inVersionString = TRUE;
+                        }
+                    }
+                    if (inVersionString) {
+                        // the version string ends with white space
+                        if (ALSAVersionString[curr] <= 32) {
+                            break;
+                        }
+                        if (curr != len) {
+                            // copy this char to the beginning of the string
+                            ALSAVersionString[len] = ALSAVersionString[curr];
+                        }
+                        len++;
+                    }
+                    curr++;
+                }
+                // remove trailing dots
+                while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
+                    len--;
+                }
+                // null terminate
+                ALSAVersionString[len] = 0;
+            }
+            fclose(file);
+            hasGottenALSAVersion = TRUE;
+        }
+    }
+    strncpy(buffer, ALSAVersionString, len);
+}
+
+
+/* end */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2003, 2007, 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 
+#include "Utilities.h"
+
+#ifndef PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
+#define PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
+
+#define ALSA_VERSION_PROC_FILE "/proc/asound/version"
+#define ALSA_HARDWARE "hw"
+#define ALSA_HARDWARE_CARD ALSA_HARDWARE":%d"
+#define ALSA_HARDWARE_DEVICE ALSA_HARDWARE_CARD",%d"
+#define ALSA_HARDWARE_SUBDEVICE ALSA_HARDWARE_DEVICE",%d"
+
+#define ALSA_PLUGHARDWARE "plughw"
+#define ALSA_DEFAULT_DEVICE_NAME "default"
+
+#define ALSA_DEFAULT_DEVICE_ID (0)
+
+#define ALSA_PCM     (0)
+#define ALSA_RAWMIDI (1)
+
+// for use in info objects
+#define ALSA_VENDOR "ALSA (http://www.alsa-project.org)"
+
+// Environment variable for inclusion of subdevices in device listing.
+// If this variable is unset or "no", then subdevices are ignored, and
+// it's ALSA's choice which one to use (enables hardware mixing)
+#define ENV_ENUMERATE_PCM_SUBDEVICES "ALSA_ENUMERATE_PCM_SUBDEVICES"
+
+// if defined, subdevices are listed.
+//#undef ALSA_MIDI_ENUMERATE_SUBDEVICES
+#define ALSA_MIDI_ENUMERATE_SUBDEVICES
+
+// must be called before any ALSA calls
+void initAlsaSupport();
+
+/* if true (non-zero), ALSA sub devices should be listed as separate devices
+ */
+int needEnumerateSubdevices(int isMidi);
+
+
+/*
+ * deviceID contains packed card, device and subdevice numbers
+ * each number takes 10 bits
+ * "default" device has id == ALSA_DEFAULT_DEVICE_ID
+ */
+UINT32 encodeDeviceID(int card, int device, int subdevice);
+
+void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
+                    int isMidi);
+
+void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
+                                 int usePlugHw, int isMidi);
+
+void getALSAVersion(char* buffer, int len);
+
+
+#endif // PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2003, 2010, 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.
+ */
+
+#define USE_ERROR
+#define USE_TRACE
+
+#if USE_PLATFORM_MIDI_IN == TRUE
+
+
+#include 
+#include "PlatformMidi.h"
+#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
+#if defined(i586)
+#include 
+#endif
+
+/*
+ * Helper methods
+ */
+
+static inline UINT32 packMessage(int status, int data1, int data2) {
+    return ((status & 0xFF) | ((data1 & 0xFF) << 8) | ((data2 & 0xFF) << 16));
+}
+
+
+static void setShortMessage(MidiMessage* message,
+                            int status, int data1, int data2) {
+    message->type = SHORT_MESSAGE;
+    message->data.s.packedMsg = packMessage(status, data1, data2);
+}
+
+
+static void setRealtimeMessage(MidiMessage* message, int status) {
+    setShortMessage(message, status, 0, 0);
+}
+
+
+static void set14bitMessage(MidiMessage* message, int status, int value) {
+    TRACE3("14bit value: %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
+    value &= 0x3FFF;
+    TRACE3("14bit value (2): %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
+    setShortMessage(message, status,
+                    value & 0x7F,
+                    (value >> 7) & 0x7F);
+}
+
+
+/*
+ * implementation of the platform-dependent
+ * MIDI in functions declared in PlatformMidi.h
+ */
+
+char* MIDI_IN_GetErrorStr(INT32 err) {
+    return (char*) getErrorStr(err);
+}
+
+INT32 MIDI_IN_GetNumDevices() {
+/* Workaround for 6842956: 32bit app on 64bit linux
+ * gets assertion failure trying to open midiIn ports.
+ * Untill the issue is fixed in ALSA
+ * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807)
+ * report no midi in devices in the configuration.
+ */
+#if defined(i586)
+    static int jre32onlinux64 = -1;
+    if (jre32onlinux64 < 0) {
+        jre32onlinux64 = 0;
+        /* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN"
+         * environment variable.
+         */
+        if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) {
+            struct utsname u;
+            jre32onlinux64 = 0;
+            if (uname(&u) == 0) {
+                if (strstr(u.machine, "64") != NULL) {
+                    TRACE0("jre32 on linux64 detected - report no midiIn devices\n");
+                    jre32onlinux64 = 1;
+                }
+            }
+        }
+    }
+    if (jre32onlinux64) {
+        return 0;
+    }
+#endif
+
+    TRACE0("MIDI_IN_GetNumDevices()\n");
+
+    return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT);
+}
+
+
+INT32 MIDI_IN_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    int ret = getMidiDeviceName(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
+                                name, nameLength);
+    return ret;
+}
+
+
+INT32 MIDI_IN_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    int ret = getMidiDeviceVendor(deviceIndex, name, nameLength);
+    return ret;
+}
+
+
+INT32 MIDI_IN_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    int ret = getMidiDeviceDescription(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
+                                       name, nameLength);
+    return ret;
+}
+
+
+INT32 MIDI_IN_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    int ret = getMidiDeviceVersion(deviceIndex, name, nameLength);
+    return ret;
+}
+
+/*************************************************************************/
+
+INT32 MIDI_IN_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
+    INT32 ret;
+    TRACE0("> MIDI_IN_OpenDevice\n");
+    ret = openMidiDevice(SND_RAWMIDI_STREAM_INPUT, deviceIndex, handle);
+    TRACE1("< MIDI_IN_OpenDevice: returning %d\n", (int) ret);
+    return ret;
+}
+
+
+INT32 MIDI_IN_CloseDevice(MidiDeviceHandle* handle) {
+    INT32 ret;
+    TRACE0("> MIDI_IN_CloseDevice\n");
+    ret = closeMidiDevice(handle);
+    TRACE1("< MIDI_IN_CloseDevice: returning %d\n", (int) ret);
+    return ret;
+}
+
+
+INT32 MIDI_IN_StartDevice(MidiDeviceHandle* handle) {
+    TRACE0("MIDI_IN_StartDevice\n");
+    return MIDI_SUCCESS;
+}
+
+
+INT32 MIDI_IN_StopDevice(MidiDeviceHandle* handle) {
+    TRACE0("MIDI_IN_StopDevice\n");
+    return MIDI_SUCCESS;
+}
+
+
+INT64 MIDI_IN_GetTimeStamp(MidiDeviceHandle* handle) {
+    return getMidiTimestamp(handle);
+}
+
+
+/* read the next message from the queue */
+MidiMessage* MIDI_IN_GetMessage(MidiDeviceHandle* handle) {
+    snd_seq_event_t alsa_message;
+    MidiMessage* jdk_message;
+    int err;
+    char buffer[1];
+    int status;
+
+    TRACE0("> MIDI_IN_GetMessage\n");
+    if (!handle) {
+        ERROR0("< ERROR: MIDI_IN_GetMessage(): handle is NULL\n");
+        return NULL;
+    }
+    if (!handle->deviceHandle) {
+        ERROR0("< ERROR: MIDI_IN_GetMessage(): native handle is NULL\n");
+        return NULL;
+    }
+    if (!handle->platformData) {
+        ERROR0("< ERROR: MIDI_IN_GetMessage(): platformData is NULL\n");
+        return NULL;
+    }
+
+    /* For MIDI In, the device is left in non blocking mode. So if there is
+       no data from the device, snd_rawmidi_read() returns with -11 (EAGAIN).
+       This results in jumping back to the Java layer. */
+    while (TRUE) {
+        TRACE0("before snd_rawmidi_read()\n");
+        err = snd_rawmidi_read((snd_rawmidi_t*) handle->deviceHandle, buffer, 1);
+        TRACE0("after snd_rawmidi_read()\n");
+        if (err != 1) {
+            ERROR2("< ERROR: MIDI_IN_GetMessage(): snd_rawmidi_read() returned %d : %s\n", err, snd_strerror(err));
+            return NULL;
+        }
+        // printf("received byte: %d\n", buffer[0]);
+        err = snd_midi_event_encode_byte((snd_midi_event_t*) handle->platformData,
+                                         (int) buffer[0],
+                                         &alsa_message);
+        if (err == 1) {
+            break;
+        } else if (err < 0) {
+            ERROR1("< ERROR: MIDI_IN_GetMessage(): snd_midi_event_encode_byte() returned %d\n", err);
+            return NULL;
+        }
+    }
+    jdk_message = (MidiMessage*) calloc(sizeof(MidiMessage), 1);
+    if (!jdk_message) {
+        ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
+        return NULL;
+    }
+    // TODO: tra
+    switch (alsa_message.type) {
+    case SND_SEQ_EVENT_NOTEON:
+    case SND_SEQ_EVENT_NOTEOFF:
+    case SND_SEQ_EVENT_KEYPRESS:
+        status = (alsa_message.type == SND_SEQ_EVENT_KEYPRESS) ? 0xA0 :
+            (alsa_message.type == SND_SEQ_EVENT_NOTEON) ? 0x90 : 0x80;
+        status |= alsa_message.data.note.channel;
+        setShortMessage(jdk_message, status,
+                        alsa_message.data.note.note,
+                        alsa_message.data.note.velocity);
+        break;
+
+    case SND_SEQ_EVENT_CONTROLLER:
+        status = 0xB0 | alsa_message.data.control.channel;
+        setShortMessage(jdk_message, status,
+                        alsa_message.data.control.param,
+                        alsa_message.data.control.value);
+        break;
+
+    case SND_SEQ_EVENT_PGMCHANGE:
+    case SND_SEQ_EVENT_CHANPRESS:
+        status = (alsa_message.type == SND_SEQ_EVENT_PGMCHANGE) ? 0xC0 : 0xD0;
+        status |= alsa_message.data.control.channel;
+        setShortMessage(jdk_message, status,
+                        alsa_message.data.control.value, 0);
+        break;
+
+    case SND_SEQ_EVENT_PITCHBEND:
+        status = 0xE0 | alsa_message.data.control.channel;
+        // $$mp 2003-09-23:
+        // possible hack to work around a bug in ALSA. Necessary for
+        // ALSA 0.9.2. May be fixed in newer versions of ALSA.
+        // alsa_message.data.control.value ^= 0x2000;
+        // TRACE1("pitchbend value: %d\n", alsa_message.data.control.value);
+        set14bitMessage(jdk_message, status,
+                        alsa_message.data.control.value);
+        break;
+
+        /* System exclusive messages */
+
+    case SND_SEQ_EVENT_SYSEX:
+        jdk_message->type = LONG_MESSAGE;
+        jdk_message->data.l.size = alsa_message.data.ext.len;
+        jdk_message->data.l.data = malloc(alsa_message.data.ext.len);
+        if (jdk_message->data.l.data == NULL) {
+            ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
+            free(jdk_message);
+            jdk_message = NULL;
+        } else {
+            memcpy(jdk_message->data.l.data, alsa_message.data.ext.ptr, alsa_message.data.ext.len);
+        }
+        break;
+
+        /* System common messages */
+
+    case SND_SEQ_EVENT_QFRAME:
+        setShortMessage(jdk_message, 0xF1,
+                        alsa_message.data.control.value & 0x7F, 0);
+        break;
+
+    case SND_SEQ_EVENT_SONGPOS:
+        set14bitMessage(jdk_message, 0xF2,
+                        alsa_message.data.control.value);
+        break;
+
+    case SND_SEQ_EVENT_SONGSEL:
+        setShortMessage(jdk_message, 0xF3,
+                        alsa_message.data.control.value & 0x7F, 0);
+        break;
+
+    case SND_SEQ_EVENT_TUNE_REQUEST:
+        setRealtimeMessage(jdk_message, 0xF6);
+        break;
+
+        /* System realtime messages */
+
+    case SND_SEQ_EVENT_CLOCK:
+        setRealtimeMessage(jdk_message, 0xF8);
+        break;
+
+    case SND_SEQ_EVENT_START:
+        setRealtimeMessage(jdk_message, 0xFA);
+        break;
+
+    case SND_SEQ_EVENT_CONTINUE:
+        setRealtimeMessage(jdk_message, 0xFB);
+        break;
+
+    case SND_SEQ_EVENT_STOP:
+        setRealtimeMessage(jdk_message, 0xFC);
+        break;
+
+    case SND_SEQ_EVENT_SENSING:
+        setRealtimeMessage(jdk_message, 0xFE);
+        break;
+
+    case SND_SEQ_EVENT_RESET:
+        setRealtimeMessage(jdk_message, 0xFF);
+        break;
+
+    default:
+        ERROR0("< ERROR: MIDI_IN_GetMessage(): unhandled ALSA MIDI message type\n");
+        free(jdk_message);
+        jdk_message = NULL;
+
+    }
+
+    // set timestamp
+    if (jdk_message != NULL) {
+        jdk_message->timestamp = getMidiTimestamp(handle);
+    }
+    TRACE1("< MIDI_IN_GetMessage: returning %p\n", jdk_message);
+    return jdk_message;
+}
+
+
+void MIDI_IN_ReleaseMessage(MidiDeviceHandle* handle, MidiMessage* msg) {
+    if (!msg) {
+        ERROR0("< ERROR: MIDI_IN_ReleaseMessage(): message is NULL\n");
+        return;
+    }
+    if (msg->type == LONG_MESSAGE && msg->data.l.data) {
+        free(msg->data.l.data);
+    }
+    free(msg);
+}
+
+#endif /* USE_PLATFORM_MIDI_IN */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiOut.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiOut.c	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2003, 2007, 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.
+ */
+
+#define USE_ERROR
+#define USE_TRACE
+
+#if USE_PLATFORM_MIDI_OUT == TRUE
+
+#include 
+#include "PlatformMidi.h"
+#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
+
+
+
+static int CHANNEL_MESSAGE_LENGTH[] = {
+    -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 3, 3, 2, 2, 3 };
+/*                                 8x 9x Ax Bx Cx Dx Ex */
+
+static int SYSTEM_MESSAGE_LENGTH[] = {
+    -1, 2, 3, 2, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1 };
+/*  F0 F1 F2 F3  F4  F5 F6 F7 F8  F9 FA FB FC  FD FE FF */
+
+
+// the returned length includes the status byte.
+// for illegal messages, -1 is returned.
+static int getShortMessageLength(int status) {
+        int     dataLength = 0;
+        if (status < 0xF0) { // channel voice message
+                dataLength = CHANNEL_MESSAGE_LENGTH[(status >> 4) & 0xF];
+        } else {
+                dataLength = SYSTEM_MESSAGE_LENGTH[status & 0xF];
+        }
+        return dataLength;
+}
+
+
+/*
+ * implementation of the platform-dependent
+ * MIDI out functions declared in PlatformMidi.h
+ */
+char* MIDI_OUT_GetErrorStr(INT32 err) {
+    return (char*) getErrorStr(err);
+}
+
+
+INT32 MIDI_OUT_GetNumDevices() {
+    TRACE0("MIDI_OUT_GetNumDevices()\n");
+    return getMidiDeviceCount(SND_RAWMIDI_STREAM_OUTPUT);
+}
+
+
+INT32 MIDI_OUT_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    TRACE0("MIDI_OUT_GetDeviceName()\n");
+    return getMidiDeviceName(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
+                             name, nameLength);
+}
+
+
+INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    TRACE0("MIDI_OUT_GetDeviceVendor()\n");
+    return getMidiDeviceVendor(deviceIndex, name, nameLength);
+}
+
+
+INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    TRACE0("MIDI_OUT_GetDeviceDescription()\n");
+    return getMidiDeviceDescription(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
+                                    name, nameLength);
+}
+
+
+INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    TRACE0("MIDI_OUT_GetDeviceVersion()\n");
+    return getMidiDeviceVersion(deviceIndex, name, nameLength);
+}
+
+
+/* *************************** MidiOutDevice implementation *************** */
+
+INT32 MIDI_OUT_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
+    TRACE1("MIDI_OUT_OpenDevice(): deviceIndex: %d\n", (int) deviceIndex);
+    return openMidiDevice(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex, handle);
+}
+
+
+INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle) {
+    TRACE0("MIDI_OUT_CloseDevice()\n");
+    return closeMidiDevice(handle);
+}
+
+
+INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle) {
+    return getMidiTimestamp(handle);
+}
+
+
+INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg,
+                                UINT32 timestamp) {
+    int err;
+    int status;
+    int data1;
+    int data2;
+    char buffer[3];
+
+    TRACE2("> MIDI_OUT_SendShortMessage() %x, time: %u\n", packedMsg, (unsigned int) timestamp);
+    if (!handle) {
+        ERROR0("< ERROR: MIDI_OUT_SendShortMessage(): handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    if (!handle->deviceHandle) {
+        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    status = (packedMsg & 0xFF);
+    buffer[0] = (char) status;
+    buffer[1]  = (char) ((packedMsg >> 8) & 0xFF);
+    buffer[2]  = (char) ((packedMsg >> 16) & 0xFF);
+    TRACE4("status: %d, data1: %d, data2: %d, length: %d\n", (int) buffer[0], (int) buffer[1], (int) buffer[2], getShortMessageLength(status));
+    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle, buffer, getShortMessageLength(status));
+    if (err < 0) {
+        ERROR1("  ERROR: MIDI_OUT_SendShortMessage(): snd_rawmidi_write() returned %d\n", err);
+    }
+
+    TRACE0("< MIDI_OUT_SendShortMessage()\n");
+    return err;
+}
+
+
+INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data,
+                               UINT32 size, UINT32 timestamp) {
+    int err;
+
+    TRACE2("> MIDI_OUT_SendLongMessage() size %u, time: %u\n", (unsigned int) size, (unsigned int) timestamp);
+    if (!handle) {
+        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    if (!handle->deviceHandle) {
+        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    if (!data) {
+        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): data is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle,
+                            data, size);
+    if (err < 0) {
+        ERROR1("  ERROR: MIDI_OUT_SendLongMessage(): snd_rawmidi_write() returned %d\n", err);
+    }
+
+    TRACE0("< MIDI_OUT_SendLongMessage()\n");
+    return err;
+}
+
+
+#endif /* USE_PLATFORM_MIDI_OUT */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,481 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+#define USE_ERROR
+#define USE_TRACE
+
+#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
+#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
+#include 
+#include 
+
+static INT64 getTimeInMicroseconds() {
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    return (tv.tv_sec * 1000000UL) + tv.tv_usec;
+}
+
+
+const char* getErrorStr(INT32 err) {
+        return snd_strerror((int) err);
+}
+
+
+
+// callback for iteration through devices
+// returns TRUE if iteration should continue
+typedef int (*DeviceIteratorPtr)(UINT32 deviceID,
+                                 snd_rawmidi_info_t* rawmidi_info,
+                                 snd_ctl_card_info_t* cardinfo,
+                                 void *userData);
+
+// for each ALSA device, call iterator. userData is passed to the iterator
+// returns total number of iterations
+static int iterateRawmidiDevices(snd_rawmidi_stream_t direction,
+                                 DeviceIteratorPtr iterator,
+                                 void* userData) {
+    int count = 0;
+    int subdeviceCount;
+    int card, dev, subDev;
+    char devname[16];
+    int err;
+    snd_ctl_t *handle;
+    snd_rawmidi_t *rawmidi;
+    snd_rawmidi_info_t *rawmidi_info;
+    snd_ctl_card_info_t *card_info, *defcardinfo = NULL;
+    UINT32 deviceID;
+    int doContinue = TRUE;
+
+    snd_rawmidi_info_malloc(&rawmidi_info);
+    snd_ctl_card_info_malloc(&card_info);
+
+    // 1st try "default" device
+    if (direction == SND_RAWMIDI_STREAM_INPUT) {
+        err = snd_rawmidi_open(&rawmidi, NULL, ALSA_DEFAULT_DEVICE_NAME,
+                               SND_RAWMIDI_NONBLOCK);
+    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
+        err = snd_rawmidi_open(NULL, &rawmidi, ALSA_DEFAULT_DEVICE_NAME,
+                               SND_RAWMIDI_NONBLOCK);
+    } else {
+        ERROR0("ERROR: iterateRawmidiDevices(): direction is neither"
+               " SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
+        err = MIDI_INVALID_ARGUMENT;
+    }
+    if (err < 0) {
+        ERROR1("ERROR: snd_rawmidi_open (\"default\"): %s\n",
+               snd_strerror(err));
+    } else {
+        err = snd_rawmidi_info(rawmidi, rawmidi_info);
+
+        snd_rawmidi_close(rawmidi);
+        if (err < 0) {
+            ERROR1("ERROR: snd_rawmidi_info (\"default\"): %s\n",
+                    snd_strerror(err));
+        } else {
+            // try to get card info
+            card = snd_rawmidi_info_get_card(rawmidi_info);
+            if (card >= 0) {
+                sprintf(devname, ALSA_HARDWARE_CARD, card);
+                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
+                    if (snd_ctl_card_info(handle, card_info) >= 0) {
+                        defcardinfo = card_info;
+                    }
+                    snd_ctl_close(handle);
+                }
+            }
+            // call calback function for the device
+            if (iterator != NULL) {
+                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, rawmidi_info,
+                                         defcardinfo, userData);
+            }
+            count++;
+        }
+    }
+
+    // iterate cards
+    card = -1;
+    TRACE0("testing for cards...\n");
+    if (snd_card_next(&card) >= 0) {
+        TRACE1("Found card %d\n", card);
+        while (doContinue && (card >= 0)) {
+            sprintf(devname, ALSA_HARDWARE_CARD, card);
+            TRACE1("Opening control for alsa rawmidi device \"%s\"...\n", devname);
+            err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
+            if (err < 0) {
+                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
+            } else {
+                TRACE0("snd_ctl_open() SUCCESS\n");
+                err = snd_ctl_card_info(handle, card_info);
+                if (err < 0) {
+                    ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", card, snd_strerror(err));
+                } else {
+                    TRACE0("snd_ctl_card_info() SUCCESS\n");
+                    dev = -1;
+                    while (doContinue) {
+                        if (snd_ctl_rawmidi_next_device(handle, &dev) < 0) {
+                            ERROR0("snd_ctl_rawmidi_next_device\n");
+                        }
+                        TRACE0("snd_ctl_rawmidi_next_device() SUCCESS\n");
+                        if (dev < 0) {
+                            break;
+                        }
+                        snd_rawmidi_info_set_device(rawmidi_info, dev);
+                        snd_rawmidi_info_set_subdevice(rawmidi_info, 0);
+                        snd_rawmidi_info_set_stream(rawmidi_info, direction);
+                        err = snd_ctl_rawmidi_info(handle, rawmidi_info);
+                        TRACE0("after snd_ctl_rawmidi_info()\n");
+                        if (err < 0) {
+                            if (err != -ENOENT) {
+                                ERROR2("ERROR: snd_ctl_rawmidi_info, card=%d: %s", card, snd_strerror(err));
+                            }
+                        } else {
+                            TRACE0("snd_ctl_rawmidi_info() SUCCESS\n");
+                            subdeviceCount = needEnumerateSubdevices(ALSA_RAWMIDI)
+                                ? snd_rawmidi_info_get_subdevices_count(rawmidi_info)
+                                : 1;
+                            if (iterator!=NULL) {
+                                for (subDev = 0; subDev < subdeviceCount; subDev++) {
+                                    TRACE3("  Iterating %d,%d,%d\n", card, dev, subDev);
+                                    deviceID = encodeDeviceID(card, dev, subDev);
+                                    doContinue = (*iterator)(deviceID, rawmidi_info,
+                                                             card_info, userData);
+                                    count++;
+                                    TRACE0("returned from iterator\n");
+                                    if (!doContinue) {
+                                        break;
+                                    }
+                                }
+                            } else {
+                                count += subdeviceCount;
+                            }
+                        }
+                    } // of while(doContinue)
+                }
+                snd_ctl_close(handle);
+            }
+            if (snd_card_next(&card) < 0) {
+                break;
+            }
+        }
+    } else {
+        ERROR0("No cards found!\n");
+    }
+    snd_ctl_card_info_free(card_info);
+    snd_rawmidi_info_free(rawmidi_info);
+    return count;
+}
+
+
+
+int getMidiDeviceCount(snd_rawmidi_stream_t direction) {
+    int deviceCount;
+    TRACE0("> getMidiDeviceCount()\n");
+    initAlsaSupport();
+    deviceCount = iterateRawmidiDevices(direction, NULL, NULL);
+    TRACE0("< getMidiDeviceCount()\n");
+    return deviceCount;
+}
+
+
+
+/*
+  userData is assumed to be a pointer to ALSA_MIDIDeviceDescription.
+  ALSA_MIDIDeviceDescription->index has to be set to the index of the device
+  we want to get information of before this method is called the first time via
+  iterateRawmidiDevices(). On each call of this method,
+  ALSA_MIDIDeviceDescription->index is decremented. If it is equal to zero,
+  we have reached the desired device, so action is taken.
+  So after successful completion of iterateRawmidiDevices(),
+  ALSA_MIDIDeviceDescription->index is zero. If it isn't, this is an
+  indication of an error.
+*/
+static int deviceInfoIterator(UINT32 deviceID, snd_rawmidi_info_t *rawmidi_info,
+                              snd_ctl_card_info_t *cardinfo, void *userData) {
+    char buffer[300];
+    ALSA_MIDIDeviceDescription* desc = (ALSA_MIDIDeviceDescription*)userData;
+#ifdef ALSA_MIDI_USE_PLUGHW
+    int usePlugHw = 1;
+#else
+    int usePlugHw = 0;
+#endif
+
+    TRACE0("deviceInfoIterator\n");
+    initAlsaSupport();
+    if (desc->index == 0) {
+        // we found the device with correct index
+        desc->deviceID = deviceID;
+
+        buffer[0]=' '; buffer[1]='[';
+        // buffer[300] is enough to store the actual device string w/o overrun
+        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_RAWMIDI);
+        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
+        strncpy(desc->name,
+                (cardinfo != NULL)
+                    ? snd_ctl_card_info_get_id(cardinfo)
+                    : snd_rawmidi_info_get_id(rawmidi_info),
+                desc->strLen - strlen(buffer));
+        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
+        desc->description[0] = 0;
+        if (cardinfo != NULL) {
+            strncpy(desc->description, snd_ctl_card_info_get_name(cardinfo),
+                    desc->strLen);
+            strncat(desc->description, ", ",
+                    desc->strLen - strlen(desc->description));
+        }
+        strncat(desc->description, snd_rawmidi_info_get_id(rawmidi_info),
+                desc->strLen - strlen(desc->description));
+        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
+        strncat(desc->description, snd_rawmidi_info_get_name(rawmidi_info),
+                desc->strLen - strlen(desc->description));
+        TRACE2("Returning %s, %s\n", desc->name, desc->description);
+        return FALSE; // do not continue iteration
+    }
+    desc->index--;
+    return TRUE;
+}
+
+
+static int getMIDIDeviceDescriptionByIndex(snd_rawmidi_stream_t direction,
+                                           ALSA_MIDIDeviceDescription* desc) {
+    initAlsaSupport();
+    TRACE1(" getMIDIDeviceDescriptionByIndex (index = %d)\n", desc->index);
+    iterateRawmidiDevices(direction, &deviceInfoIterator, desc);
+    return (desc->index == 0) ? MIDI_SUCCESS : MIDI_INVALID_DEVICEID;
+}
+
+
+
+int initMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc, int index) {
+    int ret = MIDI_SUCCESS;
+    desc->index = index;
+    desc->strLen = 200;
+    desc->name = (char*) calloc(desc->strLen + 1, 1);
+    desc->description = (char*) calloc(desc->strLen + 1, 1);
+    if (! desc->name ||
+        ! desc->description) {
+        ret = MIDI_OUT_OF_MEMORY;
+    }
+    return ret;
+}
+
+
+void freeMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc) {
+    if (desc->name) {
+        free(desc->name);
+    }
+    if (desc->description) {
+        free(desc->description);
+    }
+}
+
+
+int getMidiDeviceName(snd_rawmidi_stream_t direction, int index, char *name,
+                      UINT32 nameLength) {
+    ALSA_MIDIDeviceDescription desc;
+    int ret;
+
+    TRACE1("getMidiDeviceName: nameLength: %d\n", (int) nameLength);
+    ret = initMIDIDeviceDescription(&desc, index);
+    if (ret == MIDI_SUCCESS) {
+        TRACE0("getMidiDeviceName: initMIDIDeviceDescription() SUCCESS\n");
+        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
+        if (ret == MIDI_SUCCESS) {
+            TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
+            strncpy(name, desc.name, nameLength - 1);
+            name[nameLength - 1] = 0;
+        }
+    }
+    freeMIDIDeviceDescription(&desc);
+    return ret;
+}
+
+
+int getMidiDeviceVendor(int index, char *name, UINT32 nameLength) {
+    strncpy(name, ALSA_VENDOR, nameLength - 1);
+    name[nameLength - 1] = 0;
+    return MIDI_SUCCESS;
+}
+
+
+int getMidiDeviceDescription(snd_rawmidi_stream_t direction,
+                             int index, char *name, UINT32 nameLength) {
+    ALSA_MIDIDeviceDescription desc;
+    int ret;
+
+    ret = initMIDIDeviceDescription(&desc, index);
+    if (ret == MIDI_SUCCESS) {
+        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
+        if (ret == MIDI_SUCCESS) {
+            strncpy(name, desc.description, nameLength - 1);
+            name[nameLength - 1] = 0;
+        }
+    }
+    freeMIDIDeviceDescription(&desc);
+    return ret;
+}
+
+
+int getMidiDeviceVersion(int index, char *name, UINT32 nameLength) {
+    getALSAVersion(name, nameLength);
+    return MIDI_SUCCESS;
+}
+
+
+static int getMidiDeviceID(snd_rawmidi_stream_t direction, int index,
+                           UINT32* deviceID) {
+    ALSA_MIDIDeviceDescription desc;
+    int ret;
+
+    ret = initMIDIDeviceDescription(&desc, index);
+    if (ret == MIDI_SUCCESS) {
+        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
+        if (ret == MIDI_SUCCESS) {
+            // TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
+            *deviceID = desc.deviceID;
+        }
+    }
+    freeMIDIDeviceDescription(&desc);
+    return ret;
+}
+
+
+/*
+  direction has to be either SND_RAWMIDI_STREAM_INPUT or
+  SND_RAWMIDI_STREAM_OUTPUT.
+  Returns 0 on success. Otherwise, MIDI_OUT_OF_MEMORY, MIDI_INVALID_ARGUMENT
+   or a negative ALSA error code is returned.
+*/
+INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
+                     MidiDeviceHandle** handle) {
+    snd_rawmidi_t* native_handle;
+    snd_midi_event_t* event_parser = NULL;
+    int err;
+    UINT32 deviceID = 0;
+    char devicename[100];
+#ifdef ALSA_MIDI_USE_PLUGHW
+    int usePlugHw = 1;
+#else
+    int usePlugHw = 0;
+#endif
+
+    TRACE0("> openMidiDevice()\n");
+
+    (*handle) = (MidiDeviceHandle*) calloc(sizeof(MidiDeviceHandle), 1);
+    if (!(*handle)) {
+        ERROR0("ERROR: openDevice: out of memory\n");
+        return MIDI_OUT_OF_MEMORY;
+    }
+
+    // TODO: iterate to get dev ID from index
+    err = getMidiDeviceID(direction, deviceIndex, &deviceID);
+    TRACE1("  openMidiDevice(): deviceID: %d\n", (int) deviceID);
+    getDeviceStringFromDeviceID(devicename, deviceID,
+                                usePlugHw, ALSA_RAWMIDI);
+    TRACE1("  openMidiDevice(): deviceString: %s\n", devicename);
+
+    // finally open the device
+    if (direction == SND_RAWMIDI_STREAM_INPUT) {
+        err = snd_rawmidi_open(&native_handle, NULL, devicename,
+                               SND_RAWMIDI_NONBLOCK);
+    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
+        err = snd_rawmidi_open(NULL, &native_handle, devicename,
+                               SND_RAWMIDI_NONBLOCK);
+    } else {
+        ERROR0("  ERROR: openMidiDevice(): direction is neither SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
+        err = MIDI_INVALID_ARGUMENT;
+    }
+    if (err < 0) {
+        ERROR1("<  ERROR: openMidiDevice(): snd_rawmidi_open() returned %d\n", err);
+        free(*handle);
+        (*handle) = NULL;
+        return err;
+    }
+    /* We opened with non-blocking behaviour to not get hung if the device
+       is used by a different process. Writing, however, should
+       be blocking. So we change it here. */
+    if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
+        err = snd_rawmidi_nonblock(native_handle, 0);
+        if (err < 0) {
+            ERROR1("  ERROR: openMidiDevice(): snd_rawmidi_nonblock() returned %d\n", err);
+            snd_rawmidi_close(native_handle);
+            free(*handle);
+            (*handle) = NULL;
+            return err;
+        }
+    }
+    if (direction == SND_RAWMIDI_STREAM_INPUT) {
+        err = snd_midi_event_new(EVENT_PARSER_BUFSIZE, &event_parser);
+        if (err < 0) {
+            ERROR1("  ERROR: openMidiDevice(): snd_midi_event_new() returned %d\n", err);
+            snd_rawmidi_close(native_handle);
+            free(*handle);
+            (*handle) = NULL;
+            return err;
+        }
+    }
+
+    (*handle)->deviceHandle = (void*) native_handle;
+    (*handle)->startTime = getTimeInMicroseconds();
+    (*handle)->platformData = event_parser;
+    TRACE0("< openMidiDevice(): succeeded\n");
+    return err;
+}
+
+
+
+INT32 closeMidiDevice(MidiDeviceHandle* handle) {
+    int err;
+
+    TRACE0("> closeMidiDevice()\n");
+    if (!handle) {
+        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    if (!handle->deviceHandle) {
+        ERROR0("< ERROR: closeMidiDevice(): native handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    err = snd_rawmidi_close((snd_rawmidi_t*) handle->deviceHandle);
+    TRACE1("  snd_rawmidi_close() returns %d\n", err);
+    if (handle->platformData) {
+        snd_midi_event_free((snd_midi_event_t*) handle->platformData);
+    }
+    free(handle);
+    TRACE0("< closeMidiDevice: succeeded\n");
+    return err;
+}
+
+
+INT64 getMidiTimestamp(MidiDeviceHandle* handle) {
+    if (!handle) {
+        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    return getTimeInMicroseconds() - handle->startTime;
+}
+
+
+/* end */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.h	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2003, 2007, 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 
+#include "Utilities.h"
+#include "PlatformMidi.h"
+
+
+#ifndef PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
+#define PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
+
+#define EVENT_PARSER_BUFSIZE (2048)
+
+// if this is defined, use plughw: devices
+//#define ALSA_MIDI_USE_PLUGHW
+#undef ALSA_MIDI_USE_PLUGHW
+
+typedef struct tag_ALSA_MIDIDeviceDescription {
+        int index;          // in
+        int strLen;         // in
+        INT32 deviceID;    // out
+        char* name;         // out
+        char* description;  // out
+} ALSA_MIDIDeviceDescription;
+
+
+const char* getErrorStr(INT32 err);
+
+/* Returns the number of devices. */
+/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
+   SND_RAWMIDI_STREAM_INPUT. */
+int getMidiDeviceCount(snd_rawmidi_stream_t direction);
+
+/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
+/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
+   SND_RAWMIDI_STREAM_INPUT. */
+int getMidiDeviceName(snd_rawmidi_stream_t direction, int index,
+                      char *name, UINT32 nameLength);
+
+/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
+int getMidiDeviceVendor(int index, char *name, UINT32 nameLength);
+
+/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
+/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
+   SND_RAWMIDI_STREAM_INPUT. */
+int getMidiDeviceDescription(snd_rawmidi_stream_t direction, int index,
+                             char *name, UINT32 nameLength);
+
+/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
+int getMidiDeviceVersion(int index, char *name, UINT32 nameLength);
+
+// returns 0 on success, otherwise MIDI_OUT_OF_MEMORY or ALSA error code
+/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
+   SND_RAWMIDI_STREAM_INPUT. */
+INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
+                     MidiDeviceHandle** handle);
+
+// returns 0 on success, otherwise a (negative) ALSA error code
+INT32 closeMidiDevice(MidiDeviceHandle* handle);
+
+INT64 getMidiTimestamp(MidiDeviceHandle* handle);
+
+#endif // PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,941 @@
+/*
+ * Copyright (c) 2002, 2011, 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.
+ */
+
+#define USE_ERROR
+#define USE_TRACE
+
+#include "PLATFORM_API_LinuxOS_ALSA_PCMUtils.h"
+#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
+#include "DirectAudio.h"
+
+#if USE_DAUDIO == TRUE
+
+// GetPosition method 1: based on how many bytes are passed to the kernel driver
+//                       + does not need much processor resources
+//                       - not very exact, "jumps"
+// GetPosition method 2: ask kernel about actual position of playback.
+//                       - very exact
+//                       - switch to kernel layer for each call
+// GetPosition method 3: use snd_pcm_avail() call - not yet in official ALSA
+// quick tests on a Pentium 200MMX showed max. 1.5% processor usage
+// for playing back a CD-quality file and printing 20x per second a line
+// on the console with the current time. So I guess performance is not such a
+// factor here.
+//#define GET_POSITION_METHOD1
+#define GET_POSITION_METHOD2
+
+
+// The default time for a period in microseconds.
+// For very small buffers, only 2 periods are used.
+#define DEFAULT_PERIOD_TIME 20000 /* 20ms */
+
+///// implemented functions of DirectAudio.h
+
+INT32 DAUDIO_GetDirectAudioDeviceCount() {
+    return (INT32) getAudioDeviceCount();
+}
+
+
+INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex, DirectAudioDeviceDescription* description) {
+    ALSA_AudioDeviceDescription adesc;
+
+    adesc.index = (int) mixerIndex;
+    adesc.strLen = DAUDIO_STRING_LENGTH;
+
+    adesc.maxSimultaneousLines = (int*) (&(description->maxSimulLines));
+    adesc.deviceID = &(description->deviceID);
+    adesc.name = description->name;
+    adesc.vendor = description->vendor;
+    adesc.description = description->description;
+    adesc.version = description->version;
+
+    return getAudioDeviceDescriptionByIndex(&adesc);
+}
+
+#define MAX_BIT_INDEX 6
+// returns
+// 6: for anything above 24-bit
+// 5: for 4 bytes sample size, 24-bit
+// 4: for 3 bytes sample size, 24-bit
+// 3: for 3 bytes sample size, 20-bit
+// 2: for 2 bytes sample size, 16-bit
+// 1: for 1 byte sample size, 8-bit
+// 0: for anything else
+int getBitIndex(int sampleSizeInBytes, int significantBits) {
+    if (significantBits > 24) return 6;
+    if (sampleSizeInBytes == 4 && significantBits == 24) return 5;
+    if (sampleSizeInBytes == 3) {
+        if (significantBits == 24) return 4;
+        if (significantBits == 20) return 3;
+    }
+    if (sampleSizeInBytes == 2 && significantBits == 16) return 2;
+    if (sampleSizeInBytes == 1 && significantBits == 8) return 1;
+    return 0;
+}
+
+int getSampleSizeInBytes(int bitIndex, int sampleSizeInBytes) {
+    switch(bitIndex) {
+    case 1: return 1;
+    case 2: return 2;
+    case 3: /* fall through */
+    case 4: return 3;
+    case 5: return 4;
+    }
+    return sampleSizeInBytes;
+}
+
+int getSignificantBits(int bitIndex, int significantBits) {
+    switch(bitIndex) {
+    case 1: return 8;
+    case 2: return 16;
+    case 3: return 20;
+    case 4: /* fall through */
+    case 5: return 24;
+    }
+    return significantBits;
+}
+
+void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
+    snd_pcm_t* handle;
+    snd_pcm_format_mask_t* formatMask;
+    snd_pcm_format_t format;
+    snd_pcm_hw_params_t* hwParams;
+    int handledBits[MAX_BIT_INDEX+1];
+
+    int ret;
+    int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc;
+    int origSampleSizeInBytes, origSignificantBits;
+    unsigned int channels, minChannels, maxChannels;
+    int rate, bitIndex;
+
+    for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE;
+    if (openPCMfromDeviceID(deviceID, &handle, isSource, TRUE /*query hardware*/) < 0) {
+        return;
+    }
+    ret = snd_pcm_format_mask_malloc(&formatMask);
+    if (ret != 0) {
+        ERROR1("snd_pcm_format_mask_malloc returned error %d\n", ret);
+    } else {
+        ret = snd_pcm_hw_params_malloc(&hwParams);
+        if (ret != 0) {
+            ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
+        } else {
+            ret = snd_pcm_hw_params_any(handle, hwParams);
+            /* snd_pcm_hw_params_any can return a positive value on success too */
+            if (ret < 0) {
+                 ERROR1("snd_pcm_hw_params_any returned error %d\n", ret);
+            } else {
+                /* for the logic following this code, set ret to 0 to indicate success */
+                ret = 0;
+            }
+        }
+        snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
+        if (ret == 0) {
+            ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels);
+            if (ret != 0) {
+                ERROR1("snd_pcm_hw_params_get_channels_min returned error %d\n", ret);
+            }
+        }
+        if (ret == 0) {
+            ret = snd_pcm_hw_params_get_channels_max(hwParams, &maxChannels);
+            if (ret != 0) {
+                ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret);
+            }
+        }
+
+        // since we queried the hw: device, for many soundcards, it will only
+        // report the maximum number of channels (which is the only way to talk
+        // to the hw: device). Since we will, however, open the plughw: device
+        // when opening the Source/TargetDataLine, we can safely assume that
+        // also the channels 1..maxChannels are available.
+#ifdef ALSA_PCM_USE_PLUGHW
+        minChannels = 1;
+#endif
+        if (ret == 0) {
+            // plughw: supports any sample rate
+            rate = -1;
+            for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
+                if (snd_pcm_format_mask_test(formatMask, format)) {
+                    // format exists
+                    if (getFormatFromAlsaFormat(format, &origSampleSizeInBytes,
+                                                &origSignificantBits,
+                                                &isSigned, &isBigEndian, &enc)) {
+                        // now if we use plughw:, we can use any bit size below the
+                        // natively supported ones. Some ALSA drivers only support the maximum
+                        // bit size, so we add any sample rates below the reported one.
+                        // E.g. this iteration reports support for 16-bit.
+                        // getBitIndex will return 2, so it will add entries for
+                        // 16-bit (bitIndex=2) and in the next do-while loop iteration,
+                        // it will decrease bitIndex and will therefore add 8-bit support.
+                        bitIndex = getBitIndex(origSampleSizeInBytes, origSignificantBits);
+                        do {
+                            if (bitIndex == 0
+                                || bitIndex == MAX_BIT_INDEX
+                                || !handledBits[bitIndex]) {
+                                handledBits[bitIndex] = TRUE;
+                                sampleSizeInBytes = getSampleSizeInBytes(bitIndex, origSampleSizeInBytes);
+                                significantBits = getSignificantBits(bitIndex, origSignificantBits);
+                                if (maxChannels - minChannels > MAXIMUM_LISTED_CHANNELS) {
+                                    // avoid too many channels explicitly listed
+                                    // just add -1, min, and max
+                                    DAUDIO_AddAudioFormat(creator, significantBits,
+                                                          -1, -1, rate,
+                                                          enc, isSigned, isBigEndian);
+                                    DAUDIO_AddAudioFormat(creator, significantBits,
+                                                          sampleSizeInBytes * minChannels,
+                                                          minChannels, rate,
+                                                          enc, isSigned, isBigEndian);
+                                    DAUDIO_AddAudioFormat(creator, significantBits,
+                                                          sampleSizeInBytes * maxChannels,
+                                                          maxChannels, rate,
+                                                          enc, isSigned, isBigEndian);
+                                } else {
+                                    for (channels = minChannels; channels <= maxChannels; channels++) {
+                                        DAUDIO_AddAudioFormat(creator, significantBits,
+                                                              sampleSizeInBytes * channels,
+                                                              channels, rate,
+                                                              enc, isSigned, isBigEndian);
+                                    }
+                                }
+                            }
+#ifndef ALSA_PCM_USE_PLUGHW
+                            // without plugin, do not add fake formats
+                            break;
+#endif
+                        } while (--bitIndex > 0);
+                    } else {
+                        TRACE1("could not get format from alsa for format %d\n", format);
+                    }
+                } else {
+                    //TRACE1("Format %d not supported\n", format);
+                }
+            } // for loop
+            snd_pcm_hw_params_free(hwParams);
+        }
+        snd_pcm_format_mask_free(formatMask);
+    }
+    snd_pcm_close(handle);
+}
+
+/** Workaround for cr 7033899, 7030629:
+ * dmix plugin doesn't like flush (snd_pcm_drop) when the buffer is empty
+ * (just opened, underruned or already flushed).
+ * Sometimes it causes PCM falls to -EBADFD error,
+ * sometimes causes bufferSize change.
+ * To prevent unnecessary flushes AlsaPcmInfo::isRunning & isFlushed are used.
+ */
+/* ******* ALSA PCM INFO ******************** */
+typedef struct tag_AlsaPcmInfo {
+    snd_pcm_t* handle;
+    snd_pcm_hw_params_t* hwParams;
+    snd_pcm_sw_params_t* swParams;
+    int bufferSizeInBytes;
+    int frameSize; // storage size in Bytes
+    unsigned int periods;
+    snd_pcm_uframes_t periodSize;
+    short int isRunning;    // see comment above
+    short int isFlushed;    // see comment above
+#ifdef GET_POSITION_METHOD2
+    // to be used exclusively by getBytePosition!
+    snd_pcm_status_t* positionStatus;
+#endif
+} AlsaPcmInfo;
+
+
+int setStartThresholdNoCommit(AlsaPcmInfo* info, int useThreshold) {
+    int ret;
+    int threshold;
+
+    if (useThreshold) {
+        // start device whenever anything is written to the buffer
+        threshold = 1;
+    } else {
+        // never start the device automatically
+        threshold = 2000000000; /* near UINT_MAX */
+    }
+    ret = snd_pcm_sw_params_set_start_threshold(info->handle, info->swParams, threshold);
+    if (ret < 0) {
+        ERROR1("Unable to set start threshold mode: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    return TRUE;
+}
+
+int setStartThreshold(AlsaPcmInfo* info, int useThreshold) {
+    int ret = 0;
+
+    if (!setStartThresholdNoCommit(info, useThreshold)) {
+        ret = -1;
+    }
+    if (ret == 0) {
+        // commit it
+        ret = snd_pcm_sw_params(info->handle, info->swParams);
+        if (ret < 0) {
+            ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
+        }
+    }
+    return (ret == 0)?TRUE:FALSE;
+}
+
+
+// returns TRUE if successful
+int setHWParams(AlsaPcmInfo* info,
+                float sampleRate,
+                int channels,
+                int bufferSizeInFrames,
+                snd_pcm_format_t format) {
+    unsigned int rrate, periodTime, periods;
+    int ret, dir;
+    snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames;
+
+    /* choose all parameters */
+    ret = snd_pcm_hw_params_any(info->handle, info->hwParams);
+    if (ret < 0) {
+        ERROR1("Broken configuration: no configurations available: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    /* set the interleaved read/write format */
+    ret = snd_pcm_hw_params_set_access(info->handle, info->hwParams, SND_PCM_ACCESS_RW_INTERLEAVED);
+    if (ret < 0) {
+        ERROR1("SND_PCM_ACCESS_RW_INTERLEAVED access type not available: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    /* set the sample format */
+    ret = snd_pcm_hw_params_set_format(info->handle, info->hwParams, format);
+    if (ret < 0) {
+        ERROR1("Sample format not available: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    /* set the count of channels */
+    ret = snd_pcm_hw_params_set_channels(info->handle, info->hwParams, channels);
+    if (ret < 0) {
+        ERROR2("Channels count (%d) not available: %s\n", channels, snd_strerror(ret));
+        return FALSE;
+    }
+    /* set the stream rate */
+    rrate = (int) (sampleRate + 0.5f);
+    dir = 0;
+    ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir);
+    if (ret < 0) {
+        ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret));
+        return FALSE;
+    }
+    if ((rrate-sampleRate > 2) || (rrate-sampleRate < - 2)) {
+        ERROR2("Rate doesn't match (requested %2.2fHz, got %dHz)\n", sampleRate, rrate);
+        return FALSE;
+    }
+    /* set the buffer time */
+    ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames);
+    if (ret < 0) {
+        ERROR2("Unable to set buffer size to %d frames: %s\n",
+               (int) alsaBufferSizeInFrames, snd_strerror(ret));
+        return FALSE;
+    }
+    bufferSizeInFrames = (int) alsaBufferSizeInFrames;
+    /* set the period time */
+    if (bufferSizeInFrames > 1024) {
+        dir = 0;
+        periodTime = DEFAULT_PERIOD_TIME;
+        ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir);
+        if (ret < 0) {
+            ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret));
+            return FALSE;
+        }
+    } else {
+        /* set the period count for very small buffer sizes to 2 */
+        dir = 0;
+        periods = 2;
+        ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir);
+        if (ret < 0) {
+            ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret));
+            return FALSE;
+        }
+    }
+    /* write the parameters to device */
+    ret = snd_pcm_hw_params(info->handle, info->hwParams);
+    if (ret < 0) {
+        ERROR1("Unable to set hw params: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    return TRUE;
+}
+
+// returns 1 if successful
+int setSWParams(AlsaPcmInfo* info) {
+    int ret;
+
+    /* get the current swparams */
+    ret = snd_pcm_sw_params_current(info->handle, info->swParams);
+    if (ret < 0) {
+        ERROR1("Unable to determine current swparams: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    /* never start the transfer automatically */
+    if (!setStartThresholdNoCommit(info, FALSE /* don't use threshold */)) {
+        return FALSE;
+    }
+
+    /* allow the transfer when at least period_size samples can be processed */
+    ret = snd_pcm_sw_params_set_avail_min(info->handle, info->swParams, info->periodSize);
+    if (ret < 0) {
+        ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    /* write the parameters to the playback device */
+    ret = snd_pcm_sw_params(info->handle, info->swParams);
+    if (ret < 0) {
+        ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static snd_output_t* ALSA_OUTPUT = NULL;
+
+void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
+                  int encoding, float sampleRate, int sampleSizeInBits,
+                  int frameSize, int channels,
+                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
+    snd_pcm_format_mask_t* formatMask;
+    snd_pcm_format_t format;
+    int dir;
+    int ret = 0;
+    AlsaPcmInfo* info = NULL;
+    /* snd_pcm_uframes_t is 64 bit on 64-bit systems */
+    snd_pcm_uframes_t alsaBufferSizeInFrames = 0;
+
+
+    TRACE0("> DAUDIO_Open\n");
+#ifdef USE_TRACE
+    // for using ALSA debug dump methods
+    if (ALSA_OUTPUT == NULL) {
+        snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
+    }
+#endif
+    if (channels <= 0) {
+        ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
+        return NULL;
+    }
+    info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
+    if (!info) {
+        ERROR0("Out of memory\n");
+        return NULL;
+    }
+    memset(info, 0, sizeof(AlsaPcmInfo));
+    // initial values are: stopped, flushed
+    info->isRunning = 0;
+    info->isFlushed = 1;
+
+    ret = openPCMfromDeviceID(deviceID, &(info->handle), isSource, FALSE /* do open device*/);
+    if (ret == 0) {
+        // set to blocking mode
+        snd_pcm_nonblock(info->handle, 0);
+        ret = snd_pcm_hw_params_malloc(&(info->hwParams));
+        if (ret != 0) {
+            ERROR1("  snd_pcm_hw_params_malloc returned error %d\n", ret);
+        } else {
+            ret = -1;
+            if (getAlsaFormatFromFormat(&format, frameSize / channels, sampleSizeInBits,
+                                        isSigned, isBigEndian, encoding)) {
+                if (setHWParams(info,
+                                sampleRate,
+                                channels,
+                                bufferSizeInBytes / frameSize,
+                                format)) {
+                    info->frameSize = frameSize;
+                    ret = snd_pcm_hw_params_get_period_size(info->hwParams, &info->periodSize, &dir);
+                    if (ret < 0) {
+                        ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret));
+                    }
+                    snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir);
+                    snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames);
+                    info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize;
+                    TRACE3("  DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n",
+                           (int) info->periodSize, info->periods, info->bufferSizeInBytes);
+                }
+            }
+        }
+        if (ret == 0) {
+            // set software parameters
+            ret = snd_pcm_sw_params_malloc(&(info->swParams));
+            if (ret != 0) {
+                ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
+            } else {
+                if (!setSWParams(info)) {
+                    ret = -1;
+                }
+            }
+        }
+        if (ret == 0) {
+            // prepare device
+            ret = snd_pcm_prepare(info->handle);
+            if (ret < 0) {
+                ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
+            }
+        }
+
+#ifdef GET_POSITION_METHOD2
+        if (ret == 0) {
+            ret = snd_pcm_status_malloc(&(info->positionStatus));
+            if (ret != 0) {
+                ERROR1("ERROR in snd_pcm_status_malloc: %s\n", snd_strerror(ret));
+            }
+        }
+#endif
+    }
+    if (ret != 0) {
+        DAUDIO_Close((void*) info, isSource);
+        info = NULL;
+    } else {
+        // set to non-blocking mode
+        snd_pcm_nonblock(info->handle, 1);
+        TRACE1("< DAUDIO_Open: Opened device successfully. Handle=%p\n",
+               (void*) info->handle);
+    }
+    return (void*) info;
+}
+
+#ifdef USE_TRACE
+void printState(snd_pcm_state_t state) {
+    if (state == SND_PCM_STATE_OPEN) {
+        TRACE0("State: SND_PCM_STATE_OPEN\n");
+    }
+    else if (state == SND_PCM_STATE_SETUP) {
+        TRACE0("State: SND_PCM_STATE_SETUP\n");
+    }
+    else if (state == SND_PCM_STATE_PREPARED) {
+        TRACE0("State: SND_PCM_STATE_PREPARED\n");
+    }
+    else if (state == SND_PCM_STATE_RUNNING) {
+        TRACE0("State: SND_PCM_STATE_RUNNING\n");
+    }
+    else if (state == SND_PCM_STATE_XRUN) {
+        TRACE0("State: SND_PCM_STATE_XRUN\n");
+    }
+    else if (state == SND_PCM_STATE_DRAINING) {
+        TRACE0("State: SND_PCM_STATE_DRAINING\n");
+    }
+    else if (state == SND_PCM_STATE_PAUSED) {
+        TRACE0("State: SND_PCM_STATE_PAUSED\n");
+    }
+    else if (state == SND_PCM_STATE_SUSPENDED) {
+        TRACE0("State: SND_PCM_STATE_SUSPENDED\n");
+    }
+}
+#endif
+
+int DAUDIO_Start(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret;
+    snd_pcm_state_t state;
+
+    TRACE0("> DAUDIO_Start\n");
+    // set to blocking mode
+    snd_pcm_nonblock(info->handle, 0);
+    // set start mode so that it always starts as soon as data is there
+    setStartThreshold(info, TRUE /* use threshold */);
+    state = snd_pcm_state(info->handle);
+    if (state == SND_PCM_STATE_PAUSED) {
+        // in case it was stopped previously
+        TRACE0("  Un-pausing...\n");
+        ret = snd_pcm_pause(info->handle, FALSE);
+        if (ret != 0) {
+            ERROR2("  NOTE: error in snd_pcm_pause:%d: %s\n", ret, snd_strerror(ret));
+        }
+    }
+    if (state == SND_PCM_STATE_SUSPENDED) {
+        TRACE0("  Resuming...\n");
+        ret = snd_pcm_resume(info->handle);
+        if (ret < 0) {
+            if ((ret != -EAGAIN) && (ret != -ENOSYS)) {
+                ERROR2("  ERROR: error in snd_pcm_resume:%d: %s\n", ret, snd_strerror(ret));
+            }
+        }
+    }
+    if (state == SND_PCM_STATE_SETUP) {
+        TRACE0("need to call prepare again...\n");
+        // prepare device
+        ret = snd_pcm_prepare(info->handle);
+        if (ret < 0) {
+            ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
+        }
+    }
+    // in case there is still data in the buffers
+    ret = snd_pcm_start(info->handle);
+    if (ret != 0) {
+        if (ret != -EPIPE) {
+            ERROR2("  NOTE: error in snd_pcm_start: %d: %s\n", ret, snd_strerror(ret));
+        }
+    }
+    // set to non-blocking mode
+    ret = snd_pcm_nonblock(info->handle, 1);
+    if (ret != 0) {
+        ERROR1("  ERROR in snd_pcm_nonblock: %s\n", snd_strerror(ret));
+    }
+    state = snd_pcm_state(info->handle);
+#ifdef USE_TRACE
+    printState(state);
+#endif
+    ret = (state == SND_PCM_STATE_PREPARED)
+        || (state == SND_PCM_STATE_RUNNING)
+        || (state == SND_PCM_STATE_XRUN)
+        || (state == SND_PCM_STATE_SUSPENDED);
+    if (ret) {
+        info->isRunning = 1;
+        // source line should keep isFlushed value until Write() is called;
+        // for target data line reset it right now.
+        if (!isSource) {
+            info->isFlushed = 0;
+        }
+    }
+    TRACE1("< DAUDIO_Start %s\n", ret?"success":"error");
+    return ret?TRUE:FALSE;
+}
+
+int DAUDIO_Stop(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret;
+
+    TRACE0("> DAUDIO_Stop\n");
+    // set to blocking mode
+    snd_pcm_nonblock(info->handle, 0);
+    setStartThreshold(info, FALSE /* don't use threshold */); // device will not start after buffer xrun
+    ret = snd_pcm_pause(info->handle, 1);
+    // set to non-blocking mode
+    snd_pcm_nonblock(info->handle, 1);
+    if (ret != 0) {
+        ERROR1("ERROR in snd_pcm_pause: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    info->isRunning = 0;
+    TRACE0("< DAUDIO_Stop success\n");
+    return TRUE;
+}
+
+void DAUDIO_Close(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+
+    TRACE0("DAUDIO_Close\n");
+    if (info != NULL) {
+        if (info->handle != NULL) {
+            snd_pcm_close(info->handle);
+        }
+        if (info->hwParams) {
+            snd_pcm_hw_params_free(info->hwParams);
+        }
+        if (info->swParams) {
+            snd_pcm_sw_params_free(info->swParams);
+        }
+#ifdef GET_POSITION_METHOD2
+        if (info->positionStatus) {
+            snd_pcm_status_free(info->positionStatus);
+        }
+#endif
+        free(info);
+    }
+}
+
+/*
+ * Underrun and suspend recovery
+ * returns
+ * 0:  exit native and return 0
+ * 1:  try again to write/read
+ * -1: error - exit native with return value -1
+ */
+int xrun_recovery(AlsaPcmInfo* info, int err) {
+    int ret;
+
+    if (err == -EPIPE) {    /* underrun / overflow */
+        TRACE0("xrun_recovery: underrun/overflow.\n");
+        ret = snd_pcm_prepare(info->handle);
+        if (ret < 0) {
+            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
+            return -1;
+        }
+        return 1;
+    } else if (err == -ESTRPIPE) {
+        TRACE0("xrun_recovery: suspended.\n");
+        ret = snd_pcm_resume(info->handle);
+        if (ret < 0) {
+            if (ret == -EAGAIN) {
+                return 0; /* wait until the suspend flag is released */
+            }
+            return -1;
+        }
+        ret = snd_pcm_prepare(info->handle);
+        if (ret < 0) {
+            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
+            return -1;
+        }
+        return 1;
+    } else if (err == -EAGAIN) {
+        TRACE0("xrun_recovery: EAGAIN try again flag.\n");
+        return 0;
+    }
+
+    TRACE2("xrun_recovery: unexpected error %d: %s\n", err, snd_strerror(err));
+    return -1;
+}
+
+// returns -1 on error
+int DAUDIO_Write(void* id, char* data, int byteSize) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret, count;
+    snd_pcm_sframes_t frameSize, writtenFrames;
+
+    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
+
+    /* sanity */
+    if (byteSize <= 0 || info->frameSize <= 0) {
+        ERROR2(" DAUDIO_Write: byteSize=%d, frameSize=%d!\n",
+               (int) byteSize, (int) info->frameSize);
+        TRACE0("< DAUDIO_Write returning -1\n");
+        return -1;
+    }
+
+    count = 2; // maximum number of trials to recover from underrun
+    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
+    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
+    do {
+        writtenFrames = snd_pcm_writei(info->handle, (const void*) data, (snd_pcm_uframes_t) frameSize);
+
+        if (writtenFrames < 0) {
+            ret = xrun_recovery(info, (int) writtenFrames);
+            if (ret <= 0) {
+                TRACE1("DAUDIO_Write: xrun recovery returned %d -> return.\n", ret);
+                return ret;
+            }
+            if (count-- <= 0) {
+                ERROR0("DAUDIO_Write: too many attempts to recover from xrun/suspend\n");
+                return -1;
+            }
+        } else {
+            break;
+        }
+    } while (TRUE);
+    //ret =  snd_pcm_frames_to_bytes(info->handle, writtenFrames);
+
+    if (writtenFrames > 0) {
+        // reset "flushed" flag
+        info->isFlushed = 0;
+    }
+
+    ret =  (int) (writtenFrames * info->frameSize);
+    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
+    return ret;
+}
+
+// returns -1 on error
+int DAUDIO_Read(void* id, char* data, int byteSize) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret, count;
+    snd_pcm_sframes_t frameSize, readFrames;
+
+    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
+    /*TRACE3("  info=%p, data=%p, byteSize=%d\n",
+      (void*) info, (void*) data, (int) byteSize);
+      TRACE2("  info->frameSize=%d, info->handle=%p\n",
+      (int) info->frameSize, (void*) info->handle);
+    */
+    /* sanity */
+    if (byteSize <= 0 || info->frameSize <= 0) {
+        ERROR2(" DAUDIO_Read: byteSize=%d, frameSize=%d!\n",
+               (int) byteSize, (int) info->frameSize);
+        TRACE0("< DAUDIO_Read returning -1\n");
+        return -1;
+    }
+    if (!info->isRunning && info->isFlushed) {
+        // PCM has nothing to read
+        return 0;
+    }
+
+    count = 2; // maximum number of trials to recover from error
+    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
+    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
+    do {
+        readFrames = snd_pcm_readi(info->handle, (void*) data, (snd_pcm_uframes_t) frameSize);
+        if (readFrames < 0) {
+            ret = xrun_recovery(info, (int) readFrames);
+            if (ret <= 0) {
+                TRACE1("DAUDIO_Read: xrun recovery returned %d -> return.\n", ret);
+                return ret;
+            }
+            if (count-- <= 0) {
+                ERROR0("DAUDIO_Read: too many attempts to recover from xrun/suspend\n");
+                return -1;
+            }
+        } else {
+            break;
+        }
+    } while (TRUE);
+    //ret =  snd_pcm_frames_to_bytes(info->handle, readFrames);
+    ret =  (int) (readFrames * info->frameSize);
+    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
+    return ret;
+}
+
+
+int DAUDIO_GetBufferSize(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+
+    return info->bufferSizeInBytes;
+}
+
+int DAUDIO_StillDraining(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    snd_pcm_state_t state;
+
+    state = snd_pcm_state(info->handle);
+    //printState(state);
+    //TRACE1("Still draining: %s\n", (state != SND_PCM_STATE_XRUN)?"TRUE":"FALSE");
+    return (state == SND_PCM_STATE_RUNNING)?TRUE:FALSE;
+}
+
+
+int DAUDIO_Flush(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret;
+
+    TRACE0("DAUDIO_Flush\n");
+
+    if (info->isFlushed) {
+        // nothing to drop
+        return 1;
+    }
+
+    ret = snd_pcm_drop(info->handle);
+    if (ret != 0) {
+        ERROR1("ERROR in snd_pcm_drop: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+
+    info->isFlushed = 1;
+    if (info->isRunning) {
+        ret = DAUDIO_Start(id, isSource);
+    }
+    return ret;
+}
+
+int DAUDIO_GetAvailable(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    snd_pcm_sframes_t availableInFrames;
+    snd_pcm_state_t state;
+    int ret;
+
+    state = snd_pcm_state(info->handle);
+    if (info->isFlushed || state == SND_PCM_STATE_XRUN) {
+        // if in xrun state then we have the entire buffer available,
+        // not 0 as alsa reports
+        ret = info->bufferSizeInBytes;
+    } else {
+        availableInFrames = snd_pcm_avail_update(info->handle);
+        if (availableInFrames < 0) {
+            ret = 0;
+        } else {
+            //ret = snd_pcm_frames_to_bytes(info->handle, availableInFrames);
+            ret = (int) (availableInFrames * info->frameSize);
+        }
+    }
+    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
+    return ret;
+}
+
+INT64 estimatePositionFromAvail(AlsaPcmInfo* info, int isSource, INT64 javaBytePos, int availInBytes) {
+    // estimate the current position with the buffer size and
+    // the available bytes to read or write in the buffer.
+    // not an elegant solution - bytePos will stop on xruns,
+    // and in race conditions it may jump backwards
+    // Advantage is that it is indeed based on the samples that go through
+    // the system (rather than time-based methods)
+    if (isSource) {
+        // javaBytePos is the position that is reached when the current
+        // buffer is played completely
+        return (INT64) (javaBytePos - info->bufferSizeInBytes + availInBytes);
+    } else {
+        // javaBytePos is the position that was when the current buffer was empty
+        return (INT64) (javaBytePos + availInBytes);
+    }
+}
+
+INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret;
+    INT64 result = javaBytePos;
+    snd_pcm_state_t state;
+    state = snd_pcm_state(info->handle);
+
+    if (!info->isFlushed && state != SND_PCM_STATE_XRUN) {
+#ifdef GET_POSITION_METHOD2
+        snd_timestamp_t* ts;
+        snd_pcm_uframes_t framesAvail;
+
+        // note: slight race condition if this is called simultaneously from 2 threads
+        ret = snd_pcm_status(info->handle, info->positionStatus);
+        if (ret != 0) {
+            ERROR1("ERROR in snd_pcm_status: %s\n", snd_strerror(ret));
+            result = javaBytePos;
+        } else {
+            // calculate from time value, or from available bytes
+            framesAvail = snd_pcm_status_get_avail(info->positionStatus);
+            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
+        }
+#endif
+#ifdef GET_POSITION_METHOD3
+        snd_pcm_uframes_t framesAvail;
+        ret = snd_pcm_avail(info->handle, &framesAvail);
+        if (ret != 0) {
+            ERROR1("ERROR in snd_pcm_avail: %s\n", snd_strerror(ret));
+            result = javaBytePos;
+        } else {
+            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
+        }
+#endif
+#ifdef GET_POSITION_METHOD1
+        result = estimatePositionFromAvail(info, isSource, javaBytePos, DAUDIO_GetAvailable(id, isSource));
+#endif
+    }
+    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
+    return result;
+}
+
+
+
+void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
+    /* save to ignore, since GetBytePosition
+     * takes the javaBytePos param into account
+     */
+}
+
+int DAUDIO_RequiresServicing(void* id, int isSource) {
+    // never need servicing on Linux
+    return FALSE;
+}
+
+void DAUDIO_Service(void* id, int isSource) {
+    // never need servicing on Linux
+}
+
+
+#endif // USE_DAUDIO
diff -r eb72d194235c -r 514c68575523 src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+//#define USE_ERROR
+//#define USE_TRACE
+
+#include "PLATFORM_API_LinuxOS_ALSA_PCMUtils.h"
+#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
+
+
+
+// callback for iteration through devices
+// returns TRUE if iteration should continue
+// NOTE: cardinfo may be NULL (for "default" device)
+typedef int (*DeviceIteratorPtr)(UINT32 deviceID, snd_pcm_info_t* pcminfo,
+                             snd_ctl_card_info_t* cardinfo, void *userData);
+
+// for each ALSA device, call iterator. userData is passed to the iterator
+// returns total number of iterations
+int iteratePCMDevices(DeviceIteratorPtr iterator, void* userData) {
+    int count = 0;
+    int subdeviceCount;
+    int card, dev, subDev;
+    char devname[16];
+    int err;
+    snd_ctl_t *handle;
+    snd_pcm_t *pcm;
+    snd_pcm_info_t* pcminfo;
+    snd_ctl_card_info_t *cardinfo, *defcardinfo = NULL;
+    UINT32 deviceID;
+    int doContinue = TRUE;
+
+    snd_pcm_info_malloc(&pcminfo);
+    snd_ctl_card_info_malloc(&cardinfo);
+
+    // 1st try "default" device
+    err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
+                       SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
+    if (err < 0) {
+        // try with the other direction
+        err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
+                           SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
+    }
+    if (err < 0) {
+        ERROR1("ERROR: snd_pcm_open (\"default\"): %s\n", snd_strerror(err));
+    } else {
+        err = snd_pcm_info(pcm, pcminfo);
+        snd_pcm_close(pcm);
+        if (err < 0) {
+            ERROR1("ERROR: snd_pcm_info (\"default\"): %s\n",
+                    snd_strerror(err));
+        } else {
+            // try to get card info
+            card = snd_pcm_info_get_card(pcminfo);
+            if (card >= 0) {
+                sprintf(devname, ALSA_HARDWARE_CARD, card);
+                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
+                    if (snd_ctl_card_info(handle, cardinfo) >= 0) {
+                        defcardinfo = cardinfo;
+                    }
+                    snd_ctl_close(handle);
+                }
+            }
+            // call callback function for the device
+            if (iterator != NULL) {
+                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, pcminfo,
+                                         defcardinfo, userData);
+            }
+            count++;
+        }
+    }
+
+    // iterate cards
+    card = -1;
+    while (doContinue) {
+        if (snd_card_next(&card) < 0) {
+            break;
+        }
+        if (card < 0) {
+            break;
+        }
+        sprintf(devname, ALSA_HARDWARE_CARD, card);
+        TRACE1("Opening alsa device \"%s\"...\n", devname);
+        err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
+        if (err < 0) {
+            ERROR2("ERROR: snd_ctl_open, card=%d: %s\n",
+                    card, snd_strerror(err));
+        } else {
+            err = snd_ctl_card_info(handle, cardinfo);
+            if (err < 0) {
+                ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n",
+                        card, snd_strerror(err));
+            } else {
+                dev = -1;
+                while (doContinue) {
+                    if (snd_ctl_pcm_next_device(handle, &dev) < 0) {
+                        ERROR0("snd_ctl_pcm_next_device\n");
+                    }
+                    if (dev < 0) {
+                        break;
+                    }
+                    snd_pcm_info_set_device(pcminfo, dev);
+                    snd_pcm_info_set_subdevice(pcminfo, 0);
+                    snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
+                    err = snd_ctl_pcm_info(handle, pcminfo);
+                    if (err == -ENOENT) {
+                        // try with the other direction
+                        snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
+                        err = snd_ctl_pcm_info(handle, pcminfo);
+                    }
+                    if (err < 0) {
+                        if (err != -ENOENT) {
+                            ERROR2("ERROR: snd_ctl_pcm_info, card=%d: %s",
+                                    card, snd_strerror(err));
+                        }
+                    } else {
+                        subdeviceCount = needEnumerateSubdevices(ALSA_PCM) ?
+                            snd_pcm_info_get_subdevices_count(pcminfo) : 1;
+                        if (iterator!=NULL) {
+                            for (subDev = 0; subDev < subdeviceCount; subDev++) {
+                                deviceID = encodeDeviceID(card, dev, subDev);
+                                doContinue = (*iterator)(deviceID, pcminfo,
+                                                         cardinfo, userData);
+                                count++;
+                                if (!doContinue) {
+                                    break;
+                                }
+                            }
+                        } else {
+                            count += subdeviceCount;
+                        }
+                    }
+                } // of while(doContinue)
+            }
+            snd_ctl_close(handle);
+        }
+    }
+    snd_ctl_card_info_free(cardinfo);
+    snd_pcm_info_free(pcminfo);
+    return count;
+}
+
+int getAudioDeviceCount() {
+    initAlsaSupport();
+    return iteratePCMDevices(NULL, NULL);
+}
+
+int deviceInfoIterator(UINT32 deviceID, snd_pcm_info_t* pcminfo,
+                       snd_ctl_card_info_t* cardinfo, void* userData) {
+    char buffer[300];
+    ALSA_AudioDeviceDescription* desc = (ALSA_AudioDeviceDescription*)userData;
+#ifdef ALSA_PCM_USE_PLUGHW
+    int usePlugHw = 1;
+#else
+    int usePlugHw = 0;
+#endif
+
+    initAlsaSupport();
+    if (desc->index == 0) {
+        // we found the device with correct index
+        *(desc->maxSimultaneousLines) = needEnumerateSubdevices(ALSA_PCM) ?
+                1 : snd_pcm_info_get_subdevices_count(pcminfo);
+        *desc->deviceID = deviceID;
+        buffer[0]=' '; buffer[1]='[';
+        // buffer[300] is enough to store the actual device string w/o overrun
+        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_PCM);
+        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
+        strncpy(desc->name,
+                (cardinfo != NULL)
+                    ? snd_ctl_card_info_get_id(cardinfo)
+                    : snd_pcm_info_get_id(pcminfo),
+                desc->strLen - strlen(buffer));
+        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
+        strncpy(desc->vendor, "ALSA (http://www.alsa-project.org)", desc->strLen);
+        strncpy(desc->description,
+                (cardinfo != NULL)
+                    ? snd_ctl_card_info_get_name(cardinfo)
+                    : snd_pcm_info_get_name(pcminfo),
+                desc->strLen);
+        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
+        strncat(desc->description, snd_pcm_info_get_id(pcminfo), desc->strLen - strlen(desc->description));
+        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
+        strncat(desc->description, snd_pcm_info_get_name(pcminfo), desc->strLen - strlen(desc->description));
+        getALSAVersion(desc->version, desc->strLen);
+        TRACE4("Returning %s, %s, %s, %s\n", desc->name, desc->vendor, desc->description, desc->version);
+        return FALSE; // do not continue iteration
+    }
+    desc->index--;
+    return TRUE;
+}
+
+// returns 0 if successful
+int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware) {
+    char buffer[200];
+    int ret;
+
+    initAlsaSupport();
+    getDeviceStringFromDeviceID(buffer, deviceID, !hardware, ALSA_PCM);
+
+    TRACE1("Opening ALSA device %s\n", buffer);
+    ret = snd_pcm_open(handle, buffer,
+                       isSource?SND_PCM_STREAM_PLAYBACK:SND_PCM_STREAM_CAPTURE,
+                       SND_PCM_NONBLOCK);
+    if (ret != 0) {
+        ERROR1("snd_pcm_open returned error code %d \n", ret);
+        *handle = NULL;
+    }
+    return ret;
+}
+
+
+int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc) {
+    initAlsaSupport();
+    TRACE1(" getAudioDeviceDescriptionByIndex(mixerIndex = %d\n", desc->index);
+    iteratePCMDevices(&deviceInfoIterator, desc);
+    return (desc->index == 0)?TRUE:FALSE;
+}
+
+// returns 1 if successful
+// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
+int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
+                            int* sampleSizeInBytes, int* significantBits,
+                            int* isSigned, int* isBigEndian, int* enc) {
+
+    *sampleSizeInBytes = (snd_pcm_format_physical_width(alsaFormat) + 7) / 8;
+    *significantBits = snd_pcm_format_width(alsaFormat);
+
+    // defaults
+    *enc = 0; // PCM
+    *isSigned = (snd_pcm_format_signed(alsaFormat) > 0);
+    *isBigEndian = (snd_pcm_format_big_endian(alsaFormat) > 0);
+
+    // non-PCM formats
+    if (alsaFormat == SND_PCM_FORMAT_MU_LAW) { // Mu-Law
+        *sampleSizeInBytes = 8; *enc = 1; *significantBits = *sampleSizeInBytes;
+    }
+    else if (alsaFormat == SND_PCM_FORMAT_A_LAW) {     // A-Law
+        *sampleSizeInBytes = 8; *enc = 2; *significantBits = *sampleSizeInBytes;
+    }
+    else if (snd_pcm_format_linear(alsaFormat) < 1) {
+        return 0;
+    }
+    return (*sampleSizeInBytes > 0);
+}
+
+// returns 1 if successful
+int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
+                            int sampleSizeInBytes, int significantBits,
+                            int isSigned, int isBigEndian, int enc) {
+    *alsaFormat = SND_PCM_FORMAT_UNKNOWN;
+
+    if (enc == 0) {
+        *alsaFormat = snd_pcm_build_linear_format(significantBits,
+                                                  sampleSizeInBytes * 8,
+                                                  isSigned?0:1,
+                                                  isBigEndian?1:0);
+    }
+    else if ((sampleSizeInBytes == 1) && (significantBits == 8)) {
+        if (enc == 1) { // ULAW
+            *alsaFormat = SND_PCM_FORMAT_MU_LAW;
+        }
+        else if (enc == 2) { // ALAW
+            *alsaFormat = SND_PCM_FORMAT_A_LAW;
+        }
+    }
+    return (*alsaFormat == SND_PCM_FORMAT_UNKNOWN)?0:1;
+}
+
+
+/* end */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2003, 2010, 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.
+ */
+
+// define this with a later version of ALSA than 0.9.0rc3
+// (starting from 1.0.0 it became default behaviour)
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#include 
+#include "Utilities.h"
+
+#ifndef PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
+#define PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
+
+// if this is defined, use plughw: devices
+#define ALSA_PCM_USE_PLUGHW
+//#undef ALSA_PCM_USE_PLUGHW
+
+
+// maximum number of channels that is listed in the formats. If more, than
+// just -1 for channel count is used.
+#define MAXIMUM_LISTED_CHANNELS 32
+
+typedef struct tag_ALSA_AudioDeviceDescription {
+    int index;          // in
+    int strLen;         // in
+    INT32* deviceID;    // out
+    int* maxSimultaneousLines; // out
+    char* name;         // out
+    char* vendor;       // out
+    char* description;  // out
+    char* version;      // out
+} ALSA_AudioDeviceDescription;
+
+
+
+int getAudioDeviceCount();
+int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc);
+
+// returns ALSA error code, or 0 if successful
+int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware);
+
+// returns 1 if successful
+// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
+int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
+                            int* sampleSizeInBytes, int* significantBits,
+                            int* isSigned, int* isBigEndian, int* enc);
+
+int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
+                            int sampleSizeInBytes, int significantBits,
+                            int isSigned, int isBigEndian, int enc);
+
+#endif // PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,724 @@
+/*
+ * 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.  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.
+ */
+
+#define USE_ERROR
+//#define USE_TRACE
+
+#include "Ports.h"
+#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
+#include 
+
+#if USE_PORTS == TRUE
+
+#define MAX_ELEMS (300)
+#define MAX_CONTROLS (MAX_ELEMS * 4)
+
+#define CHANNELS_MONO (SND_MIXER_SCHN_LAST + 1)
+#define CHANNELS_STEREO (SND_MIXER_SCHN_LAST + 2)
+
+typedef struct {
+    snd_mixer_elem_t* elem;
+    INT32 portType; /* one of PORT_XXX_xx */
+    char* controlType; /* one of CONTROL_TYPE_xx */
+    /* Values: either SND_MIXER_SCHN_FRONT_xx, CHANNELS_MONO or CHANNELS_STEREO.
+       For SND_MIXER_SCHN_FRONT_xx, exactly this channel is set/retrieved directly.
+       For CHANNELS_MONO, ALSA channel SND_MIXER_SCHN_MONO is set/retrieved directly.
+       For CHANNELS_STEREO, ALSA channels SND_MIXER_SCHN_FRONT_LEFT and SND_MIXER_SCHN_FRONT_RIGHT
+       are set after a calculation that takes balance into account. Retrieved? Average of both
+       channels? (Using a cached value is not a good idea since the value in the HW may have been
+       altered.) */
+    INT32 channel;
+} PortControl;
+
+
+typedef struct tag_PortMixer {
+    snd_mixer_t* mixer_handle;
+    /* Number of array elements used in elems and types. */
+    int numElems;
+    snd_mixer_elem_t** elems;
+    /* Array of port types (PORT_SRC_UNKNOWN etc.). Indices are the same as in elems. */
+    INT32* types;
+    /* Number of array elements used in controls. */
+    int numControls;
+    PortControl* controls;
+} PortMixer;
+
+
+///// implemented functions of Ports.h
+
+INT32 PORT_GetPortMixerCount() {
+    INT32 mixerCount;
+    int card;
+    char devname[16];
+    int err;
+    snd_ctl_t *handle;
+    snd_ctl_card_info_t* info;
+
+    TRACE0("> PORT_GetPortMixerCount\n");
+
+    initAlsaSupport();
+
+    snd_ctl_card_info_malloc(&info);
+    card = -1;
+    mixerCount = 0;
+    if (snd_card_next(&card) >= 0) {
+        while (card >= 0) {
+            sprintf(devname, ALSA_HARDWARE_CARD, card);
+            TRACE1("PORT_GetPortMixerCount: Opening alsa device \"%s\"...\n", devname);
+            err = snd_ctl_open(&handle, devname, 0);
+            if (err < 0) {
+                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
+            } else {
+                mixerCount++;
+                snd_ctl_close(handle);
+            }
+            if (snd_card_next(&card) < 0) {
+                break;
+            }
+        }
+    }
+    snd_ctl_card_info_free(info);
+    TRACE0("< PORT_GetPortMixerCount\n");
+    return mixerCount;
+}
+
+
+INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
+    snd_ctl_t* handle;
+    snd_ctl_card_info_t* card_info;
+    char devname[16];
+    int err;
+    char buffer[100];
+
+    TRACE0("> PORT_GetPortMixerDescription\n");
+    snd_ctl_card_info_malloc(&card_info);
+
+    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
+    TRACE1("Opening alsa device \"%s\"...\n", devname);
+    err = snd_ctl_open(&handle, devname, 0);
+    if (err < 0) {
+        ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
+        return FALSE;
+    }
+    err = snd_ctl_card_info(handle, card_info);
+    if (err < 0) {
+        ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
+    }
+    strncpy(description->name, snd_ctl_card_info_get_id(card_info), PORT_STRING_LENGTH - 1);
+    sprintf(buffer, " [%s]", devname);
+    strncat(description->name, buffer, PORT_STRING_LENGTH - 1 - strlen(description->name));
+    strncpy(description->vendor, "ALSA (http://www.alsa-project.org)", PORT_STRING_LENGTH - 1);
+    strncpy(description->description, snd_ctl_card_info_get_name(card_info), PORT_STRING_LENGTH - 1);
+    strncat(description->description, ", ", PORT_STRING_LENGTH - 1 - strlen(description->description));
+    strncat(description->description, snd_ctl_card_info_get_mixername(card_info), PORT_STRING_LENGTH - 1 - strlen(description->description));
+    getALSAVersion(description->version, PORT_STRING_LENGTH - 1);
+
+    snd_ctl_close(handle);
+    snd_ctl_card_info_free(card_info);
+    TRACE0("< PORT_GetPortMixerDescription\n");
+    return TRUE;
+}
+
+
+void* PORT_Open(INT32 mixerIndex) {
+    char devname[16];
+    snd_mixer_t* mixer_handle;
+    int err;
+    PortMixer* handle;
+
+    TRACE0("> PORT_Open\n");
+    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
+    if ((err = snd_mixer_open(&mixer_handle, 0)) < 0) {
+        ERROR2("Mixer %s open error: %s", devname, snd_strerror(err));
+        return NULL;
+    }
+    if ((err = snd_mixer_attach(mixer_handle, devname)) < 0) {
+        ERROR2("Mixer attach %s error: %s", devname, snd_strerror(err));
+        snd_mixer_close(mixer_handle);
+        return NULL;
+    }
+    if ((err = snd_mixer_selem_register(mixer_handle, NULL, NULL)) < 0) {
+        ERROR1("Mixer register error: %s", snd_strerror(err));
+        snd_mixer_close(mixer_handle);
+        return NULL;
+    }
+    err = snd_mixer_load(mixer_handle);
+    if (err < 0) {
+        ERROR2("Mixer %s load error: %s", devname, snd_strerror(err));
+        snd_mixer_close(mixer_handle);
+        return NULL;
+    }
+    handle = (PortMixer*) calloc(1, sizeof(PortMixer));
+    if (handle == NULL) {
+        ERROR0("malloc() failed.");
+        snd_mixer_close(mixer_handle);
+        return NULL;
+    }
+    handle->numElems = 0;
+    handle->elems = (snd_mixer_elem_t**) calloc(MAX_ELEMS, sizeof(snd_mixer_elem_t*));
+    if (handle->elems == NULL) {
+        ERROR0("malloc() failed.");
+        snd_mixer_close(mixer_handle);
+        free(handle);
+        return NULL;
+    }
+    handle->types = (INT32*) calloc(MAX_ELEMS, sizeof(INT32));
+    if (handle->types == NULL) {
+        ERROR0("malloc() failed.");
+        snd_mixer_close(mixer_handle);
+        free(handle->elems);
+        free(handle);
+        return NULL;
+    }
+    handle->controls = (PortControl*) calloc(MAX_CONTROLS, sizeof(PortControl));
+    if (handle->controls == NULL) {
+        ERROR0("malloc() failed.");
+        snd_mixer_close(mixer_handle);
+        free(handle->elems);
+        free(handle->types);
+        free(handle);
+        return NULL;
+    }
+    handle->mixer_handle = mixer_handle;
+    // necessary to initialize data structures
+    PORT_GetPortCount(handle);
+    TRACE0("< PORT_Open\n");
+    return handle;
+}
+
+
+void PORT_Close(void* id) {
+    TRACE0("> PORT_Close\n");
+    if (id != NULL) {
+        PortMixer* handle = (PortMixer*) id;
+        if (handle->mixer_handle != NULL) {
+            snd_mixer_close(handle->mixer_handle);
+        }
+        if (handle->elems != NULL) {
+            free(handle->elems);
+        }
+        if (handle->types != NULL) {
+            free(handle->types);
+        }
+        if (handle->controls != NULL) {
+            free(handle->controls);
+        }
+        free(handle);
+    }
+    TRACE0("< PORT_Close\n");
+}
+
+
+
+INT32 PORT_GetPortCount(void* id) {
+    PortMixer* portMixer;
+    snd_mixer_elem_t *elem;
+
+    TRACE0("> PORT_GetPortCount\n");
+    if (id == NULL) {
+        // $$mp: Should become a descriptive error code (invalid handle).
+        return -1;
+    }
+    portMixer = (PortMixer*) id;
+    if (portMixer->numElems == 0) {
+        for (elem = snd_mixer_first_elem(portMixer->mixer_handle); elem; elem = snd_mixer_elem_next(elem)) {
+            if (!snd_mixer_selem_is_active(elem))
+                continue;
+            TRACE2("Simple mixer control '%s',%i\n",
+                   snd_mixer_selem_get_name(elem),
+                   snd_mixer_selem_get_index(elem));
+            if (snd_mixer_selem_has_playback_volume(elem)) {
+                portMixer->elems[portMixer->numElems] = elem;
+                portMixer->types[portMixer->numElems] = PORT_DST_UNKNOWN;
+                portMixer->numElems++;
+            }
+            // to prevent buffer overflow
+            if (portMixer->numElems >= MAX_ELEMS) {
+                break;
+            }
+            /* If an element has both playback an capture volume, it is put into the arrays
+               twice. */
+            if (snd_mixer_selem_has_capture_volume(elem)) {
+                portMixer->elems[portMixer->numElems] = elem;
+                portMixer->types[portMixer->numElems] = PORT_SRC_UNKNOWN;
+                portMixer->numElems++;
+            }
+            // to prevent buffer overflow
+            if (portMixer->numElems >= MAX_ELEMS) {
+                break;
+            }
+        }
+    }
+    TRACE0("< PORT_GetPortCount\n");
+    return portMixer->numElems;
+}
+
+
+INT32 PORT_GetPortType(void* id, INT32 portIndex) {
+    PortMixer* portMixer;
+    INT32 type;
+    TRACE0("> PORT_GetPortType\n");
+    if (id == NULL) {
+        // $$mp: Should become a descriptive error code (invalid handle).
+        return -1;
+    }
+    portMixer = (PortMixer*) id;
+    if (portIndex < 0 || portIndex >= portMixer->numElems) {
+        // $$mp: Should become a descriptive error code (index out of bounds).
+        return -1;
+    }
+    type = portMixer->types[portIndex];
+    TRACE0("< PORT_GetPortType\n");
+    return type;
+}
+
+
+INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
+    PortMixer* portMixer;
+    const char* nam;
+
+    TRACE0("> PORT_GetPortName\n");
+    if (id == NULL) {
+        // $$mp: Should become a descriptive error code (invalid handle).
+        return -1;
+    }
+    portMixer = (PortMixer*) id;
+    if (portIndex < 0 || portIndex >= portMixer->numElems) {
+        // $$mp: Should become a descriptive error code (index out of bounds).
+        return -1;
+    }
+    nam = snd_mixer_selem_get_name(portMixer->elems[portIndex]);
+    strncpy(name, nam, len - 1);
+    name[len - 1] = 0;
+    TRACE0("< PORT_GetPortName\n");
+    return TRUE;
+}
+
+
+static int isPlaybackFunction(INT32 portType) {
+        return (portType & PORT_DST_MASK);
+}
+
+
+/* Sets portControl to a pointer to the next free array element in the PortControl (pointer)
+   array of the passed portMixer. Returns TRUE if successful. May return FALSE if there is no
+   free slot. In this case, portControl is not altered */
+static int getControlSlot(PortMixer* portMixer, PortControl** portControl) {
+    if (portMixer->numControls >= MAX_CONTROLS) {
+        return FALSE;
+    } else {
+        *portControl = &(portMixer->controls[portMixer->numControls]);
+        portMixer->numControls++;
+        return TRUE;
+    }
+}
+
+
+/* Protect against illegal min-max values, preventing divisions by zero.
+ */
+inline static long getRange(long min, long max) {
+    if (max > min) {
+        return max - min;
+    } else {
+        return 1;
+    }
+}
+
+
+/* Idea: we may specify that if unit is an empty string, the values are linear and if unit is "dB",
+   the values are logarithmic.
+*/
+static void* createVolumeControl(PortControlCreator* creator,
+                                 PortControl* portControl,
+                                 snd_mixer_elem_t* elem, int isPlayback) {
+    void* control;
+    float precision;
+    long min, max;
+
+    if (isPlayback) {
+        snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
+    } else {
+        snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
+    }
+    /* $$mp: The volume values retrieved with the ALSA API are strongly supposed to be logarithmic.
+       So the following calculation is wrong. However, there is no correct calculation, since
+       for equal-distant logarithmic steps, the precision expressed in linear varies over the
+       scale. */
+    precision = 1.0F / getRange(min, max);
+    control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_VOLUME, 0.0F, +1.0F, precision, "");
+    return control;
+}
+
+
+void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
+    PortMixer* portMixer;
+    snd_mixer_elem_t* elem;
+    void* control;
+    PortControl* portControl;
+    void* controls[10];
+    int numControls;
+    char* portName;
+    int isPlayback = 0;
+    int isMono;
+    int isStereo;
+    char* type;
+    snd_mixer_selem_channel_id_t channel;
+    memset(controls, 0, sizeof(controls));
+
+    TRACE0("> PORT_GetControls\n");
+    if (id == NULL) {
+        ERROR0("Invalid handle!");
+        // $$mp: an error code should be returned.
+        return;
+    }
+    portMixer = (PortMixer*) id;
+    if (portIndex < 0 || portIndex >= portMixer->numElems) {
+        ERROR0("Port index out of range!");
+        // $$mp: an error code should be returned.
+        return;
+    }
+    numControls = 0;
+    elem = portMixer->elems[portIndex];
+    if (snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_capture_volume(elem)) {
+        /* Since we've split/duplicated elements with both playback and capture on the recovery
+           of elements, we now can assume that we handle only to deal with either playback or
+           capture. */
+        isPlayback = isPlaybackFunction(portMixer->types[portIndex]);
+        isMono = (isPlayback && snd_mixer_selem_is_playback_mono(elem)) ||
+            (!isPlayback && snd_mixer_selem_is_capture_mono(elem));
+        isStereo = (isPlayback &&
+                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
+                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) ||
+            (!isPlayback &&
+             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
+             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT));
+        // single volume control
+        if (isMono || isStereo) {
+            if (getControlSlot(portMixer, &portControl)) {
+                portControl->elem = elem;
+                portControl->portType = portMixer->types[portIndex];
+                portControl->controlType = CONTROL_TYPE_VOLUME;
+                if (isMono) {
+                    portControl->channel = CHANNELS_MONO;
+                } else {
+                    portControl->channel = CHANNELS_STEREO;
+                }
+                control = createVolumeControl(creator, portControl, elem, isPlayback);
+                if (control != NULL) {
+                    controls[numControls++] = control;
+                }
+            }
+        } else { // more than two channels, each channels has its own control.
+            for (channel = SND_MIXER_SCHN_FRONT_LEFT; channel <= SND_MIXER_SCHN_LAST; channel++) {
+                if ((isPlayback && snd_mixer_selem_has_playback_channel(elem, channel)) ||
+                    (!isPlayback && snd_mixer_selem_has_capture_channel(elem, channel))) {
+                    if (getControlSlot(portMixer, &portControl)) {
+                        portControl->elem = elem;
+                        portControl->portType = portMixer->types[portIndex];
+                        portControl->controlType = CONTROL_TYPE_VOLUME;
+                        portControl->channel = channel;
+                        control = createVolumeControl(creator, portControl, elem, isPlayback);
+                        // We wrap in a compound control to provide the channel name.
+                        if (control != NULL) {
+                            /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
+                               declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
+                               to take a const char* parameter. */
+                            control = (creator->newCompoundControl)(creator, (char*) snd_mixer_selem_channel_name(channel), &control, 1);
+                        }
+                        if (control != NULL) {
+                            controls[numControls++] = control;
+                        }
+                    }
+                }
+            }
+        }
+        // BALANCE control
+        if (isStereo) {
+            if (getControlSlot(portMixer, &portControl)) {
+                portControl->elem = elem;
+                portControl->portType = portMixer->types[portIndex];
+                portControl->controlType = CONTROL_TYPE_BALANCE;
+                portControl->channel = CHANNELS_STEREO;
+                /* $$mp: The value for precision is chosen more or less arbitrarily. */
+                control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_BALANCE, -1.0F, 1.0F, 0.01F, "");
+                if (control != NULL) {
+                    controls[numControls++] = control;
+                }
+            }
+        }
+    }
+    if (snd_mixer_selem_has_playback_switch(elem) || snd_mixer_selem_has_capture_switch(elem)) {
+        if (getControlSlot(portMixer, &portControl)) {
+            type = isPlayback ? CONTROL_TYPE_MUTE : CONTROL_TYPE_SELECT;
+            portControl->elem = elem;
+            portControl->portType = portMixer->types[portIndex];
+            portControl->controlType = type;
+            control = (creator->newBooleanControl)(creator, portControl, type);
+            if (control != NULL) {
+                controls[numControls++] = control;
+            }
+        }
+    }
+    /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
+       declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
+       to take a const char* parameter. */
+    portName = (char*) snd_mixer_selem_get_name(elem);
+    control = (creator->newCompoundControl)(creator, portName, controls, numControls);
+    if (control != NULL) {
+        (creator->addControl)(creator, control);
+    }
+    TRACE0("< PORT_GetControls\n");
+}
+
+
+INT32 PORT_GetIntValue(void* controlIDV) {
+    PortControl* portControl = (PortControl*) controlIDV;
+    int value = 0;
+    snd_mixer_selem_channel_id_t channel;
+
+    if (portControl != NULL) {
+        switch (portControl->channel) {
+        case CHANNELS_MONO:
+            channel = SND_MIXER_SCHN_MONO;
+            break;
+
+        case CHANNELS_STEREO:
+            channel = SND_MIXER_SCHN_FRONT_LEFT;
+            break;
+
+        default:
+            channel = portControl->channel;
+        }
+        if (portControl->controlType == CONTROL_TYPE_MUTE ||
+            portControl->controlType == CONTROL_TYPE_SELECT) {
+            if (isPlaybackFunction(portControl->portType)) {
+                snd_mixer_selem_get_playback_switch(portControl->elem, channel, &value);
+            } else {
+                snd_mixer_selem_get_capture_switch(portControl->elem, channel, &value);
+            }
+            if (portControl->controlType == CONTROL_TYPE_MUTE) {
+                value = ! value;
+            }
+        } else {
+            ERROR1("PORT_GetIntValue(): inappropriate control type: %s\n",
+                   portControl->controlType);
+        }
+    }
+    return (INT32) value;
+}
+
+
+void PORT_SetIntValue(void* controlIDV, INT32 value) {
+    PortControl* portControl = (PortControl*) controlIDV;
+    snd_mixer_selem_channel_id_t channel;
+
+    if (portControl != NULL) {
+        if (portControl->controlType == CONTROL_TYPE_MUTE) {
+            value = ! value;
+        }
+        if (portControl->controlType == CONTROL_TYPE_MUTE ||
+            portControl->controlType == CONTROL_TYPE_SELECT) {
+            if (isPlaybackFunction(portControl->portType)) {
+                snd_mixer_selem_set_playback_switch_all(portControl->elem, value);
+            } else {
+                snd_mixer_selem_set_capture_switch_all(portControl->elem, value);
+            }
+        } else {
+            ERROR1("PORT_SetIntValue(): inappropriate control type: %s\n",
+                   portControl->controlType);
+        }
+    }
+}
+
+
+static float scaleVolumeValueToNormalized(long value, long min, long max) {
+    return (float) (value - min) / getRange(min, max);
+}
+
+
+static long scaleVolumeValueToHardware(float value, long min, long max) {
+    return (long)(value * getRange(min, max) + min);
+}
+
+
+float getRealVolume(PortControl* portControl,
+                    snd_mixer_selem_channel_id_t channel) {
+    float fValue;
+    long lValue = 0;
+    long min = 0;
+    long max = 0;
+
+    if (isPlaybackFunction(portControl->portType)) {
+        snd_mixer_selem_get_playback_volume_range(portControl->elem,
+                                                  &min, &max);
+        snd_mixer_selem_get_playback_volume(portControl->elem,
+                                            channel, &lValue);
+    } else {
+        snd_mixer_selem_get_capture_volume_range(portControl->elem,
+                                                 &min, &max);
+        snd_mixer_selem_get_capture_volume(portControl->elem,
+                                           channel, &lValue);
+    }
+    fValue = scaleVolumeValueToNormalized(lValue, min, max);
+    return fValue;
+}
+
+
+void setRealVolume(PortControl* portControl,
+                   snd_mixer_selem_channel_id_t channel, float value) {
+    long lValue = 0;
+    long min = 0;
+    long max = 0;
+
+    if (isPlaybackFunction(portControl->portType)) {
+        snd_mixer_selem_get_playback_volume_range(portControl->elem,
+                                                  &min, &max);
+        lValue = scaleVolumeValueToHardware(value, min, max);
+        snd_mixer_selem_set_playback_volume(portControl->elem,
+                                            channel, lValue);
+    } else {
+        snd_mixer_selem_get_capture_volume_range(portControl->elem,
+                                                 &min, &max);
+        lValue = scaleVolumeValueToHardware(value, min, max);
+        snd_mixer_selem_set_capture_volume(portControl->elem,
+                                           channel, lValue);
+    }
+}
+
+
+static float getFakeBalance(PortControl* portControl) {
+    float volL, volR;
+
+    // pan is the ratio of left and right
+    volL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
+    volR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
+    if (volL > volR) {
+        return -1.0f + (volR / volL);
+    }
+    else if (volR > volL) {
+        return 1.0f - (volL / volR);
+    }
+    return 0.0f;
+}
+
+
+static float getFakeVolume(PortControl* portControl) {
+    float valueL;
+    float valueR;
+    float value;
+
+    valueL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
+    valueR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
+    // volume is the greater value of both
+    value = valueL > valueR ? valueL : valueR ;
+    return value;
+}
+
+
+/*
+ * sets the unsigned values for left and right volume according to
+ * the given volume (0...1) and balance (-1..0..+1)
+ */
+static void setFakeVolume(PortControl* portControl, float vol, float bal) {
+    float volumeLeft;
+    float volumeRight;
+
+    if (bal < 0.0f) {
+        volumeLeft = vol;
+        volumeRight = vol * (bal + 1.0f);
+    } else {
+        volumeLeft = vol * (1.0f - bal);
+        volumeRight = vol;
+    }
+    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT, volumeLeft);
+    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT, volumeRight);
+}
+
+
+float PORT_GetFloatValue(void* controlIDV) {
+    PortControl* portControl = (PortControl*) controlIDV;
+    float value = 0.0F;
+
+    if (portControl != NULL) {
+        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
+            switch (portControl->channel) {
+            case CHANNELS_MONO:
+                value = getRealVolume(portControl, SND_MIXER_SCHN_MONO);
+                break;
+
+            case CHANNELS_STEREO:
+                value = getFakeVolume(portControl);
+                break;
+
+            default:
+                value = getRealVolume(portControl, portControl->channel);
+            }
+        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
+            if (portControl->channel == CHANNELS_STEREO) {
+                value = getFakeBalance(portControl);
+            } else {
+                ERROR0("PORT_GetFloatValue(): Balance only allowed for stereo channels!\n");
+            }
+        } else {
+            ERROR1("PORT_GetFloatValue(): inappropriate control type: %s!\n",
+                   portControl->controlType);
+        }
+    }
+    return value;
+}
+
+
+void PORT_SetFloatValue(void* controlIDV, float value) {
+    PortControl* portControl = (PortControl*) controlIDV;
+
+    if (portControl != NULL) {
+        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
+            switch (portControl->channel) {
+            case CHANNELS_MONO:
+                setRealVolume(portControl, SND_MIXER_SCHN_MONO, value);
+                break;
+
+            case CHANNELS_STEREO:
+                setFakeVolume(portControl, value, getFakeBalance(portControl));
+                break;
+
+            default:
+                setRealVolume(portControl, portControl->channel, value);
+            }
+        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
+            if (portControl->channel == CHANNELS_STEREO) {
+                setFakeVolume(portControl, getFakeVolume(portControl), value);
+            } else {
+                ERROR0("PORT_SetFloatValue(): Balance only allowed for stereo channels!\n");
+            }
+        } else {
+            ERROR1("PORT_SetFloatValue(): inappropriate control type: %s!\n",
+                   portControl->controlType);
+        }
+    }
+}
+
+
+#endif // USE_PORTS
diff -r eb72d194235c -r 514c68575523 src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Mar 23 18:44:47 2018 +0000
@@ -859,7 +859,7 @@
     @Override
     public void updateFocusableWindowState() {
         final boolean isFocusable = isNativelyFocusableWindow();
-        setStyleBits(SHOULD_BECOME_KEY | SHOULD_BECOME_MAIN, isFocusable); // set both bits at once
+        setStyleBits(SHOULD_BECOME_KEY | SHOULD_BECOME_MAIN | RESIZABLE, isFocusable); // set bits at once
     }
 
     @Override
diff -r eb72d194235c -r 514c68575523 src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -30,6 +30,7 @@
     static final String VERSION_2 = "BMP v. 2.x";
     static final String VERSION_3 = "BMP v. 3.x";
     static final String VERSION_3_NT = "BMP v. 3.x NT";
+    static final String VERSION_3_EXT = "BMP V2/V3 INFO";
     static final String VERSION_4 = "BMP v. 4.x";
     static final String VERSION_5 = "BMP v. 5.x";
 
@@ -48,3 +49,4 @@
     static final int BI_JPEG = 4;
     static final int BI_PNG = 5;
 }
+
diff -r eb72d194235c -r 514c68575523 src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -78,6 +78,8 @@
  *
  *  This class supports Microsoft Windows Bitmap Version 3-5,
  *  as well as OS/2 Bitmap Version 2.x (for single-image BMP file).
+ *  It also supports undocumented DIB header of type BITMAPV2INFOHEADER
+ *  & BITMAPV3INFOHEADER.
  */
 public class BMPImageReader extends ImageReader implements BMPConstants {
     // BMP Image types
@@ -94,16 +96,25 @@
     private static final int VERSION_3_NT_16_BIT = 8;
     private static final int VERSION_3_NT_32_BIT = 9;
 
-    private static final int VERSION_4_1_BIT = 10;
-    private static final int VERSION_4_4_BIT = 11;
-    private static final int VERSION_4_8_BIT = 12;
-    private static final int VERSION_4_16_BIT = 13;
-    private static final int VERSION_4_24_BIT = 14;
-    private static final int VERSION_4_32_BIT = 15;
+    // All VERSION_3_EXT_* are for BITMAPV2INFOHEADER & BITMAPV3INFOHEADER
+    private static final int VERSION_3_EXT_1_BIT = 10;
+    private static final int VERSION_3_EXT_4_BIT = 11;
+    private static final int VERSION_3_EXT_8_BIT = 12;
+    private static final int VERSION_3_EXT_16_BIT = 13;
+    private static final int VERSION_3_EXT_24_BIT = 14;
+    private static final int VERSION_3_EXT_32_BIT = 15;
 
-    private static final int VERSION_3_XP_EMBEDDED = 16;
-    private static final int VERSION_4_XP_EMBEDDED = 17;
-    private static final int VERSION_5_XP_EMBEDDED = 18;
+    private static final int VERSION_4_1_BIT = 16;
+    private static final int VERSION_4_4_BIT = 17;
+    private static final int VERSION_4_8_BIT = 18;
+    private static final int VERSION_4_16_BIT = 19;
+    private static final int VERSION_4_24_BIT = 20;
+    private static final int VERSION_4_32_BIT = 21;
+
+    private static final int VERSION_3_XP_EMBEDDED = 22;
+    private static final int VERSION_3_EXT_EMBEDDED = 23;
+    private static final int VERSION_4_XP_EMBEDDED = 24;
+    private static final int VERSION_5_XP_EMBEDDED = 25;
 
     // BMP variables
     private long bitmapFileSize;
@@ -409,6 +420,63 @@
                     throw new
                         IIOException(I18N.getString("BMPImageReader2"));
                 }
+            } else if (size == 52 || size == 56) {
+                // BITMAPV2INFOHEADER or BITMAPV3INFOHEADER
+                redMask = (int)iis.readUnsignedInt();
+                greenMask = (int)iis.readUnsignedInt();
+                blueMask = (int)iis.readUnsignedInt();
+                if (size == 56) {
+                    alphaMask = (int)iis.readUnsignedInt();
+                }
+
+                metadata.bmpVersion = VERSION_3_EXT;
+                // Read in the palette
+                int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
+                int sizeOfPalette = numberOfEntries*4;
+                palette = new byte[sizeOfPalette];
+                iis.readFully(palette, 0, sizeOfPalette);
+                metadata.palette = palette;
+                metadata.paletteSize = numberOfEntries;
+
+                switch((int)compression) {
+
+                    case BI_JPEG:
+                    case BI_PNG:
+                        imageType = VERSION_3_EXT_EMBEDDED;
+                        break;
+                    default:
+                        if (bitsPerPixel == 1) {
+                            imageType = VERSION_3_EXT_1_BIT;
+                        } else if (bitsPerPixel == 4) {
+                            imageType = VERSION_3_EXT_4_BIT;
+                        } else if (bitsPerPixel == 8) {
+                            imageType = VERSION_3_EXT_8_BIT;
+                        } else if (bitsPerPixel == 16) {
+                            imageType = VERSION_3_EXT_16_BIT;
+                            if ((int)compression == BI_RGB) {
+                                redMask = 0x7C00;
+                                greenMask = 0x3E0;
+                                blueMask = 0x1F;
+                            }
+                        } else if (bitsPerPixel == 24) {
+                            imageType = VERSION_3_EXT_24_BIT;
+                        } else if (bitsPerPixel == 32) {
+                            imageType = VERSION_3_EXT_32_BIT;
+                            if ((int)compression == BI_RGB) {
+                                redMask   = 0x00FF0000;
+                                greenMask = 0x0000FF00;
+                                blueMask  = 0x000000FF;
+                            }
+                        } else {
+                            throw new
+                            IIOException(I18N.getString("BMPImageReader8"));
+                        }
+
+                        metadata.redMask = redMask;
+                        metadata.greenMask = greenMask;
+                        metadata.blueMask = blueMask;
+                        metadata.alphaMask = alphaMask;
+                }
             } else if (size == 108 || size == 124) {
                 // Windows 4.x BMP
                 if (size == 108)
@@ -908,15 +976,18 @@
             break;
 
         case VERSION_3_XP_EMBEDDED:
+        case VERSION_3_EXT_EMBEDDED:
         case VERSION_4_XP_EMBEDDED:
         case VERSION_5_XP_EMBEDDED:
             bi = readEmbedded((int)compression, bi, param);
             break;
 
+        case VERSION_3_EXT_1_BIT:
         case VERSION_4_1_BIT:
             read1Bit(bdata);
             break;
 
+        case VERSION_3_EXT_4_BIT:
         case VERSION_4_4_BIT:
             switch((int)compression) {
 
@@ -934,6 +1005,7 @@
             }
             break;
 
+        case VERSION_3_EXT_8_BIT:
         case VERSION_4_8_BIT:
             switch((int)compression) {
 
@@ -951,14 +1023,17 @@
             }
             break;
 
+        case VERSION_3_EXT_16_BIT:
         case VERSION_4_16_BIT:
             read16Bit(sdata);
             break;
 
+        case VERSION_3_EXT_24_BIT:
         case VERSION_4_24_BIT:
             read24Bit(bdata);
             break;
 
+        case VERSION_3_EXT_32_BIT:
         case VERSION_4_32_BIT:
             read32Bit(idata);
             break;
@@ -2000,3 +2075,4 @@
         }
     }
 }
+
diff -r eb72d194235c -r 514c68575523 src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageMetadataFormat.java
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageMetadataFormat.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageMetadataFormat.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -119,10 +119,10 @@
                      "1", "65535", true, true);
         addAttribute("PlainTextExtension", "characterCellWidth",
                      DATATYPE_INTEGER, true, null,
-                     "1", "65535", true, true);
+                     "1", "255", true, true);
         addAttribute("PlainTextExtension", "characterCellHeight",
                      DATATYPE_INTEGER, true, null,
-                     "1", "65535", true, true);
+                     "1", "255", true, true);
         addAttribute("PlainTextExtension", "textForegroundColor",
                      DATATYPE_INTEGER, true, null,
                      "0", "255", true, true);
diff -r eb72d194235c -r 514c68575523 src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFWritableImageMetadata.java
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFWritableImageMetadata.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFWritableImageMetadata.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, 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
@@ -203,15 +203,18 @@
                                                  -1, true,
                                                  true, 1, 65535);
 
+                // As per the specification (89a), character cell width
+                // and character cell height occupy one byte each
+                // in the Plain Text Extension block.
                 characterCellWidth = getIntAttribute(node,
                                                      "characterCellWidth",
                                                      -1, true,
-                                                     true, 1, 65535);
+                                                     true, 1, 255);
 
                 characterCellHeight = getIntAttribute(node,
                                                       "characterCellHeight",
                                                       -1, true,
-                                                      true, 1, 65535);
+                                                      true, 1, 255);
 
                 textForegroundColor = getIntAttribute(node,
                                                       "textForegroundColor",
diff -r eb72d194235c -r 514c68575523 src/java.desktop/share/classes/com/sun/media/sound/Platform.java
--- a/src/java.desktop/share/classes/com/sun/media/sound/Platform.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/share/classes/com/sun/media/sound/Platform.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, 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,23 +38,9 @@
 final class Platform {
 
     // native library we need to load
-    private static final String libNameMain     = "jsound";
-    private static final String libNameALSA     = "jsoundalsa";
-    private static final String libNameDSound   = "jsoundds";
-
-    // extra libs handling: bit flags for each different library
-    public static final int LIB_MAIN     = 1;
-    public static final int LIB_ALSA     = 2;
-    public static final int LIB_DSOUND   = 4;
+    private static final String libName = "jsound";
 
-    // bit field of the constants above. Willbe set in loadLibraries
-    private static int loadedLibs = 0;
-
-    // features: the main native library jsound reports which feature is
-    // contained in which lib
-    public static final int FEATURE_MIDIIO       = 1;
-    public static final int FEATURE_PORTS        = 2;
-    public static final int FEATURE_DIRECT_AUDIO = 3;
+    private static boolean isNativeLibLoaded;
 
     // SYSTEM CHARACTERISTICS
     // vary according to hardware architecture
@@ -66,7 +52,6 @@
         if(Printer.trace)Printer.trace(">> Platform.java: static");
 
         loadLibraries();
-        readProperties();
     }
 
     /**
@@ -95,72 +80,37 @@
     private static void loadLibraries() {
         if(Printer.trace)Printer.trace(">>Platform.loadLibraries");
 
-        // load the main library
-        AccessController.doPrivileged((PrivilegedAction) () -> {
-            System.loadLibrary(libNameMain);
-            return null;
-        });
-        // just for the heck of it...
-        loadedLibs |= LIB_MAIN;
-
-        // now try to load extra libs. They are defined at compile time in the Makefile
-        // with the define EXTRA_SOUND_JNI_LIBS
-        String extraLibs = nGetExtraLibraries();
-        // the string is the libraries, separated by white space
-        StringTokenizer st = new StringTokenizer(extraLibs);
-        while (st.hasMoreTokens()) {
-            final String lib = st.nextToken();
-            try {
-                AccessController.doPrivileged((PrivilegedAction) () -> {
-                    System.loadLibrary(lib);
-                    return null;
-                });
-
-                if (lib.equals(libNameALSA)) {
-                    loadedLibs |= LIB_ALSA;
-                    if (Printer.debug) Printer.debug("Loaded ALSA lib successfully.");
-                } else if (lib.equals(libNameDSound)) {
-                    loadedLibs |= LIB_DSOUND;
-                    if (Printer.debug) Printer.debug("Loaded DirectSound lib successfully.");
-                } else {
-                    if (Printer.err) Printer.err("Loaded unknown lib '"+lib+"' successfully.");
-                }
-            } catch (Throwable t) {
-                if (Printer.err) Printer.err("Couldn't load library "+lib+": "+t.toString());
-            }
+        // load the native library
+        isNativeLibLoaded = true;
+        try {
+            AccessController.doPrivileged((PrivilegedAction) () -> {
+                System.loadLibrary(libName);
+                return null;
+            });
+        } catch (Throwable t) {
+            if (Printer.err) Printer.err("Couldn't load library "+libName+": "+t.toString());
+            isNativeLibLoaded = false;
+        }
+        if (isNativeLibLoaded) {
+            bigEndian = nIsBigEndian();
         }
     }
 
     static boolean isMidiIOEnabled() {
-        return isFeatureLibLoaded(FEATURE_MIDIIO);
+        if (Printer.debug) Printer.debug("Platform: Checking for MidiIO; library is loaded=" + isNativeLibLoaded);
+        return isNativeLibLoaded;
     }
 
     static boolean isPortsEnabled() {
-        return isFeatureLibLoaded(FEATURE_PORTS);
+        if (Printer.debug) Printer.debug("Platform: Checking for Ports; library is loaded=" + isNativeLibLoaded);
+        return isNativeLibLoaded;
     }
 
     static boolean isDirectAudioEnabled() {
-        return isFeatureLibLoaded(FEATURE_DIRECT_AUDIO);
-    }
-
-    private static boolean isFeatureLibLoaded(int feature) {
-        if (Printer.debug) Printer.debug("Platform: Checking for feature "+feature+"...");
-        int requiredLib = nGetLibraryForFeature(feature);
-        boolean isLoaded = (requiredLib != 0) && ((loadedLibs & requiredLib) == requiredLib);
-        if (Printer.debug) Printer.debug("          ...needs library "+requiredLib+". Result is loaded="+isLoaded);
-        return isLoaded;
+        if (Printer.debug) Printer.debug("Platform: Checking for DirectAudio; library is loaded=" + isNativeLibLoaded);
+        return isNativeLibLoaded;
     }
 
-    // the following native methods are implemented in Platform.c
+    // the following native method is implemented in Platform.c
     private static native boolean nIsBigEndian();
-    private static native String nGetExtraLibraries();
-    private static native int nGetLibraryForFeature(int feature);
-
-    /**
-     * Read the required system properties.
-     */
-    private static void readProperties() {
-        // $$fb 2002-03-06: implement check for endianness in native. Facilitates porting !
-        bigEndian = nIsBigEndian();
-    }
 }
diff -r eb72d194235c -r 514c68575523 src/java.desktop/share/classes/java/awt/SequencedEvent.java
--- a/src/java.desktop/share/classes/java/awt/SequencedEvent.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/share/classes/java/awt/SequencedEvent.java	Fri Mar 23 18:44:47 2018 +0000
@@ -135,11 +135,7 @@
                     if (Thread.currentThread() instanceof EventDispatchThread) {
                         EventDispatchThread edt = (EventDispatchThread)
                                 Thread.currentThread();
-                        edt.pumpEvents(SentEvent.ID, new Conditional() {
-                            public boolean evaluate() {
-                                return !SequencedEvent.this.isFirstOrDisposed();
-                            }
-                        });
+                        edt.pumpEvents(ID, () -> !SequencedEvent.this.isFirstOrDisposed());
                     } else {
                         if (fxAppThreadIsDispatchThread) {
                             fxCheckSequenceThread.start();
diff -r eb72d194235c -r 514c68575523 src/java.desktop/share/classes/javax/imageio/metadata/doc-files/gif_metadata.html
--- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/gif_metadata.html	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/gif_metadata.html	Fri Mar 23 18:44:47 2018 +0000
@@ -5,7 +5,7 @@
   GIF Metadata Format Specification
 
  device paused: %d  eof=%d\n",
+               prinfo->pause, prinfo->eof);
+        */
+        return (int) (prinfo->samples * info->frameSize);
+    }
+    ERROR0("DAUDIO: getDevicePosition: ioctl failed!\n");
+    return -1;
+}
+
+int DAUDIO_Flush(void* id, int isSource) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int err = -1;
+    int pos;
+
+    TRACE0("DAUDIO_Flush\n");
+    if (info) {
+        if (isSource) {
+            err = ioctl(info->fd, I_FLUSH, FLUSHW);
+        } else {
+            err = ioctl(info->fd, I_FLUSH, FLUSHR);
+        }
+        if (err >= 0) {
+            /* resets the transferedBytes parameter to
+             * the current samples count of the device
+             */
+            pos = getDevicePosition(info, isSource);
+            if (pos >= 0) {
+                info->transferedBytes = pos;
+            }
+        }
+    }
+    if (err < 0) {
+        ERROR0("ERROR in DAUDIO_Flush\n");
+    }
+    return (err < 0)?FALSE:TRUE;
+}
+
+int DAUDIO_GetAvailable(void* id, int isSource) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int ret = 0;
+    int pos;
+
+    if (info) {
+        /* unfortunately, the STREAMS architecture
+         * seems to not have a method for querying
+         * the available bytes to read/write!
+         * estimate it...
+         */
+        pos = getDevicePosition(info, isSource);
+        if (pos >= 0) {
+            if (isSource) {
+                /* we usually have written more bytes
+                 * to the queue than the device position should be
+                 */
+                ret = (info->bufferSizeInBytes) - (info->transferedBytes - pos);
+            } else {
+                /* for record, the device stream should
+                 * be usually ahead of our read actions
+                 */
+                ret = pos - info->transferedBytes;
+            }
+            if (ret > info->bufferSizeInBytes) {
+                ERROR2("DAUDIO_GetAvailable: available=%d, too big at bufferSize=%d!\n",
+                       (int) ret, (int) info->bufferSizeInBytes);
+                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
+                       (int) pos, (int) info->transferedBytes);
+                ret = info->bufferSizeInBytes;
+            }
+            else if (ret < 0) {
+                ERROR1("DAUDIO_GetAvailable: available=%d, in theory not possible!\n",
+                       (int) ret);
+                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
+                       (int) pos, (int) info->transferedBytes);
+                ret = 0;
+            }
+        }
+    }
+
+    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
+    return ret;
+}
+
+INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int ret;
+    int pos;
+    INT64 result = javaBytePos;
+
+    if (info) {
+        pos = getDevicePosition(info, isSource);
+        if (pos >= 0) {
+            result = info->positionOffset + pos;
+        }
+    }
+
+    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
+    return result;
+}
+
+
+void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int ret;
+    int pos;
+
+    if (info) {
+        pos = getDevicePosition(info, isSource);
+        if (pos >= 0) {
+            info->positionOffset = javaBytePos - pos;
+        }
+    }
+}
+
+int DAUDIO_RequiresServicing(void* id, int isSource) {
+    // never need servicing on Solaris
+    return FALSE;
+}
+
+void DAUDIO_Service(void* id, int isSource) {
+    // never need servicing on Solaris
+}
+
+
+#endif // USE_DAUDIO
diff -r eb72d194235c -r 514c68575523 src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Ports.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Ports.c	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,600 @@
+/*
+ * 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.  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.
+ */
+
+#define USE_ERROR
+//#define USE_TRACE
+
+#include "Ports.h"
+#include "PLATFORM_API_SolarisOS_Utils.h"
+
+#if USE_PORTS == TRUE
+
+#define MONITOR_GAIN_STRING "Monitor Gain"
+
+#define ALL_TARGET_PORT_COUNT 6
+
+// define the following to not use audio_prinfo_t.mod_ports
+#define SOLARIS7_COMPATIBLE
+
+// Solaris audio defines
+static int targetPorts[ALL_TARGET_PORT_COUNT] = {
+    AUDIO_SPEAKER,
+    AUDIO_HEADPHONE,
+    AUDIO_LINE_OUT,
+    AUDIO_AUX1_OUT,
+    AUDIO_AUX2_OUT,
+    AUDIO_SPDIF_OUT
+};
+
+static char* targetPortNames[ALL_TARGET_PORT_COUNT] = {
+    "Speaker",
+    "Headphone",
+    "Line Out",
+    "AUX1 Out",
+    "AUX2 Out",
+    "SPDIF Out"
+};
+
+// defined in Ports.h
+static int targetPortJavaSoundMapping[ALL_TARGET_PORT_COUNT] = {
+    PORT_DST_SPEAKER,
+    PORT_DST_HEADPHONE,
+    PORT_DST_LINE_OUT,
+    PORT_DST_UNKNOWN,
+    PORT_DST_UNKNOWN,
+    PORT_DST_UNKNOWN,
+};
+
+#define ALL_SOURCE_PORT_COUNT 7
+
+// Solaris audio defines
+static int sourcePorts[ALL_SOURCE_PORT_COUNT] = {
+    AUDIO_MICROPHONE,
+    AUDIO_LINE_IN,
+    AUDIO_CD,
+    AUDIO_AUX1_IN,
+    AUDIO_AUX2_IN,
+    AUDIO_SPDIF_IN,
+    AUDIO_CODEC_LOOPB_IN
+};
+
+static char* sourcePortNames[ALL_SOURCE_PORT_COUNT] = {
+    "Microphone In",
+    "Line In",
+    "Compact Disc In",
+    "AUX1 In",
+    "AUX2 In",
+    "SPDIF In",
+    "Internal Loopback"
+};
+
+// Ports.h defines
+static int sourcePortJavaSoundMapping[ALL_SOURCE_PORT_COUNT] = {
+    PORT_SRC_MICROPHONE,
+    PORT_SRC_LINE_IN,
+    PORT_SRC_COMPACT_DISC,
+    PORT_SRC_UNKNOWN,
+    PORT_SRC_UNKNOWN,
+    PORT_SRC_UNKNOWN,
+    PORT_SRC_UNKNOWN
+};
+
+struct tag_PortControlID;
+
+typedef struct tag_PortInfo {
+    int fd;                    // file descriptor of the pseudo device
+    audio_info_t audioInfo;
+    // ports
+    int targetPortCount;
+    int sourcePortCount;
+    // indexes to sourcePorts/targetPorts
+    // contains first target ports, then source ports
+    int ports[ALL_TARGET_PORT_COUNT + ALL_SOURCE_PORT_COUNT];
+    // controls
+    int maxControlCount;       // upper bound of number of controls
+    int usedControlIDs;        // number of items already filled in controlIDs
+    struct tag_PortControlID* controlIDs; // the control IDs themselves
+} PortInfo;
+
+#define PORT_CONTROL_TYPE_PLAY          0x4000000
+#define PORT_CONTROL_TYPE_RECORD        0x8000000
+#define PORT_CONTROL_TYPE_SELECT_PORT   1
+#define PORT_CONTROL_TYPE_GAIN          2
+#define PORT_CONTROL_TYPE_BALANCE       3
+#define PORT_CONTROL_TYPE_MONITOR_GAIN  10
+#define PORT_CONTROL_TYPE_OUTPUT_MUTED  11
+#define PORT_CONTROL_TYPE_PLAYRECORD_MASK PORT_CONTROL_TYPE_PLAY | PORT_CONTROL_TYPE_RECORD
+#define PORT_CONTROL_TYPE_MASK 0xFFFFFF
+
+
+typedef struct tag_PortControlID {
+    PortInfo*  portInfo;
+    INT32                 controlType;  // PORT_CONTROL_TYPE_XX
+    uint_t                port;
+} PortControlID;
+
+
+///// implemented functions of Ports.h
+
+INT32 PORT_GetPortMixerCount() {
+    return (INT32) getAudioDeviceCount();
+}
+
+
+INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
+    AudioDeviceDescription desc;
+
+    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) {
+        strncpy(description->name, desc.name, PORT_STRING_LENGTH-1);
+        description->name[PORT_STRING_LENGTH-1] = 0;
+        strncpy(description->vendor, desc.vendor, PORT_STRING_LENGTH-1);
+        description->vendor[PORT_STRING_LENGTH-1] = 0;
+        strncpy(description->version, desc.version, PORT_STRING_LENGTH-1);
+        description->version[PORT_STRING_LENGTH-1] = 0;
+        /*strncpy(description->description, desc.description, PORT_STRING_LENGTH-1);*/
+        strncpy(description->description, "Solaris Ports", PORT_STRING_LENGTH-1);
+        description->description[PORT_STRING_LENGTH-1] = 0;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+
+void* PORT_Open(INT32 mixerIndex) {
+    PortInfo* info = NULL;
+    int fd = -1;
+    AudioDeviceDescription desc;
+    int success = FALSE;
+
+    TRACE0("PORT_Open\n");
+    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
+        fd = open(desc.pathctl, O_RDWR);
+    }
+    if (fd < 0) {
+        ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex);
+        return NULL;
+    }
+
+    info = (PortInfo*) malloc(sizeof(PortInfo));
+    if (info != NULL) {
+        memset(info, 0, sizeof(PortInfo));
+        info->fd = fd;
+        success = TRUE;
+    }
+    if (!success) {
+        if (fd >= 0) {
+            close(fd);
+        }
+        PORT_Close((void*) info);
+        info = NULL;
+    }
+    return info;
+}
+
+void PORT_Close(void* id) {
+    TRACE0("PORT_Close\n");
+    if (id != NULL) {
+        PortInfo* info = (PortInfo*) id;
+        if (info->fd >= 0) {
+            close(info->fd);
+            info->fd = -1;
+        }
+        if (info->controlIDs) {
+            free(info->controlIDs);
+            info->controlIDs = NULL;
+        }
+        free(info);
+    }
+}
+
+
+
+INT32 PORT_GetPortCount(void* id) {
+    int ret = 0;
+    PortInfo* info = (PortInfo*) id;
+    if (info != NULL) {
+        if (!info->targetPortCount && !info->sourcePortCount) {
+            int i;
+            AUDIO_INITINFO(&info->audioInfo);
+            if (ioctl(info->fd, AUDIO_GETINFO, &info->audioInfo) >= 0) {
+                for (i = 0; i < ALL_TARGET_PORT_COUNT; i++) {
+                    if (info->audioInfo.play.avail_ports & targetPorts[i]) {
+                        info->ports[info->targetPortCount] = i;
+                        info->targetPortCount++;
+                    }
+#ifdef SOLARIS7_COMPATIBLE
+                    TRACE3("Target %d %s: avail=%d\n", i, targetPortNames[i],
+                           info->audioInfo.play.avail_ports & targetPorts[i]);
+#else
+                    TRACE4("Target %d %s: avail=%d  mod=%d\n", i, targetPortNames[i],
+                           info->audioInfo.play.avail_ports & targetPorts[i],
+                           info->audioInfo.play.mod_ports & targetPorts[i]);
+#endif
+                }
+                for (i = 0; i < ALL_SOURCE_PORT_COUNT; i++) {
+                    if (info->audioInfo.record.avail_ports & sourcePorts[i]) {
+                        info->ports[info->targetPortCount + info->sourcePortCount] = i;
+                        info->sourcePortCount++;
+                    }
+#ifdef SOLARIS7_COMPATIBLE
+                    TRACE3("Source %d %s: avail=%d\n", i, sourcePortNames[i],
+                           info->audioInfo.record.avail_ports & sourcePorts[i]);
+#else
+                    TRACE4("Source %d %s: avail=%d  mod=%d\n", i, sourcePortNames[i],
+                           info->audioInfo.record.avail_ports & sourcePorts[i],
+                           info->audioInfo.record.mod_ports & sourcePorts[i]);
+#endif
+                }
+            }
+        }
+        ret = info->targetPortCount + info->sourcePortCount;
+    }
+    return ret;
+}
+
+int isSourcePort(PortInfo* info, INT32 portIndex) {
+    return (portIndex >= info->targetPortCount);
+}
+
+INT32 PORT_GetPortType(void* id, INT32 portIndex) {
+    PortInfo* info = (PortInfo*) id;
+    if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) {
+        if (isSourcePort(info, portIndex)) {
+            return sourcePortJavaSoundMapping[info->ports[portIndex]];
+        } else {
+            return targetPortJavaSoundMapping[info->ports[portIndex]];
+        }
+    }
+    return 0;
+}
+
+// pre-condition: portIndex must have been verified!
+char* getPortName(PortInfo* info, INT32 portIndex) {
+    char* ret = NULL;
+
+    if (isSourcePort(info, portIndex)) {
+        ret = sourcePortNames[info->ports[portIndex]];
+    } else {
+        ret = targetPortNames[info->ports[portIndex]];
+    }
+    return ret;
+}
+
+INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
+    PortInfo* info = (PortInfo*) id;
+    char* n;
+
+    if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) {
+        n = getPortName(info, portIndex);
+        if (n) {
+            strncpy(name, n, len-1);
+            name[len-1] = 0;
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+void createPortControl(PortInfo* info, PortControlCreator* creator, INT32 portIndex,
+                       INT32 type, void** controlObjects, int* controlCount) {
+    PortControlID* controlID;
+    void* newControl = NULL;
+    int controlIndex;
+    char* jsType = NULL;
+    int isBoolean = FALSE;
+
+    TRACE0(">createPortControl\n");
+
+    // fill the ControlID structure and add this control
+    if (info->usedControlIDs >= info->maxControlCount) {
+        ERROR1("not enough free controlIDs !! maxControlIDs = %d\n", info->maxControlCount);
+        return;
+    }
+    controlID = &(info->controlIDs[info->usedControlIDs]);
+    controlID->portInfo = info;
+    controlID->controlType = type;
+    controlIndex = info->ports[portIndex];
+    if (isSourcePort(info, portIndex)) {
+        controlID->port = sourcePorts[controlIndex];
+    } else {
+        controlID->port = targetPorts[controlIndex];
+    }
+    switch (type & PORT_CONTROL_TYPE_MASK) {
+    case PORT_CONTROL_TYPE_SELECT_PORT:
+        jsType = CONTROL_TYPE_SELECT; isBoolean = TRUE; break;
+    case PORT_CONTROL_TYPE_GAIN:
+        jsType = CONTROL_TYPE_VOLUME;  break;
+    case PORT_CONTROL_TYPE_BALANCE:
+        jsType = CONTROL_TYPE_BALANCE; break;
+    case PORT_CONTROL_TYPE_MONITOR_GAIN:
+        jsType = CONTROL_TYPE_VOLUME; break;
+    case PORT_CONTROL_TYPE_OUTPUT_MUTED:
+        jsType = CONTROL_TYPE_MUTE; isBoolean = TRUE; break;
+    }
+    if (isBoolean) {
+        TRACE0(" PORT_CONTROL_TYPE_BOOLEAN\n");
+        newControl = (creator->newBooleanControl)(creator, controlID, jsType);
+    }
+    else if (jsType == CONTROL_TYPE_BALANCE) {
+        TRACE0(" PORT_CONTROL_TYPE_BALANCE\n");
+        newControl = (creator->newFloatControl)(creator, controlID, jsType,
+                                                -1.0f, 1.0f, 2.0f / 65.0f, "");
+    } else {
+        TRACE0(" PORT_CONTROL_TYPE_FLOAT\n");
+        newControl = (creator->newFloatControl)(creator, controlID, jsType,
+                                                0.0f, 1.0f, 1.0f / 256.0f, "");
+    }
+    if (newControl) {
+        controlObjects[*controlCount] = newControl;
+        (*controlCount)++;
+        info->usedControlIDs++;
+    }
+    TRACE0("addCompoundControl %d controls\n", *controlCount);
+    if (*controlCount) {
+        // create compound control and add it to the vector
+        compControl = (creator->newCompoundControl)(creator, name, controlObjects, *controlCount);
+        if (compControl) {
+            TRACE1(" addCompoundControl: calling addControl %p\n", compControl);
+            (creator->addControl)(creator, compControl);
+        }
+        *controlCount = 0;
+    }
+    TRACE0("addAllControl\n");
+    // go through all controls and add them to the vector
+    for (i = 0; i < *controlCount; i++) {
+        (creator->addControl)(creator, controlObjects[i]);
+    }
+    *controlCount = 0;
+    TRACE0("PORT_GetControls(id=%p, portIndex=%d). controlIDs=%p, maxControlCount=%d\n",
+           id, portIndex, info->controlIDs, info->maxControlCount);
+    if ((portIndex >= 0) && (portIndex < portCount)) {
+        // if the memory isn't reserved for the control structures, allocate it
+        if (!info->controlIDs) {
+            int maxCount = 0;
+            TRACE0("getControl: allocate mem\n");
+            // get a maximum number of controls:
+            // each port has a select, balance, and volume control.
+            maxCount = 3 * portCount;
+            // then there is monitorGain and outputMuted
+            maxCount += (2 * info->targetPortCount);
+            info->maxControlCount = maxCount;
+            info->controlIDs = (PortControlID*) malloc(sizeof(PortControlID) * maxCount);
+        }
+        if (!isSourcePort(info, portIndex)) {
+            type = PORT_CONTROL_TYPE_PLAY;
+            // add master mute control
+            createPortControl(info, creator, portIndex,
+                              type | PORT_CONTROL_TYPE_OUTPUT_MUTED,
+                              controls, &controlCount);
+            addAllControls(info, creator, controls, &controlCount);
+#ifdef SOLARIS7_COMPATIBLE
+            selectable = info->audioInfo.play.avail_ports & targetPorts[info->ports[portIndex]];
+#else
+            selectable = info->audioInfo.play.mod_ports & targetPorts[info->ports[portIndex]];
+#endif
+        } else {
+            type = PORT_CONTROL_TYPE_RECORD;
+#ifdef SOLARIS7_COMPATIBLE
+            selectable = info->audioInfo.record.avail_ports & sourcePorts[info->ports[portIndex]];
+#else
+            selectable = info->audioInfo.record.mod_ports & sourcePorts[info->ports[portIndex]];
+#endif
+        }
+        // add a mixer strip with volume, ...
+        createPortControl(info, creator, portIndex,
+                          type | PORT_CONTROL_TYPE_GAIN,
+                          controls, &controlCount);
+        // ... balance, ...
+        createPortControl(info, creator, portIndex,
+                          type | PORT_CONTROL_TYPE_BALANCE,
+                          controls, &controlCount);
+        // ... and select control (if not always on)...
+        if (selectable) {
+            createPortControl(info, creator, portIndex,
+                              type | PORT_CONTROL_TYPE_SELECT_PORT,
+                              controls, &controlCount);
+        }
+        // ... packaged in a compound control.
+        addCompoundControl(info, creator, getPortName(info, portIndex), controls, &controlCount);
+
+        if (type == PORT_CONTROL_TYPE_PLAY) {
+            // add a single strip for source ports with monitor gain
+            createPortControl(info, creator, portIndex,
+                              type | PORT_CONTROL_TYPE_MONITOR_GAIN,
+                              controls, &controlCount);
+            // also in a compound control
+            addCompoundControl(info, creator, MONITOR_GAIN_STRING, controls, &controlCount);
+        }
+    }
+    TRACE0("< PORT_getControls\n");
+}
+
+INT32 PORT_GetIntValue(void* controlIDV) {
+    PortControlID* controlID = (PortControlID*) controlIDV;
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+
+    AUDIO_INITINFO(&audioInfo);
+    if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
+        if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
+            prinfo = &(audioInfo.play);
+        } else {
+            prinfo = &(audioInfo.record);
+        }
+        switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
+        case PORT_CONTROL_TYPE_SELECT_PORT:
+            return (prinfo->port & controlID->port)?TRUE:FALSE;
+        case PORT_CONTROL_TYPE_OUTPUT_MUTED:
+            return (audioInfo.output_muted)?TRUE:FALSE;
+        default:
+            ERROR1("PORT_GetIntValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
+        }
+    }
+    ERROR0("PORT_GetIntValue: Could not ioctl!\n");
+    return 0;
+}
+
+void PORT_SetIntValue(void* controlIDV, INT32 value) {
+    PortControlID* controlID = (PortControlID*) controlIDV;
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+    int setPort;
+
+    if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
+        prinfo = &(audioInfo.play);
+    } else {
+        prinfo = &(audioInfo.record);
+    }
+    switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
+    case PORT_CONTROL_TYPE_SELECT_PORT:
+        // first try to just add this port. if that fails, set ONLY to this port.
+        AUDIO_INITINFO(&audioInfo);
+        if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
+            if (value) {
+                setPort = (prinfo->port | controlID->port);
+            } else {
+                setPort = (prinfo->port - controlID->port);
+            }
+            AUDIO_INITINFO(&audioInfo);
+            prinfo->port = setPort;
+            if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
+                // didn't work. Either this line doesn't support to select several
+                // ports at once (e.g. record), or a real error
+                if (value) {
+                    // set to ONLY this port (and disable any other currently selected ports)
+                    AUDIO_INITINFO(&audioInfo);
+                    prinfo->port = controlID->port;
+                    if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
+                        ERROR2("Error setting output select port %d to port %d!\n", controlID->port, controlID->port);
+                    }
+                } else {
+                    // assume it's an error
+                    ERROR2("Error setting output select port %d to port %d!\n", controlID->port, setPort);
+                }
+            }
+            break;
+        case PORT_CONTROL_TYPE_OUTPUT_MUTED:
+            AUDIO_INITINFO(&audioInfo);
+            audioInfo.output_muted = (value?TRUE:FALSE);
+            if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
+                ERROR2("Error setting output muted on port %d to %d!\n", controlID->port, value);
+            }
+            break;
+        default:
+            ERROR1("PORT_SetIntValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
+        }
+    }
+}
+
+float PORT_GetFloatValue(void* controlIDV) {
+    PortControlID* controlID = (PortControlID*) controlIDV;
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+
+    AUDIO_INITINFO(&audioInfo);
+    if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
+        if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
+            prinfo = &(audioInfo.play);
+        } else {
+            prinfo = &(audioInfo.record);
+        }
+        switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
+        case PORT_CONTROL_TYPE_GAIN:
+            return ((float) (prinfo->gain - AUDIO_MIN_GAIN))
+                / ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN));
+        case PORT_CONTROL_TYPE_BALANCE:
+            return ((float) ((prinfo->balance - AUDIO_LEFT_BALANCE - AUDIO_MID_BALANCE) << 1))
+                / ((float) (AUDIO_RIGHT_BALANCE - AUDIO_LEFT_BALANCE));
+        case PORT_CONTROL_TYPE_MONITOR_GAIN:
+            return ((float) (audioInfo.monitor_gain - AUDIO_MIN_GAIN))
+                / ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN));
+        default:
+            ERROR1("PORT_GetFloatValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
+        }
+    }
+    ERROR0("PORT_GetFloatValue: Could not ioctl!\n");
+    return 0.0f;
+}
+
+void PORT_SetFloatValue(void* controlIDV, float value) {
+    PortControlID* controlID = (PortControlID*) controlIDV;
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+
+    AUDIO_INITINFO(&audioInfo);
+
+    if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
+        prinfo = &(audioInfo.play);
+    } else {
+        prinfo = &(audioInfo.record);
+    }
+    switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
+    case PORT_CONTROL_TYPE_GAIN:
+        prinfo->gain = AUDIO_MIN_GAIN
+            + (int) ((value * ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + 0.5f);
+        break;
+    case PORT_CONTROL_TYPE_BALANCE:
+        prinfo->balance =  AUDIO_LEFT_BALANCE + AUDIO_MID_BALANCE
+            + ((int) (value * ((float) ((AUDIO_RIGHT_BALANCE - AUDIO_LEFT_BALANCE) >> 1))) + 0.5f);
+        break;
+    case PORT_CONTROL_TYPE_MONITOR_GAIN:
+        audioInfo.monitor_gain = AUDIO_MIN_GAIN
+            + (int) ((value * ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + 0.5f);
+        break;
+    default:
+        ERROR1("PORT_SetFloatValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
+        return;
+    }
+    if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
+        ERROR0("PORT_SetFloatValue: Could not ioctl!\n");
+    }
+}
+
+#endif // USE_PORTS
diff -r eb72d194235c -r 514c68575523 src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Utils.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Utils.c	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2002, 2007, 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.
+ */
+
+#define USE_ERROR
+#define USE_TRACE
+
+#include "PLATFORM_API_SolarisOS_Utils.h"
+
+#define MAX_AUDIO_DEVICES 20
+
+// not thread safe...
+static AudioDevicePath globalADPaths[MAX_AUDIO_DEVICES];
+static int globalADCount = -1;
+static int globalADCacheTime = -1;
+/* how many seconds do we cache devices */
+#define AD_CACHE_TIME 30
+
+// return seconds
+long getTimeInSeconds() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec;
+}
+
+
+int getAudioDeviceCount() {
+    int count = MAX_AUDIO_DEVICES;
+
+    getAudioDevices(globalADPaths, &count);
+    return count;
+}
+
+/* returns TRUE if the path exists at all */
+int addAudioDevice(char* path, AudioDevicePath* adPath, int* count) {
+    int i;
+    int found = 0;
+    int fileExists = 0;
+    // not thread safe...
+    static struct stat statBuf;
+
+    // get stats on the file
+    if (stat(path, &statBuf) == 0) {
+        // file exists.
+        fileExists = 1;
+        // If it is not yet in the adPath array, add it to the array
+        for (i = 0; i < *count; i++) {
+            if (adPath[i].st_ino == statBuf.st_ino
+                && adPath[i].st_dev == statBuf.st_dev) {
+                found = 1;
+                break;
+            }
+        }
+        if (!found) {
+            adPath[*count].st_ino = statBuf.st_ino;
+            adPath[*count].st_dev = statBuf.st_dev;
+            strncpy(adPath[*count].path, path, MAX_NAME_LENGTH);
+            adPath[*count].path[MAX_NAME_LENGTH - 1] = 0;
+            (*count)++;
+            TRACE1("Added audio device %s\n", path);
+        }
+    }
+    return fileExists;
+}
+
+
+void getAudioDevices(AudioDevicePath* adPath, int* count) {
+    int maxCount = *count;
+    char* audiodev;
+    char devsound[15];
+    int i;
+    long timeInSeconds = getTimeInSeconds();
+
+    if (globalADCount < 0
+        || (getTimeInSeconds() - globalADCacheTime) > AD_CACHE_TIME
+        || (adPath != globalADPaths)) {
+        *count = 0;
+        // first device, if set, is AUDIODEV variable
+        audiodev = getenv("AUDIODEV");
+        if (audiodev != NULL && audiodev[0] != 0) {
+            addAudioDevice(audiodev, adPath, count);
+        }
+        // then try /dev/audio
+        addAudioDevice("/dev/audio", adPath, count);
+        // then go through all of the /dev/sound/? devices
+        for (i = 0; i < 100; i++) {
+            sprintf(devsound, "/dev/sound/%d", i);
+            if (!addAudioDevice(devsound, adPath, count)) {
+                break;
+            }
+        }
+        if (adPath == globalADPaths) {
+            /* commit cache */
+            globalADCount = *count;
+            /* set cache time */
+            globalADCacheTime = timeInSeconds;
+        }
+    } else {
+        /* return cache */
+        *count = globalADCount;
+    }
+    // that's it
+}
+
+int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames) {
+    int count = MAX_AUDIO_DEVICES;
+    int ret = 0;
+
+    getAudioDevices(globalADPaths, &count);
+    if (index>=0 && index < count) {
+        ret = getAudioDeviceDescription(globalADPaths[index].path, adDesc, getNames);
+    }
+    return ret;
+}
+
+int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames) {
+    int fd;
+    int mixerMode;
+    int len;
+    audio_info_t info;
+    audio_device_t deviceInfo;
+
+    strncpy(adDesc->path, path, MAX_NAME_LENGTH);
+    adDesc->path[MAX_NAME_LENGTH] = 0;
+    strcpy(adDesc->pathctl, adDesc->path);
+    strcat(adDesc->pathctl, "ctl");
+    strcpy(adDesc->name, adDesc->path);
+    adDesc->vendor[0] = 0;
+    adDesc->version[0] = 0;
+    adDesc->description[0] = 0;
+    adDesc->maxSimulLines = 1;
+
+    // try to open the pseudo device and get more information
+    fd = open(adDesc->pathctl, O_WRONLY | O_NONBLOCK);
+    if (fd >= 0) {
+        close(fd);
+        if (getNames) {
+            fd = open(adDesc->pathctl, O_RDONLY);
+            if (fd >= 0) {
+                if (ioctl(fd, AUDIO_GETDEV, &deviceInfo) >= 0) {
+                    strncpy(adDesc->vendor, deviceInfo.name, MAX_AUDIO_DEV_LEN);
+                    adDesc->vendor[MAX_AUDIO_DEV_LEN] = 0;
+                    strncpy(adDesc->version, deviceInfo.version, MAX_AUDIO_DEV_LEN);
+                    adDesc->version[MAX_AUDIO_DEV_LEN] = 0;
+                    /* add config string to the dev name
+                     * creates a string like "/dev/audio (onboard1)"
+                     */
+                    len = strlen(adDesc->name) + 1;
+                    if (MAX_NAME_LENGTH - len > 3) {
+                        strcat(adDesc->name, " (");
+                        strncat(adDesc->name, deviceInfo.config, MAX_NAME_LENGTH - len);
+                        strcat(adDesc->name, ")");
+                    }
+                    adDesc->name[MAX_NAME_LENGTH-1] = 0;
+                }
+                if (ioctl(fd, AUDIO_MIXERCTL_GET_MODE, &mixerMode) >= 0) {
+                    if (mixerMode == AM_MIXER_MODE) {
+                        TRACE1(" getAudioDeviceDescription: %s is in mixer mode\n", adDesc->path);
+                        adDesc->maxSimulLines = -1;
+                    }
+                } else {
+                    ERROR1("ioctl AUDIO_MIXERCTL_GET_MODE failed on %s!\n", adDesc->path);
+                }
+                close(fd);
+            } else {
+                ERROR1("could not open %s!\n", adDesc->pathctl);
+            }
+        }
+        return 1;
+    }
+    return 0;
+}
diff -r eb72d194235c -r 514c68575523 src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Utils.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Utils.h	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include 
+#include 
+#include 
+#include 
+/* does not work on Solaris 2.7 */
+#include 
+#include 
+#include 
+#ifndef __linux__
+#include 
+#endif
+#include 
+#include 
+#include 
+
+#ifndef PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
+#define PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
+
+/* defines for Solaris 2.7
+   #ifndef AUDIO_AUX1_OUT
+   #define AUDIO_AUX1_OUT   (0x08)  // output to aux1 out
+   #define AUDIO_AUX2_OUT   (0x10)  // output to aux2 out
+   #define AUDIO_SPDIF_OUT  (0x20)  // output to SPDIF port
+   #define AUDIO_AUX1_IN    (0x08)    // input from aux1 in
+   #define AUDIO_AUX2_IN    (0x10)    // input from aux2 in
+   #define AUDIO_SPDIF_IN   (0x20)    // input from SPDIF port
+   #endif
+*/
+
+/* input from Codec inter. loopback */
+#ifndef AUDIO_CODEC_LOOPB_IN
+#define AUDIO_CODEC_LOOPB_IN       (0x40)
+#endif
+
+
+#define MAX_NAME_LENGTH 300
+
+typedef struct tag_AudioDevicePath {
+    char path[MAX_NAME_LENGTH];
+    ino_t st_ino; // inode number to detect duplicate devices
+    dev_t st_dev; // device ID to detect duplicate audio devices
+} AudioDevicePath;
+
+typedef struct tag_AudioDeviceDescription {
+    INT32 maxSimulLines;
+    char path[MAX_NAME_LENGTH+1];
+    char pathctl[MAX_NAME_LENGTH+4];
+    char name[MAX_NAME_LENGTH+1];
+    char vendor[MAX_NAME_LENGTH+1];
+    char version[MAX_NAME_LENGTH+1];
+    char description[MAX_NAME_LENGTH+1];
+} AudioDeviceDescription;
+
+int getAudioDeviceCount();
+
+/*
+ * adPath is an array of AudioDevicePath structures
+ * count contains initially the number of elements in adPath
+ *       and will be set to the returned number of paths.
+ */
+void getAudioDevices(AudioDevicePath* adPath, int* count);
+
+/*
+ * fills adDesc from the audio device given in path
+ * returns 0 if an error occurred
+ * if getNames is 0, only path and pathctl are filled
+ */
+int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames);
+int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames);
+
+
+#endif // PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.c
--- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.c	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.c	Fri Mar 23 18:44:47 2018 +0000
@@ -45,18 +45,18 @@
 
 static GtkLib gtk_libs[] = {
     {
+        GTK_3,
+        JNI_LIB_NAME("gtk-3"),
+        VERSIONED_JNI_LIB_NAME("gtk-3", "0"),
+        >k3_load,
+        >k3_check
+    },
+    {
         GTK_2,
         JNI_LIB_NAME("gtk-x11-2.0"),
         VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0"),
         >k2_load,
         >k2_check
-    },
-    {
-        GTK_3,
-        JNI_LIB_NAME("gtk-3"),
-        VERSIONED_JNI_LIB_NAME("gtk-3", "0"),
-        >k3_load,
-        >k3_check
     }
 };
 
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_CommonUtils.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_CommonUtils.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-//#define USE_ERROR
-//#define USE_TRACE
-
-#include "PLATFORM_API_BsdOS_ALSA_CommonUtils.h"
-
-static void alsaDebugOutput(const char *file, int line, const char *function, int err, const char *fmt, ...) {
-#ifdef USE_ERROR
-    va_list args;
-    va_start(args, fmt);
-    printf("%s:%d function %s: error %d: %s\n", file, line, function, err, snd_strerror(err));
-    if (strlen(fmt) > 0) {
-        vprintf(fmt, args);
-    }
-    va_end(args);
-#endif
-}
-
-static int alsa_inited = 0;
-static int alsa_enumerate_pcm_subdevices = FALSE; // default: no
-static int alsa_enumerate_midi_subdevices = FALSE; // default: no
-
-void initAlsaSupport() {
-    char* enumerate;
-    if (!alsa_inited) {
-        alsa_inited = TRUE;
-        snd_lib_error_set_handler(&alsaDebugOutput);
-
-        enumerate = getenv(ENV_ENUMERATE_PCM_SUBDEVICES);
-        if (enumerate != NULL && strlen(enumerate) > 0
-            && (enumerate[0] != 'f')   // false
-            && (enumerate[0] != 'F')   // False
-            && (enumerate[0] != 'n')   // no
-            && (enumerate[0] != 'N')) { // NO
-            alsa_enumerate_pcm_subdevices = TRUE;
-        }
-#ifdef ALSA_MIDI_ENUMERATE_SUBDEVICES
-        alsa_enumerate_midi_subdevices = TRUE;
-#endif
-    }
-}
-
-
-/* if true (non-zero), ALSA sub devices should be listed as separate devices
- */
-int needEnumerateSubdevices(int isMidi) {
-    initAlsaSupport();
-    return isMidi ? alsa_enumerate_midi_subdevices
-                  : alsa_enumerate_pcm_subdevices;
-}
-
-
-/*
- * deviceID contains packed card, device and subdevice numbers
- * each number takes 10 bits
- * "default" device has id == ALSA_DEFAULT_DEVICE_ID
- */
-UINT32 encodeDeviceID(int card, int device, int subdevice) {
-    return (((card & 0x3FF) << 20) | ((device & 0x3FF) << 10)
-           | (subdevice & 0x3FF)) + 1;
-}
-
-
-void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
-                    int isMidi) {
-    deviceID--;
-    *card = (deviceID >> 20) & 0x3FF;
-    *device = (deviceID >> 10) & 0x3FF;
-    if (needEnumerateSubdevices(isMidi)) {
-        *subdevice = deviceID  & 0x3FF;
-    } else {
-        *subdevice = -1; // ALSA will choose any subdevices
-    }
-}
-
-
-void getDeviceString(char* buffer, int card, int device, int subdevice,
-                     int usePlugHw, int isMidi) {
-    if (needEnumerateSubdevices(isMidi)) {
-        sprintf(buffer, "%s:%d,%d,%d",
-                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
-                        card, device, subdevice);
-    } else {
-        sprintf(buffer, "%s:%d,%d",
-                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
-                        card, device);
-    }
-}
-
-
-void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
-                                 int usePlugHw, int isMidi) {
-    int card, device, subdevice;
-
-    if (deviceID == ALSA_DEFAULT_DEVICE_ID) {
-        strcpy(buffer, ALSA_DEFAULT_DEVICE_NAME);
-    } else {
-        decodeDeviceID(deviceID, &card, &device, &subdevice, isMidi);
-        getDeviceString(buffer, card, device, subdevice, usePlugHw, isMidi);
-    }
-}
-
-
-static int hasGottenALSAVersion = FALSE;
-#define ALSAVersionString_LENGTH 200
-static char ALSAVersionString[ALSAVersionString_LENGTH];
-
-void getALSAVersion(char* buffer, int len) {
-    if (!hasGottenALSAVersion) {
-        // get alsa version from proc interface
-        FILE* file;
-        int curr, len, totalLen, inVersionString;
-        file = fopen(ALSA_VERSION_PROC_FILE, "r");
-        ALSAVersionString[0] = 0;
-        if (file) {
-            if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) {
-                // parse for version number
-                totalLen = strlen(ALSAVersionString);
-                inVersionString = FALSE;
-                len = 0;
-                curr = 0;
-                while (curr < totalLen) {
-                    if (!inVersionString) {
-                        // is this char the beginning of a version string ?
-                        if (ALSAVersionString[curr] >= '0'
-                            && ALSAVersionString[curr] <= '9') {
-                            inVersionString = TRUE;
-                        }
-                    }
-                    if (inVersionString) {
-                        // the version string ends with white space
-                        if (ALSAVersionString[curr] <= 32) {
-                            break;
-                        }
-                        if (curr != len) {
-                            // copy this char to the beginning of the string
-                            ALSAVersionString[len] = ALSAVersionString[curr];
-                        }
-                        len++;
-                    }
-                    curr++;
-                }
-                // remove trailing dots
-                while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
-                    len--;
-                }
-                // null terminate
-                ALSAVersionString[len] = 0;
-            }
-            fclose(file);
-            hasGottenALSAVersion = TRUE;
-        }
-    }
-    strncpy(buffer, ALSAVersionString, len);
-}
-
-
-/* end */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_CommonUtils.h
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_CommonUtils.h	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 
-#include "Utilities.h"
-
-#ifndef PLATFORM_API_BSDOS_ALSA_COMMONUTILS_H_INCLUDED
-#define PLATFORM_API_BSDOS_ALSA_COMMONUTILS_H_INCLUDED
-
-#define ALSA_VERSION_PROC_FILE "/proc/asound/version"
-#define ALSA_HARDWARE "hw"
-#define ALSA_HARDWARE_CARD ALSA_HARDWARE":%d"
-#define ALSA_HARDWARE_DEVICE ALSA_HARDWARE_CARD",%d"
-#define ALSA_HARDWARE_SUBDEVICE ALSA_HARDWARE_DEVICE",%d"
-
-#define ALSA_PLUGHARDWARE "plughw"
-#define ALSA_DEFAULT_DEVICE_NAME "default"
-
-#define ALSA_DEFAULT_DEVICE_ID (0)
-
-#define ALSA_PCM     (0)
-#define ALSA_RAWMIDI (1)
-
-// for use in info objects
-#define ALSA_VENDOR "ALSA (http://www.alsa-project.org)"
-
-// Environment variable for inclusion of subdevices in device listing.
-// If this variable is unset or "no", then subdevices are ignored, and
-// it's ALSA's choice which one to use (enables hardware mixing)
-#define ENV_ENUMERATE_PCM_SUBDEVICES "ALSA_ENUMERATE_PCM_SUBDEVICES"
-
-// if defined, subdevices are listed.
-//#undef ALSA_MIDI_ENUMERATE_SUBDEVICES
-#define ALSA_MIDI_ENUMERATE_SUBDEVICES
-
-// must be called before any ALSA calls
-void initAlsaSupport();
-
-/* if true (non-zero), ALSA sub devices should be listed as separate devices
- */
-int needEnumerateSubdevices(int isMidi);
-
-
-/*
- * deviceID contains packed card, device and subdevice numbers
- * each number takes 10 bits
- * "default" device has id == ALSA_DEFAULT_DEVICE_ID
- */
-UINT32 encodeDeviceID(int card, int device, int subdevice);
-
-void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
-                    int isMidi);
-
-void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
-                                 int usePlugHw, int isMidi);
-
-void getALSAVersion(char* buffer, int len);
-
-
-#endif // PLATFORM_API_BSDOS_ALSA_COMMONUTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiIn.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiIn.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,354 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#if USE_PLATFORM_MIDI_IN == TRUE
-
-
-#include 
-#include "PlatformMidi.h"
-#include "PLATFORM_API_BsdOS_ALSA_MidiUtils.h"
-#if defined(i586)
-#include 
-#endif
-
-/*
- * Helper methods
- */
-
-static inline UINT32 packMessage(int status, int data1, int data2) {
-    return ((status & 0xFF) | ((data1 & 0xFF) << 8) | ((data2 & 0xFF) << 16));
-}
-
-
-static void setShortMessage(MidiMessage* message,
-                            int status, int data1, int data2) {
-    message->type = SHORT_MESSAGE;
-    message->data.s.packedMsg = packMessage(status, data1, data2);
-}
-
-
-static void setRealtimeMessage(MidiMessage* message, int status) {
-    setShortMessage(message, status, 0, 0);
-}
-
-
-static void set14bitMessage(MidiMessage* message, int status, int value) {
-    TRACE3("14bit value: %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
-    value &= 0x3FFF;
-    TRACE3("14bit value (2): %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
-    setShortMessage(message, status,
-                    value & 0x7F,
-                    (value >> 7) & 0x7F);
-}
-
-
-/*
- * implementation of the platform-dependent
- * MIDI in functions declared in PlatformMidi.h
- */
-
-char* MIDI_IN_GetErrorStr(INT32 err) {
-    return (char*) getErrorStr(err);
-}
-
-INT32 MIDI_IN_GetNumDevices() {
-/* Workaround for 6842956: 32bit app on 64bit bsd
- * gets assertion failure trying to open midiIn ports.
- * Untill the issue is fixed in ALSA
- * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807)
- * report no midi in devices in the configuration.
- */
-#if defined(i586)
-    static int jre32onbsd64 = -1;
-    if (jre32onbsd64 < 0) {
-        jre32onbsd64 = 0;
-        /* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN"
-         * environment variable.
-         */
-        if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) {
-            struct utsname u;
-            jre32onbsd64 = 0;
-            if (uname(&u) == 0) {
-                if (strstr(u.machine, "64") != NULL) {
-                    TRACE0("jre32 on bsd64 detected - report no midiIn devices\n");
-                    jre32onbsd64 = 1;
-                }
-            }
-        }
-    }
-    if (jre32onbsd64) {
-        return 0;
-    }
-#endif
-
-    TRACE0("MIDI_IN_GetNumDevices()\n");
-
-    return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT);
-}
-
-
-INT32 MIDI_IN_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceName(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
-                                name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceVendor(deviceIndex, name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceDescription(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
-                                       name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceVersion(deviceIndex, name, nameLength);
-    return ret;
-}
-
-/*************************************************************************/
-
-INT32 MIDI_IN_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
-    INT32 ret;
-    TRACE0("> MIDI_IN_OpenDevice\n");
-    ret = openMidiDevice(SND_RAWMIDI_STREAM_INPUT, deviceIndex, handle);
-    TRACE1("< MIDI_IN_OpenDevice: returning %d\n", (int) ret);
-    return ret;
-}
-
-
-INT32 MIDI_IN_CloseDevice(MidiDeviceHandle* handle) {
-    INT32 ret;
-    TRACE0("> MIDI_IN_CloseDevice\n");
-    ret = closeMidiDevice(handle);
-    TRACE1("< MIDI_IN_CloseDevice: returning %d\n", (int) ret);
-    return ret;
-}
-
-
-INT32 MIDI_IN_StartDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_IN_StartDevice\n");
-    return MIDI_SUCCESS;
-}
-
-
-INT32 MIDI_IN_StopDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_IN_StopDevice\n");
-    return MIDI_SUCCESS;
-}
-
-
-INT64 MIDI_IN_GetTimeStamp(MidiDeviceHandle* handle) {
-    return getMidiTimestamp(handle);
-}
-
-
-/* read the next message from the queue */
-MidiMessage* MIDI_IN_GetMessage(MidiDeviceHandle* handle) {
-    snd_seq_event_t alsa_message;
-    MidiMessage* jdk_message;
-    int err;
-    char buffer[1];
-    int status;
-
-    TRACE0("> MIDI_IN_GetMessage\n");
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): handle is NULL\n");
-        return NULL;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): native handle is NULL\n");
-        return NULL;
-    }
-    if (!handle->platformData) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): platformData is NULL\n");
-        return NULL;
-    }
-
-    /* For MIDI In, the device is left in non blocking mode. So if there is
-       no data from the device, snd_rawmidi_read() returns with -11 (EAGAIN).
-       This results in jumping back to the Java layer. */
-    while (TRUE) {
-        TRACE0("before snd_rawmidi_read()\n");
-        err = snd_rawmidi_read((snd_rawmidi_t*) handle->deviceHandle, buffer, 1);
-        TRACE0("after snd_rawmidi_read()\n");
-        if (err != 1) {
-            ERROR2("< ERROR: MIDI_IN_GetMessage(): snd_rawmidi_read() returned %d : %s\n", err, snd_strerror(err));
-            return NULL;
-        }
-        // printf("received byte: %d\n", buffer[0]);
-        err = snd_midi_event_encode_byte((snd_midi_event_t*) handle->platformData,
-                                         (int) buffer[0],
-                                         &alsa_message);
-        if (err == 1) {
-            break;
-        } else if (err < 0) {
-            ERROR1("< ERROR: MIDI_IN_GetMessage(): snd_midi_event_encode_byte() returned %d\n", err);
-            return NULL;
-        }
-    }
-    jdk_message = (MidiMessage*) calloc(sizeof(MidiMessage), 1);
-    if (!jdk_message) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
-        return NULL;
-    }
-    // TODO: tra
-    switch (alsa_message.type) {
-    case SND_SEQ_EVENT_NOTEON:
-    case SND_SEQ_EVENT_NOTEOFF:
-    case SND_SEQ_EVENT_KEYPRESS:
-        status = (alsa_message.type == SND_SEQ_EVENT_KEYPRESS) ? 0xA0 :
-            (alsa_message.type == SND_SEQ_EVENT_NOTEON) ? 0x90 : 0x80;
-        status |= alsa_message.data.note.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.note.note,
-                        alsa_message.data.note.velocity);
-        break;
-
-    case SND_SEQ_EVENT_CONTROLLER:
-        status = 0xB0 | alsa_message.data.control.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.control.param,
-                        alsa_message.data.control.value);
-        break;
-
-    case SND_SEQ_EVENT_PGMCHANGE:
-    case SND_SEQ_EVENT_CHANPRESS:
-        status = (alsa_message.type == SND_SEQ_EVENT_PGMCHANGE) ? 0xC0 : 0xD0;
-        status |= alsa_message.data.control.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.control.value, 0);
-        break;
-
-    case SND_SEQ_EVENT_PITCHBEND:
-        status = 0xE0 | alsa_message.data.control.channel;
-        // $$mp 2003-09-23:
-        // possible hack to work around a bug in ALSA. Necessary for
-        // ALSA 0.9.2. May be fixed in newer versions of ALSA.
-        // alsa_message.data.control.value ^= 0x2000;
-        // TRACE1("pitchbend value: %d\n", alsa_message.data.control.value);
-        set14bitMessage(jdk_message, status,
-                        alsa_message.data.control.value);
-        break;
-
-        /* System exclusive messages */
-
-    case SND_SEQ_EVENT_SYSEX:
-        jdk_message->type = LONG_MESSAGE;
-        jdk_message->data.l.size = alsa_message.data.ext.len;
-        jdk_message->data.l.data = malloc(alsa_message.data.ext.len);
-        if (jdk_message->data.l.data == NULL) {
-            ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
-            free(jdk_message);
-            jdk_message = NULL;
-        } else {
-            memcpy(jdk_message->data.l.data, alsa_message.data.ext.ptr, alsa_message.data.ext.len);
-        }
-        break;
-
-        /* System common messages */
-
-    case SND_SEQ_EVENT_QFRAME:
-        setShortMessage(jdk_message, 0xF1,
-                        alsa_message.data.control.value & 0x7F, 0);
-        break;
-
-    case SND_SEQ_EVENT_SONGPOS:
-        set14bitMessage(jdk_message, 0xF2,
-                        alsa_message.data.control.value);
-        break;
-
-    case SND_SEQ_EVENT_SONGSEL:
-        setShortMessage(jdk_message, 0xF3,
-                        alsa_message.data.control.value & 0x7F, 0);
-        break;
-
-    case SND_SEQ_EVENT_TUNE_REQUEST:
-        setRealtimeMessage(jdk_message, 0xF6);
-        break;
-
-        /* System realtime messages */
-
-    case SND_SEQ_EVENT_CLOCK:
-        setRealtimeMessage(jdk_message, 0xF8);
-        break;
-
-    case SND_SEQ_EVENT_START:
-        setRealtimeMessage(jdk_message, 0xFA);
-        break;
-
-    case SND_SEQ_EVENT_CONTINUE:
-        setRealtimeMessage(jdk_message, 0xFB);
-        break;
-
-    case SND_SEQ_EVENT_STOP:
-        setRealtimeMessage(jdk_message, 0xFC);
-        break;
-
-    case SND_SEQ_EVENT_SENSING:
-        setRealtimeMessage(jdk_message, 0xFE);
-        break;
-
-    case SND_SEQ_EVENT_RESET:
-        setRealtimeMessage(jdk_message, 0xFF);
-        break;
-
-    default:
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): unhandled ALSA MIDI message type\n");
-        free(jdk_message);
-        jdk_message = NULL;
-
-    }
-
-    // set timestamp
-    if (jdk_message != NULL) {
-        jdk_message->timestamp = getMidiTimestamp(handle);
-    }
-    TRACE1("< MIDI_IN_GetMessage: returning %p\n", jdk_message);
-    return jdk_message;
-}
-
-
-void MIDI_IN_ReleaseMessage(MidiDeviceHandle* handle, MidiMessage* msg) {
-    if (!msg) {
-        ERROR0("< ERROR: MIDI_IN_ReleaseMessage(): message is NULL\n");
-        return;
-    }
-    if (msg->type == LONG_MESSAGE && msg->data.l.data) {
-        free(msg->data.l.data);
-    }
-    free(msg);
-}
-
-#endif /* USE_PLATFORM_MIDI_IN */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiOut.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiOut.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#if USE_PLATFORM_MIDI_OUT == TRUE
-
-#include 
-#include "PlatformMidi.h"
-#include "PLATFORM_API_BsdOS_ALSA_MidiUtils.h"
-
-
-
-static int CHANNEL_MESSAGE_LENGTH[] = {
-    -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 3, 3, 2, 2, 3 };
-/*                                 8x 9x Ax Bx Cx Dx Ex */
-
-static int SYSTEM_MESSAGE_LENGTH[] = {
-    -1, 2, 3, 2, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1 };
-/*  F0 F1 F2 F3  F4  F5 F6 F7 F8  F9 FA FB FC  FD FE FF */
-
-
-// the returned length includes the status byte.
-// for illegal messages, -1 is returned.
-static int getShortMessageLength(int status) {
-        int     dataLength = 0;
-        if (status < 0xF0) { // channel voice message
-                dataLength = CHANNEL_MESSAGE_LENGTH[(status >> 4) & 0xF];
-        } else {
-                dataLength = SYSTEM_MESSAGE_LENGTH[status & 0xF];
-        }
-        return dataLength;
-}
-
-
-/*
- * implementation of the platform-dependent
- * MIDI out functions declared in PlatformMidi.h
- */
-char* MIDI_OUT_GetErrorStr(INT32 err) {
-    return (char*) getErrorStr(err);
-}
-
-
-INT32 MIDI_OUT_GetNumDevices() {
-    TRACE0("MIDI_OUT_GetNumDevices()\n");
-    return getMidiDeviceCount(SND_RAWMIDI_STREAM_OUTPUT);
-}
-
-
-INT32 MIDI_OUT_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceName()\n");
-    return getMidiDeviceName(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
-                             name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceVendor()\n");
-    return getMidiDeviceVendor(deviceIndex, name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceDescription()\n");
-    return getMidiDeviceDescription(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
-                                    name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceVersion()\n");
-    return getMidiDeviceVersion(deviceIndex, name, nameLength);
-}
-
-
-/* *************************** MidiOutDevice implementation *************** */
-
-INT32 MIDI_OUT_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
-    TRACE1("MIDI_OUT_OpenDevice(): deviceIndex: %d\n", (int) deviceIndex);
-    return openMidiDevice(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex, handle);
-}
-
-
-INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_OUT_CloseDevice()\n");
-    return closeMidiDevice(handle);
-}
-
-
-INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle) {
-    return getMidiTimestamp(handle);
-}
-
-
-INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg,
-                                UINT32 timestamp) {
-    int err;
-    int status;
-    int data1;
-    int data2;
-    char buffer[3];
-
-    TRACE2("> MIDI_OUT_SendShortMessage() %x, time: %u\n", packedMsg, (unsigned int) timestamp);
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_OUT_SendShortMessage(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    status = (packedMsg & 0xFF);
-    buffer[0] = (char) status;
-    buffer[1]  = (char) ((packedMsg >> 8) & 0xFF);
-    buffer[2]  = (char) ((packedMsg >> 16) & 0xFF);
-    TRACE4("status: %d, data1: %d, data2: %d, length: %d\n", (int) buffer[0], (int) buffer[1], (int) buffer[2], getShortMessageLength(status));
-    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle, buffer, getShortMessageLength(status));
-    if (err < 0) {
-        ERROR1("  ERROR: MIDI_OUT_SendShortMessage(): snd_rawmidi_write() returned %d\n", err);
-    }
-
-    TRACE0("< MIDI_OUT_SendShortMessage()\n");
-    return err;
-}
-
-
-INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data,
-                               UINT32 size, UINT32 timestamp) {
-    int err;
-
-    TRACE2("> MIDI_OUT_SendLongMessage() size %u, time: %u\n", (unsigned int) size, (unsigned int) timestamp);
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!data) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): data is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle,
-                            data, size);
-    if (err < 0) {
-        ERROR1("  ERROR: MIDI_OUT_SendLongMessage(): snd_rawmidi_write() returned %d\n", err);
-    }
-
-    TRACE0("< MIDI_OUT_SendLongMessage()\n");
-    return err;
-}
-
-
-#endif /* USE_PLATFORM_MIDI_OUT */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiUtils.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiUtils.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,481 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_BsdOS_ALSA_MidiUtils.h"
-#include "PLATFORM_API_BsdOS_ALSA_CommonUtils.h"
-#include 
-#include 
-
-static INT64 getTimeInMicroseconds() {
-    struct timeval tv;
-
-    gettimeofday(&tv, NULL);
-    return (tv.tv_sec * 1000000UL) + tv.tv_usec;
-}
-
-
-const char* getErrorStr(INT32 err) {
-        return snd_strerror((int) err);
-}
-
-
-
-// callback for iteration through devices
-// returns TRUE if iteration should continue
-typedef int (*DeviceIteratorPtr)(UINT32 deviceID,
-                                 snd_rawmidi_info_t* rawmidi_info,
-                                 snd_ctl_card_info_t* cardinfo,
-                                 void *userData);
-
-// for each ALSA device, call iterator. userData is passed to the iterator
-// returns total number of iterations
-static int iterateRawmidiDevices(snd_rawmidi_stream_t direction,
-                                 DeviceIteratorPtr iterator,
-                                 void* userData) {
-    int count = 0;
-    int subdeviceCount;
-    int card, dev, subDev;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_rawmidi_t *rawmidi;
-    snd_rawmidi_info_t *rawmidi_info;
-    snd_ctl_card_info_t *card_info, *defcardinfo = NULL;
-    UINT32 deviceID;
-    int doContinue = TRUE;
-
-    snd_rawmidi_info_malloc(&rawmidi_info);
-    snd_ctl_card_info_malloc(&card_info);
-
-    // 1st try "default" device
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_rawmidi_open(&rawmidi, NULL, ALSA_DEFAULT_DEVICE_NAME,
-                               SND_RAWMIDI_NONBLOCK);
-    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_open(NULL, &rawmidi, ALSA_DEFAULT_DEVICE_NAME,
-                               SND_RAWMIDI_NONBLOCK);
-    } else {
-        ERROR0("ERROR: iterateRawmidiDevices(): direction is neither"
-               " SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
-        err = MIDI_INVALID_ARGUMENT;
-    }
-    if (err < 0) {
-        ERROR1("ERROR: snd_rawmidi_open (\"default\"): %s\n",
-               snd_strerror(err));
-    } else {
-        err = snd_rawmidi_info(rawmidi, rawmidi_info);
-
-        snd_rawmidi_close(rawmidi);
-        if (err < 0) {
-            ERROR1("ERROR: snd_rawmidi_info (\"default\"): %s\n",
-                    snd_strerror(err));
-        } else {
-            // try to get card info
-            card = snd_rawmidi_info_get_card(rawmidi_info);
-            if (card >= 0) {
-                sprintf(devname, ALSA_HARDWARE_CARD, card);
-                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
-                    if (snd_ctl_card_info(handle, card_info) >= 0) {
-                        defcardinfo = card_info;
-                    }
-                    snd_ctl_close(handle);
-                }
-            }
-            // call calback function for the device
-            if (iterator != NULL) {
-                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, rawmidi_info,
-                                         defcardinfo, userData);
-            }
-            count++;
-        }
-    }
-
-    // iterate cards
-    card = -1;
-    TRACE0("testing for cards...\n");
-    if (snd_card_next(&card) >= 0) {
-        TRACE1("Found card %d\n", card);
-        while (doContinue && (card >= 0)) {
-            sprintf(devname, ALSA_HARDWARE_CARD, card);
-            TRACE1("Opening control for alsa rawmidi device \"%s\"...\n", devname);
-            err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
-            } else {
-                TRACE0("snd_ctl_open() SUCCESS\n");
-                err = snd_ctl_card_info(handle, card_info);
-                if (err < 0) {
-                    ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", card, snd_strerror(err));
-                } else {
-                    TRACE0("snd_ctl_card_info() SUCCESS\n");
-                    dev = -1;
-                    while (doContinue) {
-                        if (snd_ctl_rawmidi_next_device(handle, &dev) < 0) {
-                            ERROR0("snd_ctl_rawmidi_next_device\n");
-                        }
-                        TRACE0("snd_ctl_rawmidi_next_device() SUCCESS\n");
-                        if (dev < 0) {
-                            break;
-                        }
-                        snd_rawmidi_info_set_device(rawmidi_info, dev);
-                        snd_rawmidi_info_set_subdevice(rawmidi_info, 0);
-                        snd_rawmidi_info_set_stream(rawmidi_info, direction);
-                        err = snd_ctl_rawmidi_info(handle, rawmidi_info);
-                        TRACE0("after snd_ctl_rawmidi_info()\n");
-                        if (err < 0) {
-                            if (err != -ENOENT) {
-                                ERROR2("ERROR: snd_ctl_rawmidi_info, card=%d: %s", card, snd_strerror(err));
-                            }
-                        } else {
-                            TRACE0("snd_ctl_rawmidi_info() SUCCESS\n");
-                            subdeviceCount = needEnumerateSubdevices(ALSA_RAWMIDI)
-                                ? snd_rawmidi_info_get_subdevices_count(rawmidi_info)
-                                : 1;
-                            if (iterator!=NULL) {
-                                for (subDev = 0; subDev < subdeviceCount; subDev++) {
-                                    TRACE3("  Iterating %d,%d,%d\n", card, dev, subDev);
-                                    deviceID = encodeDeviceID(card, dev, subDev);
-                                    doContinue = (*iterator)(deviceID, rawmidi_info,
-                                                             card_info, userData);
-                                    count++;
-                                    TRACE0("returned from iterator\n");
-                                    if (!doContinue) {
-                                        break;
-                                    }
-                                }
-                            } else {
-                                count += subdeviceCount;
-                            }
-                        }
-                    } // of while(doContinue)
-                }
-                snd_ctl_close(handle);
-            }
-            if (snd_card_next(&card) < 0) {
-                break;
-            }
-        }
-    } else {
-        ERROR0("No cards found!\n");
-    }
-    snd_ctl_card_info_free(card_info);
-    snd_rawmidi_info_free(rawmidi_info);
-    return count;
-}
-
-
-
-int getMidiDeviceCount(snd_rawmidi_stream_t direction) {
-    int deviceCount;
-    TRACE0("> getMidiDeviceCount()\n");
-    initAlsaSupport();
-    deviceCount = iterateRawmidiDevices(direction, NULL, NULL);
-    TRACE0("< getMidiDeviceCount()\n");
-    return deviceCount;
-}
-
-
-
-/*
-  userData is assumed to be a pointer to ALSA_MIDIDeviceDescription.
-  ALSA_MIDIDeviceDescription->index has to be set to the index of the device
-  we want to get information of before this method is called the first time via
-  iterateRawmidiDevices(). On each call of this method,
-  ALSA_MIDIDeviceDescription->index is decremented. If it is equal to zero,
-  we have reached the desired device, so action is taken.
-  So after successful completion of iterateRawmidiDevices(),
-  ALSA_MIDIDeviceDescription->index is zero. If it isn't, this is an
-  indication of an error.
-*/
-static int deviceInfoIterator(UINT32 deviceID, snd_rawmidi_info_t *rawmidi_info,
-                              snd_ctl_card_info_t *cardinfo, void *userData) {
-    char buffer[300];
-    ALSA_MIDIDeviceDescription* desc = (ALSA_MIDIDeviceDescription*)userData;
-#ifdef ALSA_MIDI_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    TRACE0("deviceInfoIterator\n");
-    initAlsaSupport();
-    if (desc->index == 0) {
-        // we found the device with correct index
-        desc->deviceID = deviceID;
-
-        buffer[0]=' '; buffer[1]='[';
-        // buffer[300] is enough to store the actual device string w/o overrun
-        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_RAWMIDI);
-        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
-        strncpy(desc->name,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_id(cardinfo)
-                    : snd_rawmidi_info_get_id(rawmidi_info),
-                desc->strLen - strlen(buffer));
-        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
-        desc->description[0] = 0;
-        if (cardinfo != NULL) {
-            strncpy(desc->description, snd_ctl_card_info_get_name(cardinfo),
-                    desc->strLen);
-            strncat(desc->description, ", ",
-                    desc->strLen - strlen(desc->description));
-        }
-        strncat(desc->description, snd_rawmidi_info_get_id(rawmidi_info),
-                desc->strLen - strlen(desc->description));
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_rawmidi_info_get_name(rawmidi_info),
-                desc->strLen - strlen(desc->description));
-        TRACE2("Returning %s, %s\n", desc->name, desc->description);
-        return FALSE; // do not continue iteration
-    }
-    desc->index--;
-    return TRUE;
-}
-
-
-static int getMIDIDeviceDescriptionByIndex(snd_rawmidi_stream_t direction,
-                                           ALSA_MIDIDeviceDescription* desc) {
-    initAlsaSupport();
-    TRACE1(" getMIDIDeviceDescriptionByIndex (index = %d)\n", desc->index);
-    iterateRawmidiDevices(direction, &deviceInfoIterator, desc);
-    return (desc->index == 0) ? MIDI_SUCCESS : MIDI_INVALID_DEVICEID;
-}
-
-
-
-int initMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc, int index) {
-    int ret = MIDI_SUCCESS;
-    desc->index = index;
-    desc->strLen = 200;
-    desc->name = (char*) calloc(desc->strLen + 1, 1);
-    desc->description = (char*) calloc(desc->strLen + 1, 1);
-    if (! desc->name ||
-        ! desc->description) {
-        ret = MIDI_OUT_OF_MEMORY;
-    }
-    return ret;
-}
-
-
-void freeMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc) {
-    if (desc->name) {
-        free(desc->name);
-    }
-    if (desc->description) {
-        free(desc->description);
-    }
-}
-
-
-int getMidiDeviceName(snd_rawmidi_stream_t direction, int index, char *name,
-                      UINT32 nameLength) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    TRACE1("getMidiDeviceName: nameLength: %d\n", (int) nameLength);
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        TRACE0("getMidiDeviceName: initMIDIDeviceDescription() SUCCESS\n");
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
-            strncpy(name, desc.name, nameLength - 1);
-            name[nameLength - 1] = 0;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-int getMidiDeviceVendor(int index, char *name, UINT32 nameLength) {
-    strncpy(name, ALSA_VENDOR, nameLength - 1);
-    name[nameLength - 1] = 0;
-    return MIDI_SUCCESS;
-}
-
-
-int getMidiDeviceDescription(snd_rawmidi_stream_t direction,
-                             int index, char *name, UINT32 nameLength) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            strncpy(name, desc.description, nameLength - 1);
-            name[nameLength - 1] = 0;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-int getMidiDeviceVersion(int index, char *name, UINT32 nameLength) {
-    getALSAVersion(name, nameLength);
-    return MIDI_SUCCESS;
-}
-
-
-static int getMidiDeviceID(snd_rawmidi_stream_t direction, int index,
-                           UINT32* deviceID) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            // TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
-            *deviceID = desc.deviceID;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-/*
-  direction has to be either SND_RAWMIDI_STREAM_INPUT or
-  SND_RAWMIDI_STREAM_OUTPUT.
-  Returns 0 on success. Otherwise, MIDI_OUT_OF_MEMORY, MIDI_INVALID_ARGUMENT
-   or a negative ALSA error code is returned.
-*/
-INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
-                     MidiDeviceHandle** handle) {
-    snd_rawmidi_t* native_handle;
-    snd_midi_event_t* event_parser = NULL;
-    int err;
-    UINT32 deviceID = 0;
-    char devicename[100];
-#ifdef ALSA_MIDI_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    TRACE0("> openMidiDevice()\n");
-
-    (*handle) = (MidiDeviceHandle*) calloc(sizeof(MidiDeviceHandle), 1);
-    if (!(*handle)) {
-        ERROR0("ERROR: openDevice: out of memory\n");
-        return MIDI_OUT_OF_MEMORY;
-    }
-
-    // TODO: iterate to get dev ID from index
-    err = getMidiDeviceID(direction, deviceIndex, &deviceID);
-    TRACE1("  openMidiDevice(): deviceID: %d\n", (int) deviceID);
-    getDeviceStringFromDeviceID(devicename, deviceID,
-                                usePlugHw, ALSA_RAWMIDI);
-    TRACE1("  openMidiDevice(): deviceString: %s\n", devicename);
-
-    // finally open the device
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_rawmidi_open(&native_handle, NULL, devicename,
-                               SND_RAWMIDI_NONBLOCK);
-    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_open(NULL, &native_handle, devicename,
-                               SND_RAWMIDI_NONBLOCK);
-    } else {
-        ERROR0("  ERROR: openMidiDevice(): direction is neither SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
-        err = MIDI_INVALID_ARGUMENT;
-    }
-    if (err < 0) {
-        ERROR1("<  ERROR: openMidiDevice(): snd_rawmidi_open() returned %d\n", err);
-        free(*handle);
-        (*handle) = NULL;
-        return err;
-    }
-    /* We opened with non-blocking behaviour to not get hung if the device
-       is used by a different process. Writing, however, should
-       be blocking. So we change it here. */
-    if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_nonblock(native_handle, 0);
-        if (err < 0) {
-            ERROR1("  ERROR: openMidiDevice(): snd_rawmidi_nonblock() returned %d\n", err);
-            snd_rawmidi_close(native_handle);
-            free(*handle);
-            (*handle) = NULL;
-            return err;
-        }
-    }
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_midi_event_new(EVENT_PARSER_BUFSIZE, &event_parser);
-        if (err < 0) {
-            ERROR1("  ERROR: openMidiDevice(): snd_midi_event_new() returned %d\n", err);
-            snd_rawmidi_close(native_handle);
-            free(*handle);
-            (*handle) = NULL;
-            return err;
-        }
-    }
-
-    (*handle)->deviceHandle = (void*) native_handle;
-    (*handle)->startTime = getTimeInMicroseconds();
-    (*handle)->platformData = event_parser;
-    TRACE0("< openMidiDevice(): succeeded\n");
-    return err;
-}
-
-
-
-INT32 closeMidiDevice(MidiDeviceHandle* handle) {
-    int err;
-
-    TRACE0("> closeMidiDevice()\n");
-    if (!handle) {
-        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: closeMidiDevice(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    err = snd_rawmidi_close((snd_rawmidi_t*) handle->deviceHandle);
-    TRACE1("  snd_rawmidi_close() returns %d\n", err);
-    if (handle->platformData) {
-        snd_midi_event_free((snd_midi_event_t*) handle->platformData);
-    }
-    free(handle);
-    TRACE0("< closeMidiDevice: succeeded\n");
-    return err;
-}
-
-
-INT64 getMidiTimestamp(MidiDeviceHandle* handle) {
-    if (!handle) {
-        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    return getTimeInMicroseconds() - handle->startTime;
-}
-
-
-/* end */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiUtils.h
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiUtils.h	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 
-#include "Utilities.h"
-#include "PlatformMidi.h"
-
-
-#ifndef PLATFORM_API_BSDOS_ALSA_MIDIUTILS_H_INCLUDED
-#define PLATFORM_API_BSDOS_ALSA_MIDIUTILS_H_INCLUDED
-
-#define EVENT_PARSER_BUFSIZE (2048)
-
-// if this is defined, use plughw: devices
-//#define ALSA_MIDI_USE_PLUGHW
-#undef ALSA_MIDI_USE_PLUGHW
-
-typedef struct tag_ALSA_MIDIDeviceDescription {
-        int index;          // in
-        int strLen;         // in
-        INT32 deviceID;    // out
-        char* name;         // out
-        char* description;  // out
-} ALSA_MIDIDeviceDescription;
-
-
-const char* getErrorStr(INT32 err);
-
-/* Returns the number of devices. */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceCount(snd_rawmidi_stream_t direction);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceName(snd_rawmidi_stream_t direction, int index,
-                      char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-int getMidiDeviceVendor(int index, char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceDescription(snd_rawmidi_stream_t direction, int index,
-                             char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-int getMidiDeviceVersion(int index, char *name, UINT32 nameLength);
-
-// returns 0 on success, otherwise MIDI_OUT_OF_MEMORY or ALSA error code
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
-                     MidiDeviceHandle** handle);
-
-// returns 0 on success, otherwise a (negative) ALSA error code
-INT32 closeMidiDevice(MidiDeviceHandle* handle);
-
-INT64 getMidiTimestamp(MidiDeviceHandle* handle);
-
-#endif // PLATFORM_API_BSDOS_ALSA_MIDIUTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,941 +0,0 @@
-/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_BsdOS_ALSA_PCMUtils.h"
-#include "PLATFORM_API_BsdOS_ALSA_CommonUtils.h"
-#include "DirectAudio.h"
-
-#if USE_DAUDIO == TRUE
-
-// GetPosition method 1: based on how many bytes are passed to the kernel driver
-//                       + does not need much processor resources
-//                       - not very exact, "jumps"
-// GetPosition method 2: ask kernel about actual position of playback.
-//                       - very exact
-//                       - switch to kernel layer for each call
-// GetPosition method 3: use snd_pcm_avail() call - not yet in official ALSA
-// quick tests on a Pentium 200MMX showed max. 1.5% processor usage
-// for playing back a CD-quality file and printing 20x per second a line
-// on the console with the current time. So I guess performance is not such a
-// factor here.
-//#define GET_POSITION_METHOD1
-#define GET_POSITION_METHOD2
-
-
-// The default time for a period in microseconds.
-// For very small buffers, only 2 periods are used.
-#define DEFAULT_PERIOD_TIME 20000 /* 20ms */
-
-///// implemented functions of DirectAudio.h
-
-INT32 DAUDIO_GetDirectAudioDeviceCount() {
-    return (INT32) getAudioDeviceCount();
-}
-
-
-INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex, DirectAudioDeviceDescription* description) {
-    ALSA_AudioDeviceDescription adesc;
-
-    adesc.index = (int) mixerIndex;
-    adesc.strLen = DAUDIO_STRING_LENGTH;
-
-    adesc.maxSimultaneousLines = (int*) (&(description->maxSimulLines));
-    adesc.deviceID = &(description->deviceID);
-    adesc.name = description->name;
-    adesc.vendor = description->vendor;
-    adesc.description = description->description;
-    adesc.version = description->version;
-
-    return getAudioDeviceDescriptionByIndex(&adesc);
-}
-
-#define MAX_BIT_INDEX 6
-// returns
-// 6: for anything above 24-bit
-// 5: for 4 bytes sample size, 24-bit
-// 4: for 3 bytes sample size, 24-bit
-// 3: for 3 bytes sample size, 20-bit
-// 2: for 2 bytes sample size, 16-bit
-// 1: for 1 byte sample size, 8-bit
-// 0: for anything else
-int getBitIndex(int sampleSizeInBytes, int significantBits) {
-    if (significantBits > 24) return 6;
-    if (sampleSizeInBytes == 4 && significantBits == 24) return 5;
-    if (sampleSizeInBytes == 3) {
-        if (significantBits == 24) return 4;
-        if (significantBits == 20) return 3;
-    }
-    if (sampleSizeInBytes == 2 && significantBits == 16) return 2;
-    if (sampleSizeInBytes == 1 && significantBits == 8) return 1;
-    return 0;
-}
-
-int getSampleSizeInBytes(int bitIndex, int sampleSizeInBytes) {
-    switch(bitIndex) {
-    case 1: return 1;
-    case 2: return 2;
-    case 3: /* fall through */
-    case 4: return 3;
-    case 5: return 4;
-    }
-    return sampleSizeInBytes;
-}
-
-int getSignificantBits(int bitIndex, int significantBits) {
-    switch(bitIndex) {
-    case 1: return 8;
-    case 2: return 16;
-    case 3: return 20;
-    case 4: /* fall through */
-    case 5: return 24;
-    }
-    return significantBits;
-}
-
-void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
-    snd_pcm_t* handle;
-    snd_pcm_format_mask_t* formatMask;
-    snd_pcm_format_t format;
-    snd_pcm_hw_params_t* hwParams;
-    int handledBits[MAX_BIT_INDEX+1];
-
-    int ret;
-    int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc;
-    int origSampleSizeInBytes, origSignificantBits;
-    unsigned int channels, minChannels, maxChannels;
-    int rate, bitIndex;
-
-    for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE;
-    if (openPCMfromDeviceID(deviceID, &handle, isSource, TRUE /*query hardware*/) < 0) {
-        return;
-    }
-    ret = snd_pcm_format_mask_malloc(&formatMask);
-    if (ret != 0) {
-        ERROR1("snd_pcm_format_mask_malloc returned error %d\n", ret);
-    } else {
-        ret = snd_pcm_hw_params_malloc(&hwParams);
-        if (ret != 0) {
-            ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
-        } else {
-            ret = snd_pcm_hw_params_any(handle, hwParams);
-            /* snd_pcm_hw_params_any can return a positive value on success too */
-            if (ret < 0) {
-                 ERROR1("snd_pcm_hw_params_any returned error %d\n", ret);
-            } else {
-                /* for the logic following this code, set ret to 0 to indicate success */
-                ret = 0;
-            }
-        }
-        snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
-        if (ret == 0) {
-            ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels);
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_get_channels_min returned error %d\n", ret);
-            }
-        }
-        if (ret == 0) {
-            ret = snd_pcm_hw_params_get_channels_max(hwParams, &maxChannels);
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret);
-            }
-        }
-
-        // since we queried the hw: device, for many soundcards, it will only
-        // report the maximum number of channels (which is the only way to talk
-        // to the hw: device). Since we will, however, open the plughw: device
-        // when opening the Source/TargetDataLine, we can safely assume that
-        // also the channels 1..maxChannels are available.
-#ifdef ALSA_PCM_USE_PLUGHW
-        minChannels = 1;
-#endif
-        if (ret == 0) {
-            // plughw: supports any sample rate
-            rate = -1;
-            for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
-                if (snd_pcm_format_mask_test(formatMask, format)) {
-                    // format exists
-                    if (getFormatFromAlsaFormat(format, &origSampleSizeInBytes,
-                                                &origSignificantBits,
-                                                &isSigned, &isBigEndian, &enc)) {
-                        // now if we use plughw:, we can use any bit size below the
-                        // natively supported ones. Some ALSA drivers only support the maximum
-                        // bit size, so we add any sample rates below the reported one.
-                        // E.g. this iteration reports support for 16-bit.
-                        // getBitIndex will return 2, so it will add entries for
-                        // 16-bit (bitIndex=2) and in the next do-while loop iteration,
-                        // it will decrease bitIndex and will therefore add 8-bit support.
-                        bitIndex = getBitIndex(origSampleSizeInBytes, origSignificantBits);
-                        do {
-                            if (bitIndex == 0
-                                || bitIndex == MAX_BIT_INDEX
-                                || !handledBits[bitIndex]) {
-                                handledBits[bitIndex] = TRUE;
-                                sampleSizeInBytes = getSampleSizeInBytes(bitIndex, origSampleSizeInBytes);
-                                significantBits = getSignificantBits(bitIndex, origSignificantBits);
-                                if (maxChannels - minChannels > MAXIMUM_LISTED_CHANNELS) {
-                                    // avoid too many channels explicitly listed
-                                    // just add -1, min, and max
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          -1, -1, rate,
-                                                          enc, isSigned, isBigEndian);
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          sampleSizeInBytes * minChannels,
-                                                          minChannels, rate,
-                                                          enc, isSigned, isBigEndian);
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          sampleSizeInBytes * maxChannels,
-                                                          maxChannels, rate,
-                                                          enc, isSigned, isBigEndian);
-                                } else {
-                                    for (channels = minChannels; channels <= maxChannels; channels++) {
-                                        DAUDIO_AddAudioFormat(creator, significantBits,
-                                                              sampleSizeInBytes * channels,
-                                                              channels, rate,
-                                                              enc, isSigned, isBigEndian);
-                                    }
-                                }
-                            }
-#ifndef ALSA_PCM_USE_PLUGHW
-                            // without plugin, do not add fake formats
-                            break;
-#endif
-                        } while (--bitIndex > 0);
-                    } else {
-                        TRACE1("could not get format from alsa for format %d\n", format);
-                    }
-                } else {
-                    //TRACE1("Format %d not supported\n", format);
-                }
-            } // for loop
-            snd_pcm_hw_params_free(hwParams);
-        }
-        snd_pcm_format_mask_free(formatMask);
-    }
-    snd_pcm_close(handle);
-}
-
-/** Workaround for cr 7033899, 7030629:
- * dmix plugin doesn't like flush (snd_pcm_drop) when the buffer is empty
- * (just opened, underruned or already flushed).
- * Sometimes it causes PCM falls to -EBADFD error,
- * sometimes causes bufferSize change.
- * To prevent unnecessary flushes AlsaPcmInfo::isRunning & isFlushed are used.
- */
-/* ******* ALSA PCM INFO ******************** */
-typedef struct tag_AlsaPcmInfo {
-    snd_pcm_t* handle;
-    snd_pcm_hw_params_t* hwParams;
-    snd_pcm_sw_params_t* swParams;
-    int bufferSizeInBytes;
-    int frameSize; // storage size in Bytes
-    unsigned int periods;
-    snd_pcm_uframes_t periodSize;
-    short int isRunning;    // see comment above
-    short int isFlushed;    // see comment above
-#ifdef GET_POSITION_METHOD2
-    // to be used exclusively by getBytePosition!
-    snd_pcm_status_t* positionStatus;
-#endif
-} AlsaPcmInfo;
-
-
-int setStartThresholdNoCommit(AlsaPcmInfo* info, int useThreshold) {
-    int ret;
-    int threshold;
-
-    if (useThreshold) {
-        // start device whenever anything is written to the buffer
-        threshold = 1;
-    } else {
-        // never start the device automatically
-        threshold = 2000000000; /* near UINT_MAX */
-    }
-    ret = snd_pcm_sw_params_set_start_threshold(info->handle, info->swParams, threshold);
-    if (ret < 0) {
-        ERROR1("Unable to set start threshold mode: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-int setStartThreshold(AlsaPcmInfo* info, int useThreshold) {
-    int ret = 0;
-
-    if (!setStartThresholdNoCommit(info, useThreshold)) {
-        ret = -1;
-    }
-    if (ret == 0) {
-        // commit it
-        ret = snd_pcm_sw_params(info->handle, info->swParams);
-        if (ret < 0) {
-            ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
-        }
-    }
-    return (ret == 0)?TRUE:FALSE;
-}
-
-
-// returns TRUE if successful
-int setHWParams(AlsaPcmInfo* info,
-                float sampleRate,
-                int channels,
-                int bufferSizeInFrames,
-                snd_pcm_format_t format) {
-    unsigned int rrate, periodTime, periods;
-    int ret, dir;
-    snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames;
-
-    /* choose all parameters */
-    ret = snd_pcm_hw_params_any(info->handle, info->hwParams);
-    if (ret < 0) {
-        ERROR1("Broken configuration: no configurations available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the interleaved read/write format */
-    ret = snd_pcm_hw_params_set_access(info->handle, info->hwParams, SND_PCM_ACCESS_RW_INTERLEAVED);
-    if (ret < 0) {
-        ERROR1("SND_PCM_ACCESS_RW_INTERLEAVED access type not available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the sample format */
-    ret = snd_pcm_hw_params_set_format(info->handle, info->hwParams, format);
-    if (ret < 0) {
-        ERROR1("Sample format not available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the count of channels */
-    ret = snd_pcm_hw_params_set_channels(info->handle, info->hwParams, channels);
-    if (ret < 0) {
-        ERROR2("Channels count (%d) not available: %s\n", channels, snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the stream rate */
-    rrate = (int) (sampleRate + 0.5f);
-    dir = 0;
-    ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir);
-    if (ret < 0) {
-        ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret));
-        return FALSE;
-    }
-    if ((rrate-sampleRate > 2) || (rrate-sampleRate < - 2)) {
-        ERROR2("Rate doesn't match (requested %2.2fHz, got %dHz)\n", sampleRate, rrate);
-        return FALSE;
-    }
-    /* set the buffer time */
-    ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames);
-    if (ret < 0) {
-        ERROR2("Unable to set buffer size to %d frames: %s\n",
-               (int) alsaBufferSizeInFrames, snd_strerror(ret));
-        return FALSE;
-    }
-    bufferSizeInFrames = (int) alsaBufferSizeInFrames;
-    /* set the period time */
-    if (bufferSizeInFrames > 1024) {
-        dir = 0;
-        periodTime = DEFAULT_PERIOD_TIME;
-        ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir);
-        if (ret < 0) {
-            ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret));
-            return FALSE;
-        }
-    } else {
-        /* set the period count for very small buffer sizes to 2 */
-        dir = 0;
-        periods = 2;
-        ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir);
-        if (ret < 0) {
-            ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret));
-            return FALSE;
-        }
-    }
-    /* write the parameters to device */
-    ret = snd_pcm_hw_params(info->handle, info->hwParams);
-    if (ret < 0) {
-        ERROR1("Unable to set hw params: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-// returns 1 if successful
-int setSWParams(AlsaPcmInfo* info) {
-    int ret;
-
-    /* get the current swparams */
-    ret = snd_pcm_sw_params_current(info->handle, info->swParams);
-    if (ret < 0) {
-        ERROR1("Unable to determine current swparams: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* never start the transfer automatically */
-    if (!setStartThresholdNoCommit(info, FALSE /* don't use threshold */)) {
-        return FALSE;
-    }
-
-    /* allow the transfer when at least period_size samples can be processed */
-    ret = snd_pcm_sw_params_set_avail_min(info->handle, info->swParams, info->periodSize);
-    if (ret < 0) {
-        ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* write the parameters to the playback device */
-    ret = snd_pcm_sw_params(info->handle, info->swParams);
-    if (ret < 0) {
-        ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-static snd_output_t* ALSA_OUTPUT = NULL;
-
-void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
-                  int encoding, float sampleRate, int sampleSizeInBits,
-                  int frameSize, int channels,
-                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
-    snd_pcm_format_mask_t* formatMask;
-    snd_pcm_format_t format;
-    int dir;
-    int ret = 0;
-    AlsaPcmInfo* info = NULL;
-    /* snd_pcm_uframes_t is 64 bit on 64-bit systems */
-    snd_pcm_uframes_t alsaBufferSizeInFrames = 0;
-
-
-    TRACE0("> DAUDIO_Open\n");
-#ifdef USE_TRACE
-    // for using ALSA debug dump methods
-    if (ALSA_OUTPUT == NULL) {
-        snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
-    }
-#endif
-    if (channels <= 0) {
-        ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
-        return NULL;
-    }
-    info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
-    if (!info) {
-        ERROR0("Out of memory\n");
-        return NULL;
-    }
-    memset(info, 0, sizeof(AlsaPcmInfo));
-    // initial values are: stopped, flushed
-    info->isRunning = 0;
-    info->isFlushed = 1;
-
-    ret = openPCMfromDeviceID(deviceID, &(info->handle), isSource, FALSE /* do open device*/);
-    if (ret == 0) {
-        // set to blocking mode
-        snd_pcm_nonblock(info->handle, 0);
-        ret = snd_pcm_hw_params_malloc(&(info->hwParams));
-        if (ret != 0) {
-            ERROR1("  snd_pcm_hw_params_malloc returned error %d\n", ret);
-        } else {
-            ret = -1;
-            if (getAlsaFormatFromFormat(&format, frameSize / channels, sampleSizeInBits,
-                                        isSigned, isBigEndian, encoding)) {
-                if (setHWParams(info,
-                                sampleRate,
-                                channels,
-                                bufferSizeInBytes / frameSize,
-                                format)) {
-                    info->frameSize = frameSize;
-                    ret = snd_pcm_hw_params_get_period_size(info->hwParams, &info->periodSize, &dir);
-                    if (ret < 0) {
-                        ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret));
-                    }
-                    snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir);
-                    snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames);
-                    info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize;
-                    TRACE3("  DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n",
-                           (int) info->periodSize, info->periods, info->bufferSizeInBytes);
-                }
-            }
-        }
-        if (ret == 0) {
-            // set software parameters
-            ret = snd_pcm_sw_params_malloc(&(info->swParams));
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
-            } else {
-                if (!setSWParams(info)) {
-                    ret = -1;
-                }
-            }
-        }
-        if (ret == 0) {
-            // prepare device
-            ret = snd_pcm_prepare(info->handle);
-            if (ret < 0) {
-                ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
-            }
-        }
-
-#ifdef GET_POSITION_METHOD2
-        if (ret == 0) {
-            ret = snd_pcm_status_malloc(&(info->positionStatus));
-            if (ret != 0) {
-                ERROR1("ERROR in snd_pcm_status_malloc: %s\n", snd_strerror(ret));
-            }
-        }
-#endif
-    }
-    if (ret != 0) {
-        DAUDIO_Close((void*) info, isSource);
-        info = NULL;
-    } else {
-        // set to non-blocking mode
-        snd_pcm_nonblock(info->handle, 1);
-        TRACE1("< DAUDIO_Open: Opened device successfully. Handle=%p\n",
-               (void*) info->handle);
-    }
-    return (void*) info;
-}
-
-#ifdef USE_TRACE
-void printState(snd_pcm_state_t state) {
-    if (state == SND_PCM_STATE_OPEN) {
-        TRACE0("State: SND_PCM_STATE_OPEN\n");
-    }
-    else if (state == SND_PCM_STATE_SETUP) {
-        TRACE0("State: SND_PCM_STATE_SETUP\n");
-    }
-    else if (state == SND_PCM_STATE_PREPARED) {
-        TRACE0("State: SND_PCM_STATE_PREPARED\n");
-    }
-    else if (state == SND_PCM_STATE_RUNNING) {
-        TRACE0("State: SND_PCM_STATE_RUNNING\n");
-    }
-    else if (state == SND_PCM_STATE_XRUN) {
-        TRACE0("State: SND_PCM_STATE_XRUN\n");
-    }
-    else if (state == SND_PCM_STATE_DRAINING) {
-        TRACE0("State: SND_PCM_STATE_DRAINING\n");
-    }
-    else if (state == SND_PCM_STATE_PAUSED) {
-        TRACE0("State: SND_PCM_STATE_PAUSED\n");
-    }
-    else if (state == SND_PCM_STATE_SUSPENDED) {
-        TRACE0("State: SND_PCM_STATE_SUSPENDED\n");
-    }
-}
-#endif
-
-int DAUDIO_Start(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-    snd_pcm_state_t state;
-
-    TRACE0("> DAUDIO_Start\n");
-    // set to blocking mode
-    snd_pcm_nonblock(info->handle, 0);
-    // set start mode so that it always starts as soon as data is there
-    setStartThreshold(info, TRUE /* use threshold */);
-    state = snd_pcm_state(info->handle);
-    if (state == SND_PCM_STATE_PAUSED) {
-        // in case it was stopped previously
-        TRACE0("  Un-pausing...\n");
-        ret = snd_pcm_pause(info->handle, FALSE);
-        if (ret != 0) {
-            ERROR2("  NOTE: error in snd_pcm_pause:%d: %s\n", ret, snd_strerror(ret));
-        }
-    }
-    if (state == SND_PCM_STATE_SUSPENDED) {
-        TRACE0("  Resuming...\n");
-        ret = snd_pcm_resume(info->handle);
-        if (ret < 0) {
-            if ((ret != -EAGAIN) && (ret != -ENOSYS)) {
-                ERROR2("  ERROR: error in snd_pcm_resume:%d: %s\n", ret, snd_strerror(ret));
-            }
-        }
-    }
-    if (state == SND_PCM_STATE_SETUP) {
-        TRACE0("need to call prepare again...\n");
-        // prepare device
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
-        }
-    }
-    // in case there is still data in the buffers
-    ret = snd_pcm_start(info->handle);
-    if (ret != 0) {
-        if (ret != -EPIPE) {
-            ERROR2("  NOTE: error in snd_pcm_start: %d: %s\n", ret, snd_strerror(ret));
-        }
-    }
-    // set to non-blocking mode
-    ret = snd_pcm_nonblock(info->handle, 1);
-    if (ret != 0) {
-        ERROR1("  ERROR in snd_pcm_nonblock: %s\n", snd_strerror(ret));
-    }
-    state = snd_pcm_state(info->handle);
-#ifdef USE_TRACE
-    printState(state);
-#endif
-    ret = (state == SND_PCM_STATE_PREPARED)
-        || (state == SND_PCM_STATE_RUNNING)
-        || (state == SND_PCM_STATE_XRUN)
-        || (state == SND_PCM_STATE_SUSPENDED);
-    if (ret) {
-        info->isRunning = 1;
-        // source line should keep isFlushed value until Write() is called;
-        // for target data line reset it right now.
-        if (!isSource) {
-            info->isFlushed = 0;
-        }
-    }
-    TRACE1("< DAUDIO_Start %s\n", ret?"success":"error");
-    return ret?TRUE:FALSE;
-}
-
-int DAUDIO_Stop(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-
-    TRACE0("> DAUDIO_Stop\n");
-    // set to blocking mode
-    snd_pcm_nonblock(info->handle, 0);
-    setStartThreshold(info, FALSE /* don't use threshold */); // device will not start after buffer xrun
-    ret = snd_pcm_pause(info->handle, 1);
-    // set to non-blocking mode
-    snd_pcm_nonblock(info->handle, 1);
-    if (ret != 0) {
-        ERROR1("ERROR in snd_pcm_pause: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    info->isRunning = 0;
-    TRACE0("< DAUDIO_Stop success\n");
-    return TRUE;
-}
-
-void DAUDIO_Close(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-
-    TRACE0("DAUDIO_Close\n");
-    if (info != NULL) {
-        if (info->handle != NULL) {
-            snd_pcm_close(info->handle);
-        }
-        if (info->hwParams) {
-            snd_pcm_hw_params_free(info->hwParams);
-        }
-        if (info->swParams) {
-            snd_pcm_sw_params_free(info->swParams);
-        }
-#ifdef GET_POSITION_METHOD2
-        if (info->positionStatus) {
-            snd_pcm_status_free(info->positionStatus);
-        }
-#endif
-        free(info);
-    }
-}
-
-/*
- * Underrun and suspend recovery
- * returns
- * 0:  exit native and return 0
- * 1:  try again to write/read
- * -1: error - exit native with return value -1
- */
-int xrun_recovery(AlsaPcmInfo* info, int err) {
-    int ret;
-
-    if (err == -EPIPE) {    /* underrun / overflow */
-        TRACE0("xrun_recovery: underrun/overflow.\n");
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
-            return -1;
-        }
-        return 1;
-    } else if (err == -ESTRPIPE) {
-        TRACE0("xrun_recovery: suspended.\n");
-        ret = snd_pcm_resume(info->handle);
-        if (ret < 0) {
-            if (ret == -EAGAIN) {
-                return 0; /* wait until the suspend flag is released */
-            }
-            return -1;
-        }
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
-            return -1;
-        }
-        return 1;
-    } else if (err == -EAGAIN) {
-        TRACE0("xrun_recovery: EAGAIN try again flag.\n");
-        return 0;
-    }
-
-    TRACE2("xrun_recovery: unexpected error %d: %s\n", err, snd_strerror(err));
-    return -1;
-}
-
-// returns -1 on error
-int DAUDIO_Write(void* id, char* data, int byteSize) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret, count;
-    snd_pcm_sframes_t frameSize, writtenFrames;
-
-    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
-
-    /* sanity */
-    if (byteSize <= 0 || info->frameSize <= 0) {
-        ERROR2(" DAUDIO_Write: byteSize=%d, frameSize=%d!\n",
-               (int) byteSize, (int) info->frameSize);
-        TRACE0("< DAUDIO_Write returning -1\n");
-        return -1;
-    }
-
-    count = 2; // maximum number of trials to recover from underrun
-    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
-    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
-    do {
-        writtenFrames = snd_pcm_writei(info->handle, (const void*) data, (snd_pcm_uframes_t) frameSize);
-
-        if (writtenFrames < 0) {
-            ret = xrun_recovery(info, (int) writtenFrames);
-            if (ret <= 0) {
-                TRACE1("DAUDIO_Write: xrun recovery returned %d -> return.\n", ret);
-                return ret;
-            }
-            if (count-- <= 0) {
-                ERROR0("DAUDIO_Write: too many attempts to recover from xrun/suspend\n");
-                return -1;
-            }
-        } else {
-            break;
-        }
-    } while (TRUE);
-    //ret =  snd_pcm_frames_to_bytes(info->handle, writtenFrames);
-
-    if (writtenFrames > 0) {
-        // reset "flushed" flag
-        info->isFlushed = 0;
-    }
-
-    ret =  (int) (writtenFrames * info->frameSize);
-    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
-    return ret;
-}
-
-// returns -1 on error
-int DAUDIO_Read(void* id, char* data, int byteSize) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret, count;
-    snd_pcm_sframes_t frameSize, readFrames;
-
-    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
-    /*TRACE3("  info=%p, data=%p, byteSize=%d\n",
-      (void*) info, (void*) data, (int) byteSize);
-      TRACE2("  info->frameSize=%d, info->handle=%p\n",
-      (int) info->frameSize, (void*) info->handle);
-    */
-    /* sanity */
-    if (byteSize <= 0 || info->frameSize <= 0) {
-        ERROR2(" DAUDIO_Read: byteSize=%d, frameSize=%d!\n",
-               (int) byteSize, (int) info->frameSize);
-        TRACE0("< DAUDIO_Read returning -1\n");
-        return -1;
-    }
-    if (!info->isRunning && info->isFlushed) {
-        // PCM has nothing to read
-        return 0;
-    }
-
-    count = 2; // maximum number of trials to recover from error
-    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
-    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
-    do {
-        readFrames = snd_pcm_readi(info->handle, (void*) data, (snd_pcm_uframes_t) frameSize);
-        if (readFrames < 0) {
-            ret = xrun_recovery(info, (int) readFrames);
-            if (ret <= 0) {
-                TRACE1("DAUDIO_Read: xrun recovery returned %d -> return.\n", ret);
-                return ret;
-            }
-            if (count-- <= 0) {
-                ERROR0("DAUDIO_Read: too many attempts to recover from xrun/suspend\n");
-                return -1;
-            }
-        } else {
-            break;
-        }
-    } while (TRUE);
-    //ret =  snd_pcm_frames_to_bytes(info->handle, readFrames);
-    ret =  (int) (readFrames * info->frameSize);
-    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
-    return ret;
-}
-
-
-int DAUDIO_GetBufferSize(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-
-    return info->bufferSizeInBytes;
-}
-
-int DAUDIO_StillDraining(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    snd_pcm_state_t state;
-
-    state = snd_pcm_state(info->handle);
-    //printState(state);
-    //TRACE1("Still draining: %s\n", (state != SND_PCM_STATE_XRUN)?"TRUE":"FALSE");
-    return (state == SND_PCM_STATE_RUNNING)?TRUE:FALSE;
-}
-
-
-int DAUDIO_Flush(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-
-    TRACE0("DAUDIO_Flush\n");
-
-    if (info->isFlushed) {
-        // nothing to drop
-        return 1;
-    }
-
-    ret = snd_pcm_drop(info->handle);
-    if (ret != 0) {
-        ERROR1("ERROR in snd_pcm_drop: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-
-    info->isFlushed = 1;
-    if (info->isRunning) {
-        ret = DAUDIO_Start(id, isSource);
-    }
-    return ret;
-}
-
-int DAUDIO_GetAvailable(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    snd_pcm_sframes_t availableInFrames;
-    snd_pcm_state_t state;
-    int ret;
-
-    state = snd_pcm_state(info->handle);
-    if (info->isFlushed || state == SND_PCM_STATE_XRUN) {
-        // if in xrun state then we have the entire buffer available,
-        // not 0 as alsa reports
-        ret = info->bufferSizeInBytes;
-    } else {
-        availableInFrames = snd_pcm_avail_update(info->handle);
-        if (availableInFrames < 0) {
-            ret = 0;
-        } else {
-            //ret = snd_pcm_frames_to_bytes(info->handle, availableInFrames);
-            ret = (int) (availableInFrames * info->frameSize);
-        }
-    }
-    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
-    return ret;
-}
-
-INT64 estimatePositionFromAvail(AlsaPcmInfo* info, int isSource, INT64 javaBytePos, int availInBytes) {
-    // estimate the current position with the buffer size and
-    // the available bytes to read or write in the buffer.
-    // not an elegant solution - bytePos will stop on xruns,
-    // and in race conditions it may jump backwards
-    // Advantage is that it is indeed based on the samples that go through
-    // the system (rather than time-based methods)
-    if (isSource) {
-        // javaBytePos is the position that is reached when the current
-        // buffer is played completely
-        return (INT64) (javaBytePos - info->bufferSizeInBytes + availInBytes);
-    } else {
-        // javaBytePos is the position that was when the current buffer was empty
-        return (INT64) (javaBytePos + availInBytes);
-    }
-}
-
-INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-    INT64 result = javaBytePos;
-    snd_pcm_state_t state;
-    state = snd_pcm_state(info->handle);
-
-    if (!info->isFlushed && state != SND_PCM_STATE_XRUN) {
-#ifdef GET_POSITION_METHOD2
-        snd_timestamp_t* ts;
-        snd_pcm_uframes_t framesAvail;
-
-        // note: slight race condition if this is called simultaneously from 2 threads
-        ret = snd_pcm_status(info->handle, info->positionStatus);
-        if (ret != 0) {
-            ERROR1("ERROR in snd_pcm_status: %s\n", snd_strerror(ret));
-            result = javaBytePos;
-        } else {
-            // calculate from time value, or from available bytes
-            framesAvail = snd_pcm_status_get_avail(info->positionStatus);
-            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
-        }
-#endif
-#ifdef GET_POSITION_METHOD3
-        snd_pcm_uframes_t framesAvail;
-        ret = snd_pcm_avail(info->handle, &framesAvail);
-        if (ret != 0) {
-            ERROR1("ERROR in snd_pcm_avail: %s\n", snd_strerror(ret));
-            result = javaBytePos;
-        } else {
-            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
-        }
-#endif
-#ifdef GET_POSITION_METHOD1
-        result = estimatePositionFromAvail(info, isSource, javaBytePos, DAUDIO_GetAvailable(id, isSource));
-#endif
-    }
-    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
-    return result;
-}
-
-
-
-void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    /* save to ignore, since GetBytePosition
-     * takes the javaBytePos param into account
-     */
-}
-
-int DAUDIO_RequiresServicing(void* id, int isSource) {
-    // never need servicing on Bsd
-    return FALSE;
-}
-
-void DAUDIO_Service(void* id, int isSource) {
-    // never need servicing on Bsd
-}
-
-
-#endif // USE_DAUDIO
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCMUtils.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCMUtils.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-//#define USE_ERROR
-//#define USE_TRACE
-
-#include "PLATFORM_API_BsdOS_ALSA_PCMUtils.h"
-#include "PLATFORM_API_BsdOS_ALSA_CommonUtils.h"
-
-
-
-// callback for iteration through devices
-// returns TRUE if iteration should continue
-// NOTE: cardinfo may be NULL (for "default" device)
-typedef int (*DeviceIteratorPtr)(UINT32 deviceID, snd_pcm_info_t* pcminfo,
-                             snd_ctl_card_info_t* cardinfo, void *userData);
-
-// for each ALSA device, call iterator. userData is passed to the iterator
-// returns total number of iterations
-int iteratePCMDevices(DeviceIteratorPtr iterator, void* userData) {
-    int count = 0;
-    int subdeviceCount;
-    int card, dev, subDev;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_pcm_t *pcm;
-    snd_pcm_info_t* pcminfo;
-    snd_ctl_card_info_t *cardinfo, *defcardinfo = NULL;
-    UINT32 deviceID;
-    int doContinue = TRUE;
-
-    snd_pcm_info_malloc(&pcminfo);
-    snd_ctl_card_info_malloc(&cardinfo);
-
-    // 1st try "default" device
-    err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
-                       SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
-    if (err < 0) {
-        // try with the other direction
-        err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
-                           SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
-    }
-    if (err < 0) {
-        ERROR1("ERROR: snd_pcm_open (\"default\"): %s\n", snd_strerror(err));
-    } else {
-        err = snd_pcm_info(pcm, pcminfo);
-        snd_pcm_close(pcm);
-        if (err < 0) {
-            ERROR1("ERROR: snd_pcm_info (\"default\"): %s\n",
-                    snd_strerror(err));
-        } else {
-            // try to get card info
-            card = snd_pcm_info_get_card(pcminfo);
-            if (card >= 0) {
-                sprintf(devname, ALSA_HARDWARE_CARD, card);
-                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
-                    if (snd_ctl_card_info(handle, cardinfo) >= 0) {
-                        defcardinfo = cardinfo;
-                    }
-                    snd_ctl_close(handle);
-                }
-            }
-            // call callback function for the device
-            if (iterator != NULL) {
-                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, pcminfo,
-                                         defcardinfo, userData);
-            }
-            count++;
-        }
-    }
-
-    // iterate cards
-    card = -1;
-    while (doContinue) {
-        if (snd_card_next(&card) < 0) {
-            break;
-        }
-        if (card < 0) {
-            break;
-        }
-        sprintf(devname, ALSA_HARDWARE_CARD, card);
-        TRACE1("Opening alsa device \"%s\"...\n", devname);
-        err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
-        if (err < 0) {
-            ERROR2("ERROR: snd_ctl_open, card=%d: %s\n",
-                    card, snd_strerror(err));
-        } else {
-            err = snd_ctl_card_info(handle, cardinfo);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n",
-                        card, snd_strerror(err));
-            } else {
-                dev = -1;
-                while (doContinue) {
-                    if (snd_ctl_pcm_next_device(handle, &dev) < 0) {
-                        ERROR0("snd_ctl_pcm_next_device\n");
-                    }
-                    if (dev < 0) {
-                        break;
-                    }
-                    snd_pcm_info_set_device(pcminfo, dev);
-                    snd_pcm_info_set_subdevice(pcminfo, 0);
-                    snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
-                    err = snd_ctl_pcm_info(handle, pcminfo);
-                    if (err == -ENOENT) {
-                        // try with the other direction
-                        snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
-                        err = snd_ctl_pcm_info(handle, pcminfo);
-                    }
-                    if (err < 0) {
-                        if (err != -ENOENT) {
-                            ERROR2("ERROR: snd_ctl_pcm_info, card=%d: %s",
-                                    card, snd_strerror(err));
-                        }
-                    } else {
-                        subdeviceCount = needEnumerateSubdevices(ALSA_PCM) ?
-                            snd_pcm_info_get_subdevices_count(pcminfo) : 1;
-                        if (iterator!=NULL) {
-                            for (subDev = 0; subDev < subdeviceCount; subDev++) {
-                                deviceID = encodeDeviceID(card, dev, subDev);
-                                doContinue = (*iterator)(deviceID, pcminfo,
-                                                         cardinfo, userData);
-                                count++;
-                                if (!doContinue) {
-                                    break;
-                                }
-                            }
-                        } else {
-                            count += subdeviceCount;
-                        }
-                    }
-                } // of while(doContinue)
-            }
-            snd_ctl_close(handle);
-        }
-    }
-    snd_ctl_card_info_free(cardinfo);
-    snd_pcm_info_free(pcminfo);
-    return count;
-}
-
-int getAudioDeviceCount() {
-    initAlsaSupport();
-    return iteratePCMDevices(NULL, NULL);
-}
-
-int deviceInfoIterator(UINT32 deviceID, snd_pcm_info_t* pcminfo,
-                       snd_ctl_card_info_t* cardinfo, void* userData) {
-    char buffer[300];
-    ALSA_AudioDeviceDescription* desc = (ALSA_AudioDeviceDescription*)userData;
-#ifdef ALSA_PCM_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    initAlsaSupport();
-    if (desc->index == 0) {
-        // we found the device with correct index
-        *(desc->maxSimultaneousLines) = needEnumerateSubdevices(ALSA_PCM) ?
-                1 : snd_pcm_info_get_subdevices_count(pcminfo);
-        *desc->deviceID = deviceID;
-        buffer[0]=' '; buffer[1]='[';
-        // buffer[300] is enough to store the actual device string w/o overrun
-        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_PCM);
-        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
-        strncpy(desc->name,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_id(cardinfo)
-                    : snd_pcm_info_get_id(pcminfo),
-                desc->strLen - strlen(buffer));
-        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
-        strncpy(desc->vendor, "ALSA (http://www.alsa-project.org)", desc->strLen);
-        strncpy(desc->description,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_name(cardinfo)
-                    : snd_pcm_info_get_name(pcminfo),
-                desc->strLen);
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_pcm_info_get_id(pcminfo), desc->strLen - strlen(desc->description));
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_pcm_info_get_name(pcminfo), desc->strLen - strlen(desc->description));
-        getALSAVersion(desc->version, desc->strLen);
-        TRACE4("Returning %s, %s, %s, %s\n", desc->name, desc->vendor, desc->description, desc->version);
-        return FALSE; // do not continue iteration
-    }
-    desc->index--;
-    return TRUE;
-}
-
-// returns 0 if successful
-int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware) {
-    char buffer[200];
-    int ret;
-
-    initAlsaSupport();
-    getDeviceStringFromDeviceID(buffer, deviceID, !hardware, ALSA_PCM);
-
-    TRACE1("Opening ALSA device %s\n", buffer);
-    ret = snd_pcm_open(handle, buffer,
-                       isSource?SND_PCM_STREAM_PLAYBACK:SND_PCM_STREAM_CAPTURE,
-                       SND_PCM_NONBLOCK);
-    if (ret != 0) {
-        ERROR1("snd_pcm_open returned error code %d \n", ret);
-        *handle = NULL;
-    }
-    return ret;
-}
-
-
-int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc) {
-    initAlsaSupport();
-    TRACE1(" getAudioDeviceDescriptionByIndex(mixerIndex = %d\n", desc->index);
-    iteratePCMDevices(&deviceInfoIterator, desc);
-    return (desc->index == 0)?TRUE:FALSE;
-}
-
-// returns 1 if successful
-// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
-int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
-                            int* sampleSizeInBytes, int* significantBits,
-                            int* isSigned, int* isBigEndian, int* enc) {
-
-    *sampleSizeInBytes = (snd_pcm_format_physical_width(alsaFormat) + 7) / 8;
-    *significantBits = snd_pcm_format_width(alsaFormat);
-
-    // defaults
-    *enc = 0; // PCM
-    *isSigned = (snd_pcm_format_signed(alsaFormat) > 0);
-    *isBigEndian = (snd_pcm_format_big_endian(alsaFormat) > 0);
-
-    // non-PCM formats
-    if (alsaFormat == SND_PCM_FORMAT_MU_LAW) { // Mu-Law
-        *sampleSizeInBytes = 8; *enc = 1; *significantBits = *sampleSizeInBytes;
-    }
-    else if (alsaFormat == SND_PCM_FORMAT_A_LAW) {     // A-Law
-        *sampleSizeInBytes = 8; *enc = 2; *significantBits = *sampleSizeInBytes;
-    }
-    else if (snd_pcm_format_linear(alsaFormat) < 1) {
-        return 0;
-    }
-    return (*sampleSizeInBytes > 0);
-}
-
-// returns 1 if successful
-int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
-                            int sampleSizeInBytes, int significantBits,
-                            int isSigned, int isBigEndian, int enc) {
-    *alsaFormat = SND_PCM_FORMAT_UNKNOWN;
-
-    if (enc == 0) {
-        *alsaFormat = snd_pcm_build_linear_format(significantBits,
-                                                  sampleSizeInBytes * 8,
-                                                  isSigned?0:1,
-                                                  isBigEndian?1:0);
-    }
-    else if ((sampleSizeInBytes == 1) && (significantBits == 8)) {
-        if (enc == 1) { // ULAW
-            *alsaFormat = SND_PCM_FORMAT_MU_LAW;
-        }
-        else if (enc == 2) { // ALAW
-            *alsaFormat = SND_PCM_FORMAT_A_LAW;
-        }
-    }
-    return (*alsaFormat == SND_PCM_FORMAT_UNKNOWN)?0:1;
-}
-
-
-/* end */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCMUtils.h
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCMUtils.h	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-// define this with a later version of ALSA than 0.9.0rc3
-// (starting from 1.0.0 it became default behaviour)
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#include 
-#include "Utilities.h"
-
-#ifndef PLATFORM_API_BSDOS_ALSA_PCMUTILS_H_INCLUDED
-#define PLATFORM_API_BSDOS_ALSA_PCMUTILS_H_INCLUDED
-
-// if this is defined, use plughw: devices
-#define ALSA_PCM_USE_PLUGHW
-//#undef ALSA_PCM_USE_PLUGHW
-
-
-// maximum number of channels that is listed in the formats. If more, than
-// just -1 for channel count is used.
-#define MAXIMUM_LISTED_CHANNELS 32
-
-typedef struct tag_ALSA_AudioDeviceDescription {
-    int index;          // in
-    int strLen;         // in
-    INT32* deviceID;    // out
-    int* maxSimultaneousLines; // out
-    char* name;         // out
-    char* vendor;       // out
-    char* description;  // out
-    char* version;      // out
-} ALSA_AudioDeviceDescription;
-
-
-
-int getAudioDeviceCount();
-int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc);
-
-// returns ALSA error code, or 0 if successful
-int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware);
-
-// returns 1 if successful
-// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
-int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
-                            int* sampleSizeInBytes, int* significantBits,
-                            int* isSigned, int* isBigEndian, int* enc);
-
-int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
-                            int sampleSizeInBytes, int significantBits,
-                            int isSigned, int isBigEndian, int enc);
-
-#endif // PLATFORM_API_BSDOS_ALSA_PCMUTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_Ports.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_Ports.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,724 +0,0 @@
-/*
- * 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.  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.
- */
-
-#define USE_ERROR
-//#define USE_TRACE
-
-#include "Ports.h"
-#include "PLATFORM_API_BsdOS_ALSA_CommonUtils.h"
-#include 
-
-#if USE_PORTS == TRUE
-
-#define MAX_ELEMS (300)
-#define MAX_CONTROLS (MAX_ELEMS * 4)
-
-#define CHANNELS_MONO (SND_MIXER_SCHN_LAST + 1)
-#define CHANNELS_STEREO (SND_MIXER_SCHN_LAST + 2)
-
-typedef struct {
-    snd_mixer_elem_t* elem;
-    INT32 portType; /* one of PORT_XXX_xx */
-    char* controlType; /* one of CONTROL_TYPE_xx */
-    /* Values: either SND_MIXER_SCHN_FRONT_xx, CHANNELS_MONO or CHANNELS_STEREO.
-       For SND_MIXER_SCHN_FRONT_xx, exactly this channel is set/retrieved directly.
-       For CHANNELS_MONO, ALSA channel SND_MIXER_SCHN_MONO is set/retrieved directly.
-       For CHANNELS_STEREO, ALSA channels SND_MIXER_SCHN_FRONT_LEFT and SND_MIXER_SCHN_FRONT_RIGHT
-       are set after a calculation that takes balance into account. Retrieved? Average of both
-       channels? (Using a cached value is not a good idea since the value in the HW may have been
-       altered.) */
-    INT32 channel;
-} PortControl;
-
-
-typedef struct tag_PortMixer {
-    snd_mixer_t* mixer_handle;
-    /* Number of array elements used in elems and types. */
-    int numElems;
-    snd_mixer_elem_t** elems;
-    /* Array of port types (PORT_SRC_UNKNOWN etc.). Indices are the same as in elems. */
-    INT32* types;
-    /* Number of array elements used in controls. */
-    int numControls;
-    PortControl* controls;
-} PortMixer;
-
-
-///// implemented functions of Ports.h
-
-INT32 PORT_GetPortMixerCount() {
-    INT32 mixerCount;
-    int card;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_ctl_card_info_t* info;
-
-    TRACE0("> PORT_GetPortMixerCount\n");
-
-    initAlsaSupport();
-
-    snd_ctl_card_info_malloc(&info);
-    card = -1;
-    mixerCount = 0;
-    if (snd_card_next(&card) >= 0) {
-        while (card >= 0) {
-            sprintf(devname, ALSA_HARDWARE_CARD, card);
-            TRACE1("PORT_GetPortMixerCount: Opening alsa device \"%s\"...\n", devname);
-            err = snd_ctl_open(&handle, devname, 0);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
-            } else {
-                mixerCount++;
-                snd_ctl_close(handle);
-            }
-            if (snd_card_next(&card) < 0) {
-                break;
-            }
-        }
-    }
-    snd_ctl_card_info_free(info);
-    TRACE0("< PORT_GetPortMixerCount\n");
-    return mixerCount;
-}
-
-
-INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
-    snd_ctl_t* handle;
-    snd_ctl_card_info_t* card_info;
-    char devname[16];
-    int err;
-    char buffer[100];
-
-    TRACE0("> PORT_GetPortMixerDescription\n");
-    snd_ctl_card_info_malloc(&card_info);
-
-    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
-    TRACE1("Opening alsa device \"%s\"...\n", devname);
-    err = snd_ctl_open(&handle, devname, 0);
-    if (err < 0) {
-        ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
-        return FALSE;
-    }
-    err = snd_ctl_card_info(handle, card_info);
-    if (err < 0) {
-        ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
-    }
-    strncpy(description->name, snd_ctl_card_info_get_id(card_info), PORT_STRING_LENGTH - 1);
-    sprintf(buffer, " [%s]", devname);
-    strncat(description->name, buffer, PORT_STRING_LENGTH - 1 - strlen(description->name));
-    strncpy(description->vendor, "ALSA (http://www.alsa-project.org)", PORT_STRING_LENGTH - 1);
-    strncpy(description->description, snd_ctl_card_info_get_name(card_info), PORT_STRING_LENGTH - 1);
-    strncat(description->description, ", ", PORT_STRING_LENGTH - 1 - strlen(description->description));
-    strncat(description->description, snd_ctl_card_info_get_mixername(card_info), PORT_STRING_LENGTH - 1 - strlen(description->description));
-    getALSAVersion(description->version, PORT_STRING_LENGTH - 1);
-
-    snd_ctl_close(handle);
-    snd_ctl_card_info_free(card_info);
-    TRACE0("< PORT_GetPortMixerDescription\n");
-    return TRUE;
-}
-
-
-void* PORT_Open(INT32 mixerIndex) {
-    char devname[16];
-    snd_mixer_t* mixer_handle;
-    int err;
-    PortMixer* handle;
-
-    TRACE0("> PORT_Open\n");
-    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
-    if ((err = snd_mixer_open(&mixer_handle, 0)) < 0) {
-        ERROR2("Mixer %s open error: %s", devname, snd_strerror(err));
-        return NULL;
-    }
-    if ((err = snd_mixer_attach(mixer_handle, devname)) < 0) {
-        ERROR2("Mixer attach %s error: %s", devname, snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    if ((err = snd_mixer_selem_register(mixer_handle, NULL, NULL)) < 0) {
-        ERROR1("Mixer register error: %s", snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    err = snd_mixer_load(mixer_handle);
-    if (err < 0) {
-        ERROR2("Mixer %s load error: %s", devname, snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    handle = (PortMixer*) calloc(1, sizeof(PortMixer));
-    if (handle == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    handle->numElems = 0;
-    handle->elems = (snd_mixer_elem_t**) calloc(MAX_ELEMS, sizeof(snd_mixer_elem_t*));
-    if (handle->elems == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle);
-        return NULL;
-    }
-    handle->types = (INT32*) calloc(MAX_ELEMS, sizeof(INT32));
-    if (handle->types == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle->elems);
-        free(handle);
-        return NULL;
-    }
-    handle->controls = (PortControl*) calloc(MAX_CONTROLS, sizeof(PortControl));
-    if (handle->controls == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle->elems);
-        free(handle->types);
-        free(handle);
-        return NULL;
-    }
-    handle->mixer_handle = mixer_handle;
-    // necessary to initialize data structures
-    PORT_GetPortCount(handle);
-    TRACE0("< PORT_Open\n");
-    return handle;
-}
-
-
-void PORT_Close(void* id) {
-    TRACE0("> PORT_Close\n");
-    if (id != NULL) {
-        PortMixer* handle = (PortMixer*) id;
-        if (handle->mixer_handle != NULL) {
-            snd_mixer_close(handle->mixer_handle);
-        }
-        if (handle->elems != NULL) {
-            free(handle->elems);
-        }
-        if (handle->types != NULL) {
-            free(handle->types);
-        }
-        if (handle->controls != NULL) {
-            free(handle->controls);
-        }
-        free(handle);
-    }
-    TRACE0("< PORT_Close\n");
-}
-
-
-
-INT32 PORT_GetPortCount(void* id) {
-    PortMixer* portMixer;
-    snd_mixer_elem_t *elem;
-
-    TRACE0("> PORT_GetPortCount\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portMixer->numElems == 0) {
-        for (elem = snd_mixer_first_elem(portMixer->mixer_handle); elem; elem = snd_mixer_elem_next(elem)) {
-            if (!snd_mixer_selem_is_active(elem))
-                continue;
-            TRACE2("Simple mixer control '%s',%i\n",
-                   snd_mixer_selem_get_name(elem),
-                   snd_mixer_selem_get_index(elem));
-            if (snd_mixer_selem_has_playback_volume(elem)) {
-                portMixer->elems[portMixer->numElems] = elem;
-                portMixer->types[portMixer->numElems] = PORT_DST_UNKNOWN;
-                portMixer->numElems++;
-            }
-            // to prevent buffer overflow
-            if (portMixer->numElems >= MAX_ELEMS) {
-                break;
-            }
-            /* If an element has both playback an capture volume, it is put into the arrays
-               twice. */
-            if (snd_mixer_selem_has_capture_volume(elem)) {
-                portMixer->elems[portMixer->numElems] = elem;
-                portMixer->types[portMixer->numElems] = PORT_SRC_UNKNOWN;
-                portMixer->numElems++;
-            }
-            // to prevent buffer overflow
-            if (portMixer->numElems >= MAX_ELEMS) {
-                break;
-            }
-        }
-    }
-    TRACE0("< PORT_GetPortCount\n");
-    return portMixer->numElems;
-}
-
-
-INT32 PORT_GetPortType(void* id, INT32 portIndex) {
-    PortMixer* portMixer;
-    INT32 type;
-    TRACE0("> PORT_GetPortType\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        // $$mp: Should become a descriptive error code (index out of bounds).
-        return -1;
-    }
-    type = portMixer->types[portIndex];
-    TRACE0("< PORT_GetPortType\n");
-    return type;
-}
-
-
-INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
-    PortMixer* portMixer;
-    const char* nam;
-
-    TRACE0("> PORT_GetPortName\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        // $$mp: Should become a descriptive error code (index out of bounds).
-        return -1;
-    }
-    nam = snd_mixer_selem_get_name(portMixer->elems[portIndex]);
-    strncpy(name, nam, len - 1);
-    name[len - 1] = 0;
-    TRACE0("< PORT_GetPortName\n");
-    return TRUE;
-}
-
-
-static int isPlaybackFunction(INT32 portType) {
-        return (portType & PORT_DST_MASK);
-}
-
-
-/* Sets portControl to a pointer to the next free array element in the PortControl (pointer)
-   array of the passed portMixer. Returns TRUE if successful. May return FALSE if there is no
-   free slot. In this case, portControl is not altered */
-static int getControlSlot(PortMixer* portMixer, PortControl** portControl) {
-    if (portMixer->numControls >= MAX_CONTROLS) {
-        return FALSE;
-    } else {
-        *portControl = &(portMixer->controls[portMixer->numControls]);
-        portMixer->numControls++;
-        return TRUE;
-    }
-}
-
-
-/* Protect against illegal min-max values, preventing divisions by zero.
- */
-inline static long getRange(long min, long max) {
-    if (max > min) {
-        return max - min;
-    } else {
-        return 1;
-    }
-}
-
-
-/* Idea: we may specify that if unit is an empty string, the values are linear and if unit is "dB",
-   the values are logarithmic.
-*/
-static void* createVolumeControl(PortControlCreator* creator,
-                                 PortControl* portControl,
-                                 snd_mixer_elem_t* elem, int isPlayback) {
-    void* control;
-    float precision;
-    long min, max;
-
-    if (isPlayback) {
-        snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
-    }
-    /* $$mp: The volume values retrieved with the ALSA API are strongly supposed to be logarithmic.
-       So the following calculation is wrong. However, there is no correct calculation, since
-       for equal-distant logarithmic steps, the precision expressed in linear varies over the
-       scale. */
-    precision = 1.0F / getRange(min, max);
-    control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_VOLUME, 0.0F, +1.0F, precision, "");
-    return control;
-}
-
-
-void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
-    PortMixer* portMixer;
-    snd_mixer_elem_t* elem;
-    void* control;
-    PortControl* portControl;
-    void* controls[10];
-    int numControls;
-    char* portName;
-    int isPlayback = 0;
-    int isMono;
-    int isStereo;
-    char* type;
-    snd_mixer_selem_channel_id_t channel;
-    memset(controls, 0, sizeof(controls));
-
-    TRACE0("> PORT_GetControls\n");
-    if (id == NULL) {
-        ERROR0("Invalid handle!");
-        // $$mp: an error code should be returned.
-        return;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        ERROR0("Port index out of range!");
-        // $$mp: an error code should be returned.
-        return;
-    }
-    numControls = 0;
-    elem = portMixer->elems[portIndex];
-    if (snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_capture_volume(elem)) {
-        /* Since we've split/duplicated elements with both playback and capture on the recovery
-           of elements, we now can assume that we handle only to deal with either playback or
-           capture. */
-        isPlayback = isPlaybackFunction(portMixer->types[portIndex]);
-        isMono = (isPlayback && snd_mixer_selem_is_playback_mono(elem)) ||
-            (!isPlayback && snd_mixer_selem_is_capture_mono(elem));
-        isStereo = (isPlayback &&
-                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
-                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) ||
-            (!isPlayback &&
-             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
-             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT));
-        // single volume control
-        if (isMono || isStereo) {
-            if (getControlSlot(portMixer, &portControl)) {
-                portControl->elem = elem;
-                portControl->portType = portMixer->types[portIndex];
-                portControl->controlType = CONTROL_TYPE_VOLUME;
-                if (isMono) {
-                    portControl->channel = CHANNELS_MONO;
-                } else {
-                    portControl->channel = CHANNELS_STEREO;
-                }
-                control = createVolumeControl(creator, portControl, elem, isPlayback);
-                if (control != NULL) {
-                    controls[numControls++] = control;
-                }
-            }
-        } else { // more than two channels, each channels has its own control.
-            for (channel = SND_MIXER_SCHN_FRONT_LEFT; channel <= SND_MIXER_SCHN_LAST; channel++) {
-                if (isPlayback && snd_mixer_selem_has_playback_channel(elem, channel) ||
-                    !isPlayback && snd_mixer_selem_has_capture_channel(elem, channel)) {
-                    if (getControlSlot(portMixer, &portControl)) {
-                        portControl->elem = elem;
-                        portControl->portType = portMixer->types[portIndex];
-                        portControl->controlType = CONTROL_TYPE_VOLUME;
-                        portControl->channel = channel;
-                        control = createVolumeControl(creator, portControl, elem, isPlayback);
-                        // We wrap in a compound control to provide the channel name.
-                        if (control != NULL) {
-                            /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
-                               declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
-                               to take a const char* parameter. */
-                            control = (creator->newCompoundControl)(creator, (char*) snd_mixer_selem_channel_name(channel), &control, 1);
-                        }
-                        if (control != NULL) {
-                            controls[numControls++] = control;
-                        }
-                    }
-                }
-            }
-        }
-        // BALANCE control
-        if (isStereo) {
-            if (getControlSlot(portMixer, &portControl)) {
-                portControl->elem = elem;
-                portControl->portType = portMixer->types[portIndex];
-                portControl->controlType = CONTROL_TYPE_BALANCE;
-                portControl->channel = CHANNELS_STEREO;
-                /* $$mp: The value for precision is chosen more or less arbitrarily. */
-                control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_BALANCE, -1.0F, 1.0F, 0.01F, "");
-                if (control != NULL) {
-                    controls[numControls++] = control;
-                }
-            }
-        }
-    }
-    if (snd_mixer_selem_has_playback_switch(elem) || snd_mixer_selem_has_capture_switch(elem)) {
-        if (getControlSlot(portMixer, &portControl)) {
-            type = isPlayback ? CONTROL_TYPE_MUTE : CONTROL_TYPE_SELECT;
-            portControl->elem = elem;
-            portControl->portType = portMixer->types[portIndex];
-            portControl->controlType = type;
-            control = (creator->newBooleanControl)(creator, portControl, type);
-            if (control != NULL) {
-                controls[numControls++] = control;
-            }
-        }
-    }
-    /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
-       declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
-       to take a const char* parameter. */
-    portName = (char*) snd_mixer_selem_get_name(elem);
-    control = (creator->newCompoundControl)(creator, portName, controls, numControls);
-    if (control != NULL) {
-        (creator->addControl)(creator, control);
-    }
-    TRACE0("< PORT_GetControls\n");
-}
-
-
-INT32 PORT_GetIntValue(void* controlIDV) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    int value = 0;
-    snd_mixer_selem_channel_id_t channel;
-
-    if (portControl != NULL) {
-        switch (portControl->channel) {
-        case CHANNELS_MONO:
-            channel = SND_MIXER_SCHN_MONO;
-            break;
-
-        case CHANNELS_STEREO:
-            channel = SND_MIXER_SCHN_FRONT_LEFT;
-            break;
-
-        default:
-            channel = portControl->channel;
-        }
-        if (portControl->controlType == CONTROL_TYPE_MUTE ||
-            portControl->controlType == CONTROL_TYPE_SELECT) {
-            if (isPlaybackFunction(portControl->portType)) {
-                snd_mixer_selem_get_playback_switch(portControl->elem, channel, &value);
-            } else {
-                snd_mixer_selem_get_capture_switch(portControl->elem, channel, &value);
-            }
-            if (portControl->controlType == CONTROL_TYPE_MUTE) {
-                value = ! value;
-            }
-        } else {
-            ERROR1("PORT_GetIntValue(): inappropriate control type: %s\n",
-                   portControl->controlType);
-        }
-    }
-    return (INT32) value;
-}
-
-
-void PORT_SetIntValue(void* controlIDV, INT32 value) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    snd_mixer_selem_channel_id_t channel;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_MUTE) {
-            value = ! value;
-        }
-        if (portControl->controlType == CONTROL_TYPE_MUTE ||
-            portControl->controlType == CONTROL_TYPE_SELECT) {
-            if (isPlaybackFunction(portControl->portType)) {
-                snd_mixer_selem_set_playback_switch_all(portControl->elem, value);
-            } else {
-                snd_mixer_selem_set_capture_switch_all(portControl->elem, value);
-            }
-        } else {
-            ERROR1("PORT_SetIntValue(): inappropriate control type: %s\n",
-                   portControl->controlType);
-        }
-    }
-}
-
-
-static float scaleVolumeValueToNormalized(long value, long min, long max) {
-    return (float) (value - min) / getRange(min, max);
-}
-
-
-static long scaleVolumeValueToHardware(float value, long min, long max) {
-    return (long)(value * getRange(min, max) + min);
-}
-
-
-float getRealVolume(PortControl* portControl,
-                    snd_mixer_selem_channel_id_t channel) {
-    float fValue;
-    long lValue = 0;
-    long min = 0;
-    long max = 0;
-
-    if (isPlaybackFunction(portControl->portType)) {
-        snd_mixer_selem_get_playback_volume_range(portControl->elem,
-                                                  &min, &max);
-        snd_mixer_selem_get_playback_volume(portControl->elem,
-                                            channel, &lValue);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(portControl->elem,
-                                                 &min, &max);
-        snd_mixer_selem_get_capture_volume(portControl->elem,
-                                           channel, &lValue);
-    }
-    fValue = scaleVolumeValueToNormalized(lValue, min, max);
-    return fValue;
-}
-
-
-void setRealVolume(PortControl* portControl,
-                   snd_mixer_selem_channel_id_t channel, float value) {
-    long lValue = 0;
-    long min = 0;
-    long max = 0;
-
-    if (isPlaybackFunction(portControl->portType)) {
-        snd_mixer_selem_get_playback_volume_range(portControl->elem,
-                                                  &min, &max);
-        lValue = scaleVolumeValueToHardware(value, min, max);
-        snd_mixer_selem_set_playback_volume(portControl->elem,
-                                            channel, lValue);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(portControl->elem,
-                                                 &min, &max);
-        lValue = scaleVolumeValueToHardware(value, min, max);
-        snd_mixer_selem_set_capture_volume(portControl->elem,
-                                           channel, lValue);
-    }
-}
-
-
-static float getFakeBalance(PortControl* portControl) {
-    float volL, volR;
-
-    // pan is the ratio of left and right
-    volL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
-    volR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
-    if (volL > volR) {
-        return -1.0f + (volR / volL);
-    }
-    else if (volR > volL) {
-        return 1.0f - (volL / volR);
-    }
-    return 0.0f;
-}
-
-
-static float getFakeVolume(PortControl* portControl) {
-    float valueL;
-    float valueR;
-    float value;
-
-    valueL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
-    valueR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
-    // volume is the greater value of both
-    value = valueL > valueR ? valueL : valueR ;
-    return value;
-}
-
-
-/*
- * sets the unsigned values for left and right volume according to
- * the given volume (0...1) and balance (-1..0..+1)
- */
-static void setFakeVolume(PortControl* portControl, float vol, float bal) {
-    float volumeLeft;
-    float volumeRight;
-
-    if (bal < 0.0f) {
-        volumeLeft = vol;
-        volumeRight = vol * (bal + 1.0f);
-    } else {
-        volumeLeft = vol * (1.0f - bal);
-        volumeRight = vol;
-    }
-    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT, volumeLeft);
-    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT, volumeRight);
-}
-
-
-float PORT_GetFloatValue(void* controlIDV) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    float value = 0.0F;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
-            switch (portControl->channel) {
-            case CHANNELS_MONO:
-                value = getRealVolume(portControl, SND_MIXER_SCHN_MONO);
-                break;
-
-            case CHANNELS_STEREO:
-                value = getFakeVolume(portControl);
-                break;
-
-            default:
-                value = getRealVolume(portControl, portControl->channel);
-            }
-        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
-            if (portControl->channel == CHANNELS_STEREO) {
-                value = getFakeBalance(portControl);
-            } else {
-                ERROR0("PORT_GetFloatValue(): Balance only allowed for stereo channels!\n");
-            }
-        } else {
-            ERROR1("PORT_GetFloatValue(): inappropriate control type: %s!\n",
-                   portControl->controlType);
-        }
-    }
-    return value;
-}
-
-
-void PORT_SetFloatValue(void* controlIDV, float value) {
-    PortControl* portControl = (PortControl*) controlIDV;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
-            switch (portControl->channel) {
-            case CHANNELS_MONO:
-                setRealVolume(portControl, SND_MIXER_SCHN_MONO, value);
-                break;
-
-            case CHANNELS_STEREO:
-                setFakeVolume(portControl, value, getFakeBalance(portControl));
-                break;
-
-            default:
-                setRealVolume(portControl, portControl->channel, value);
-            }
-        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
-            if (portControl->channel == CHANNELS_STEREO) {
-                setFakeVolume(portControl, getFakeVolume(portControl), value);
-            } else {
-                ERROR0("PORT_SetFloatValue(): Balance only allowed for stereo channels!\n");
-            }
-        } else {
-            ERROR1("PORT_SetFloatValue(): inappropriate control type: %s!\n",
-                   portControl->controlType);
-        }
-    }
-}
-
-
-#endif // USE_PORTS
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-//#define USE_ERROR
-//#define USE_TRACE
-
-#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
-
-static void alsaDebugOutput(const char *file, int line, const char *function, int err, const char *fmt, ...) {
-#ifdef USE_ERROR
-    va_list args;
-    va_start(args, fmt);
-    printf("%s:%d function %s: error %d: %s\n", file, line, function, err, snd_strerror(err));
-    if (strlen(fmt) > 0) {
-        vprintf(fmt, args);
-    }
-    va_end(args);
-#endif
-}
-
-static int alsa_inited = 0;
-static int alsa_enumerate_pcm_subdevices = FALSE; // default: no
-static int alsa_enumerate_midi_subdevices = FALSE; // default: no
-
-/*
- * Declare library specific JNI_Onload entry if static build
- */
-DEF_STATIC_JNI_OnLoad
-
-void initAlsaSupport() {
-    char* enumerate;
-    if (!alsa_inited) {
-        alsa_inited = TRUE;
-        snd_lib_error_set_handler(&alsaDebugOutput);
-
-        enumerate = getenv(ENV_ENUMERATE_PCM_SUBDEVICES);
-        if (enumerate != NULL && strlen(enumerate) > 0
-            && (enumerate[0] != 'f')   // false
-            && (enumerate[0] != 'F')   // False
-            && (enumerate[0] != 'n')   // no
-            && (enumerate[0] != 'N')) { // NO
-            alsa_enumerate_pcm_subdevices = TRUE;
-        }
-#ifdef ALSA_MIDI_ENUMERATE_SUBDEVICES
-        alsa_enumerate_midi_subdevices = TRUE;
-#endif
-    }
-}
-
-
-/* if true (non-zero), ALSA sub devices should be listed as separate devices
- */
-int needEnumerateSubdevices(int isMidi) {
-    initAlsaSupport();
-    return isMidi ? alsa_enumerate_midi_subdevices
-                  : alsa_enumerate_pcm_subdevices;
-}
-
-
-/*
- * deviceID contains packed card, device and subdevice numbers
- * each number takes 10 bits
- * "default" device has id == ALSA_DEFAULT_DEVICE_ID
- */
-UINT32 encodeDeviceID(int card, int device, int subdevice) {
-    return (((card & 0x3FF) << 20) | ((device & 0x3FF) << 10)
-           | (subdevice & 0x3FF)) + 1;
-}
-
-
-void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
-                    int isMidi) {
-    deviceID--;
-    *card = (deviceID >> 20) & 0x3FF;
-    *device = (deviceID >> 10) & 0x3FF;
-    if (needEnumerateSubdevices(isMidi)) {
-        *subdevice = deviceID  & 0x3FF;
-    } else {
-        *subdevice = -1; // ALSA will choose any subdevices
-    }
-}
-
-
-void getDeviceString(char* buffer, int card, int device, int subdevice,
-                     int usePlugHw, int isMidi) {
-    if (needEnumerateSubdevices(isMidi)) {
-        sprintf(buffer, "%s:%d,%d,%d",
-                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
-                        card, device, subdevice);
-    } else {
-        sprintf(buffer, "%s:%d,%d",
-                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
-                        card, device);
-    }
-}
-
-
-void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
-                                 int usePlugHw, int isMidi) {
-    int card, device, subdevice;
-
-    if (deviceID == ALSA_DEFAULT_DEVICE_ID) {
-        strcpy(buffer, ALSA_DEFAULT_DEVICE_NAME);
-    } else {
-        decodeDeviceID(deviceID, &card, &device, &subdevice, isMidi);
-        getDeviceString(buffer, card, device, subdevice, usePlugHw, isMidi);
-    }
-}
-
-
-static int hasGottenALSAVersion = FALSE;
-#define ALSAVersionString_LENGTH 200
-static char ALSAVersionString[ALSAVersionString_LENGTH];
-
-void getALSAVersion(char* buffer, int len) {
-    if (!hasGottenALSAVersion) {
-        // get alsa version from proc interface
-        FILE* file;
-        int curr, len, totalLen, inVersionString;
-        file = fopen(ALSA_VERSION_PROC_FILE, "r");
-        ALSAVersionString[0] = 0;
-        if (file) {
-            if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) {
-                // parse for version number
-                totalLen = strlen(ALSAVersionString);
-                inVersionString = FALSE;
-                len = 0;
-                curr = 0;
-                while (curr < totalLen) {
-                    if (!inVersionString) {
-                        // is this char the beginning of a version string ?
-                        if (ALSAVersionString[curr] >= '0'
-                            && ALSAVersionString[curr] <= '9') {
-                            inVersionString = TRUE;
-                        }
-                    }
-                    if (inVersionString) {
-                        // the version string ends with white space
-                        if (ALSAVersionString[curr] <= 32) {
-                            break;
-                        }
-                        if (curr != len) {
-                            // copy this char to the beginning of the string
-                            ALSAVersionString[len] = ALSAVersionString[curr];
-                        }
-                        len++;
-                    }
-                    curr++;
-                }
-                // remove trailing dots
-                while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
-                    len--;
-                }
-                // null terminate
-                ALSAVersionString[len] = 0;
-            }
-            fclose(file);
-            hasGottenALSAVersion = TRUE;
-        }
-    }
-    strncpy(buffer, ALSAVersionString, len);
-}
-
-
-/* end */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2003, 2007, 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 
-#include "Utilities.h"
-
-#ifndef PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
-#define PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
-
-#define ALSA_VERSION_PROC_FILE "/proc/asound/version"
-#define ALSA_HARDWARE "hw"
-#define ALSA_HARDWARE_CARD ALSA_HARDWARE":%d"
-#define ALSA_HARDWARE_DEVICE ALSA_HARDWARE_CARD",%d"
-#define ALSA_HARDWARE_SUBDEVICE ALSA_HARDWARE_DEVICE",%d"
-
-#define ALSA_PLUGHARDWARE "plughw"
-#define ALSA_DEFAULT_DEVICE_NAME "default"
-
-#define ALSA_DEFAULT_DEVICE_ID (0)
-
-#define ALSA_PCM     (0)
-#define ALSA_RAWMIDI (1)
-
-// for use in info objects
-#define ALSA_VENDOR "ALSA (http://www.alsa-project.org)"
-
-// Environment variable for inclusion of subdevices in device listing.
-// If this variable is unset or "no", then subdevices are ignored, and
-// it's ALSA's choice which one to use (enables hardware mixing)
-#define ENV_ENUMERATE_PCM_SUBDEVICES "ALSA_ENUMERATE_PCM_SUBDEVICES"
-
-// if defined, subdevices are listed.
-//#undef ALSA_MIDI_ENUMERATE_SUBDEVICES
-#define ALSA_MIDI_ENUMERATE_SUBDEVICES
-
-// must be called before any ALSA calls
-void initAlsaSupport();
-
-/* if true (non-zero), ALSA sub devices should be listed as separate devices
- */
-int needEnumerateSubdevices(int isMidi);
-
-
-/*
- * deviceID contains packed card, device and subdevice numbers
- * each number takes 10 bits
- * "default" device has id == ALSA_DEFAULT_DEVICE_ID
- */
-UINT32 encodeDeviceID(int card, int device, int subdevice);
-
-void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
-                    int isMidi);
-
-void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
-                                 int usePlugHw, int isMidi);
-
-void getALSAVersion(char* buffer, int len);
-
-
-#endif // PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,354 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, 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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#if USE_PLATFORM_MIDI_IN == TRUE
-
-
-#include 
-#include "PlatformMidi.h"
-#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
-#if defined(i586)
-#include 
-#endif
-
-/*
- * Helper methods
- */
-
-static inline UINT32 packMessage(int status, int data1, int data2) {
-    return ((status & 0xFF) | ((data1 & 0xFF) << 8) | ((data2 & 0xFF) << 16));
-}
-
-
-static void setShortMessage(MidiMessage* message,
-                            int status, int data1, int data2) {
-    message->type = SHORT_MESSAGE;
-    message->data.s.packedMsg = packMessage(status, data1, data2);
-}
-
-
-static void setRealtimeMessage(MidiMessage* message, int status) {
-    setShortMessage(message, status, 0, 0);
-}
-
-
-static void set14bitMessage(MidiMessage* message, int status, int value) {
-    TRACE3("14bit value: %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
-    value &= 0x3FFF;
-    TRACE3("14bit value (2): %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
-    setShortMessage(message, status,
-                    value & 0x7F,
-                    (value >> 7) & 0x7F);
-}
-
-
-/*
- * implementation of the platform-dependent
- * MIDI in functions declared in PlatformMidi.h
- */
-
-char* MIDI_IN_GetErrorStr(INT32 err) {
-    return (char*) getErrorStr(err);
-}
-
-INT32 MIDI_IN_GetNumDevices() {
-/* Workaround for 6842956: 32bit app on 64bit linux
- * gets assertion failure trying to open midiIn ports.
- * Untill the issue is fixed in ALSA
- * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807)
- * report no midi in devices in the configuration.
- */
-#if defined(i586)
-    static int jre32onlinux64 = -1;
-    if (jre32onlinux64 < 0) {
-        jre32onlinux64 = 0;
-        /* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN"
-         * environment variable.
-         */
-        if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) {
-            struct utsname u;
-            jre32onlinux64 = 0;
-            if (uname(&u) == 0) {
-                if (strstr(u.machine, "64") != NULL) {
-                    TRACE0("jre32 on linux64 detected - report no midiIn devices\n");
-                    jre32onlinux64 = 1;
-                }
-            }
-        }
-    }
-    if (jre32onlinux64) {
-        return 0;
-    }
-#endif
-
-    TRACE0("MIDI_IN_GetNumDevices()\n");
-
-    return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT);
-}
-
-
-INT32 MIDI_IN_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceName(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
-                                name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceVendor(deviceIndex, name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceDescription(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
-                                       name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceVersion(deviceIndex, name, nameLength);
-    return ret;
-}
-
-/*************************************************************************/
-
-INT32 MIDI_IN_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
-    INT32 ret;
-    TRACE0("> MIDI_IN_OpenDevice\n");
-    ret = openMidiDevice(SND_RAWMIDI_STREAM_INPUT, deviceIndex, handle);
-    TRACE1("< MIDI_IN_OpenDevice: returning %d\n", (int) ret);
-    return ret;
-}
-
-
-INT32 MIDI_IN_CloseDevice(MidiDeviceHandle* handle) {
-    INT32 ret;
-    TRACE0("> MIDI_IN_CloseDevice\n");
-    ret = closeMidiDevice(handle);
-    TRACE1("< MIDI_IN_CloseDevice: returning %d\n", (int) ret);
-    return ret;
-}
-
-
-INT32 MIDI_IN_StartDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_IN_StartDevice\n");
-    return MIDI_SUCCESS;
-}
-
-
-INT32 MIDI_IN_StopDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_IN_StopDevice\n");
-    return MIDI_SUCCESS;
-}
-
-
-INT64 MIDI_IN_GetTimeStamp(MidiDeviceHandle* handle) {
-    return getMidiTimestamp(handle);
-}
-
-
-/* read the next message from the queue */
-MidiMessage* MIDI_IN_GetMessage(MidiDeviceHandle* handle) {
-    snd_seq_event_t alsa_message;
-    MidiMessage* jdk_message;
-    int err;
-    char buffer[1];
-    int status;
-
-    TRACE0("> MIDI_IN_GetMessage\n");
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): handle is NULL\n");
-        return NULL;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): native handle is NULL\n");
-        return NULL;
-    }
-    if (!handle->platformData) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): platformData is NULL\n");
-        return NULL;
-    }
-
-    /* For MIDI In, the device is left in non blocking mode. So if there is
-       no data from the device, snd_rawmidi_read() returns with -11 (EAGAIN).
-       This results in jumping back to the Java layer. */
-    while (TRUE) {
-        TRACE0("before snd_rawmidi_read()\n");
-        err = snd_rawmidi_read((snd_rawmidi_t*) handle->deviceHandle, buffer, 1);
-        TRACE0("after snd_rawmidi_read()\n");
-        if (err != 1) {
-            ERROR2("< ERROR: MIDI_IN_GetMessage(): snd_rawmidi_read() returned %d : %s\n", err, snd_strerror(err));
-            return NULL;
-        }
-        // printf("received byte: %d\n", buffer[0]);
-        err = snd_midi_event_encode_byte((snd_midi_event_t*) handle->platformData,
-                                         (int) buffer[0],
-                                         &alsa_message);
-        if (err == 1) {
-            break;
-        } else if (err < 0) {
-            ERROR1("< ERROR: MIDI_IN_GetMessage(): snd_midi_event_encode_byte() returned %d\n", err);
-            return NULL;
-        }
-    }
-    jdk_message = (MidiMessage*) calloc(sizeof(MidiMessage), 1);
-    if (!jdk_message) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
-        return NULL;
-    }
-    // TODO: tra
-    switch (alsa_message.type) {
-    case SND_SEQ_EVENT_NOTEON:
-    case SND_SEQ_EVENT_NOTEOFF:
-    case SND_SEQ_EVENT_KEYPRESS:
-        status = (alsa_message.type == SND_SEQ_EVENT_KEYPRESS) ? 0xA0 :
-            (alsa_message.type == SND_SEQ_EVENT_NOTEON) ? 0x90 : 0x80;
-        status |= alsa_message.data.note.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.note.note,
-                        alsa_message.data.note.velocity);
-        break;
-
-    case SND_SEQ_EVENT_CONTROLLER:
-        status = 0xB0 | alsa_message.data.control.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.control.param,
-                        alsa_message.data.control.value);
-        break;
-
-    case SND_SEQ_EVENT_PGMCHANGE:
-    case SND_SEQ_EVENT_CHANPRESS:
-        status = (alsa_message.type == SND_SEQ_EVENT_PGMCHANGE) ? 0xC0 : 0xD0;
-        status |= alsa_message.data.control.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.control.value, 0);
-        break;
-
-    case SND_SEQ_EVENT_PITCHBEND:
-        status = 0xE0 | alsa_message.data.control.channel;
-        // $$mp 2003-09-23:
-        // possible hack to work around a bug in ALSA. Necessary for
-        // ALSA 0.9.2. May be fixed in newer versions of ALSA.
-        // alsa_message.data.control.value ^= 0x2000;
-        // TRACE1("pitchbend value: %d\n", alsa_message.data.control.value);
-        set14bitMessage(jdk_message, status,
-                        alsa_message.data.control.value);
-        break;
-
-        /* System exclusive messages */
-
-    case SND_SEQ_EVENT_SYSEX:
-        jdk_message->type = LONG_MESSAGE;
-        jdk_message->data.l.size = alsa_message.data.ext.len;
-        jdk_message->data.l.data = malloc(alsa_message.data.ext.len);
-        if (jdk_message->data.l.data == NULL) {
-            ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
-            free(jdk_message);
-            jdk_message = NULL;
-        } else {
-            memcpy(jdk_message->data.l.data, alsa_message.data.ext.ptr, alsa_message.data.ext.len);
-        }
-        break;
-
-        /* System common messages */
-
-    case SND_SEQ_EVENT_QFRAME:
-        setShortMessage(jdk_message, 0xF1,
-                        alsa_message.data.control.value & 0x7F, 0);
-        break;
-
-    case SND_SEQ_EVENT_SONGPOS:
-        set14bitMessage(jdk_message, 0xF2,
-                        alsa_message.data.control.value);
-        break;
-
-    case SND_SEQ_EVENT_SONGSEL:
-        setShortMessage(jdk_message, 0xF3,
-                        alsa_message.data.control.value & 0x7F, 0);
-        break;
-
-    case SND_SEQ_EVENT_TUNE_REQUEST:
-        setRealtimeMessage(jdk_message, 0xF6);
-        break;
-
-        /* System realtime messages */
-
-    case SND_SEQ_EVENT_CLOCK:
-        setRealtimeMessage(jdk_message, 0xF8);
-        break;
-
-    case SND_SEQ_EVENT_START:
-        setRealtimeMessage(jdk_message, 0xFA);
-        break;
-
-    case SND_SEQ_EVENT_CONTINUE:
-        setRealtimeMessage(jdk_message, 0xFB);
-        break;
-
-    case SND_SEQ_EVENT_STOP:
-        setRealtimeMessage(jdk_message, 0xFC);
-        break;
-
-    case SND_SEQ_EVENT_SENSING:
-        setRealtimeMessage(jdk_message, 0xFE);
-        break;
-
-    case SND_SEQ_EVENT_RESET:
-        setRealtimeMessage(jdk_message, 0xFF);
-        break;
-
-    default:
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): unhandled ALSA MIDI message type\n");
-        free(jdk_message);
-        jdk_message = NULL;
-
-    }
-
-    // set timestamp
-    if (jdk_message != NULL) {
-        jdk_message->timestamp = getMidiTimestamp(handle);
-    }
-    TRACE1("< MIDI_IN_GetMessage: returning %p\n", jdk_message);
-    return jdk_message;
-}
-
-
-void MIDI_IN_ReleaseMessage(MidiDeviceHandle* handle, MidiMessage* msg) {
-    if (!msg) {
-        ERROR0("< ERROR: MIDI_IN_ReleaseMessage(): message is NULL\n");
-        return;
-    }
-    if (msg->type == LONG_MESSAGE && msg->data.l.data) {
-        free(msg->data.l.data);
-    }
-    free(msg);
-}
-
-#endif /* USE_PLATFORM_MIDI_IN */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiOut.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiOut.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2003, 2007, 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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#if USE_PLATFORM_MIDI_OUT == TRUE
-
-#include 
-#include "PlatformMidi.h"
-#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
-
-
-
-static int CHANNEL_MESSAGE_LENGTH[] = {
-    -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 3, 3, 2, 2, 3 };
-/*                                 8x 9x Ax Bx Cx Dx Ex */
-
-static int SYSTEM_MESSAGE_LENGTH[] = {
-    -1, 2, 3, 2, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1 };
-/*  F0 F1 F2 F3  F4  F5 F6 F7 F8  F9 FA FB FC  FD FE FF */
-
-
-// the returned length includes the status byte.
-// for illegal messages, -1 is returned.
-static int getShortMessageLength(int status) {
-        int     dataLength = 0;
-        if (status < 0xF0) { // channel voice message
-                dataLength = CHANNEL_MESSAGE_LENGTH[(status >> 4) & 0xF];
-        } else {
-                dataLength = SYSTEM_MESSAGE_LENGTH[status & 0xF];
-        }
-        return dataLength;
-}
-
-
-/*
- * implementation of the platform-dependent
- * MIDI out functions declared in PlatformMidi.h
- */
-char* MIDI_OUT_GetErrorStr(INT32 err) {
-    return (char*) getErrorStr(err);
-}
-
-
-INT32 MIDI_OUT_GetNumDevices() {
-    TRACE0("MIDI_OUT_GetNumDevices()\n");
-    return getMidiDeviceCount(SND_RAWMIDI_STREAM_OUTPUT);
-}
-
-
-INT32 MIDI_OUT_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceName()\n");
-    return getMidiDeviceName(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
-                             name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceVendor()\n");
-    return getMidiDeviceVendor(deviceIndex, name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceDescription()\n");
-    return getMidiDeviceDescription(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
-                                    name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceVersion()\n");
-    return getMidiDeviceVersion(deviceIndex, name, nameLength);
-}
-
-
-/* *************************** MidiOutDevice implementation *************** */
-
-INT32 MIDI_OUT_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
-    TRACE1("MIDI_OUT_OpenDevice(): deviceIndex: %d\n", (int) deviceIndex);
-    return openMidiDevice(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex, handle);
-}
-
-
-INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_OUT_CloseDevice()\n");
-    return closeMidiDevice(handle);
-}
-
-
-INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle) {
-    return getMidiTimestamp(handle);
-}
-
-
-INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg,
-                                UINT32 timestamp) {
-    int err;
-    int status;
-    int data1;
-    int data2;
-    char buffer[3];
-
-    TRACE2("> MIDI_OUT_SendShortMessage() %x, time: %u\n", packedMsg, (unsigned int) timestamp);
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_OUT_SendShortMessage(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    status = (packedMsg & 0xFF);
-    buffer[0] = (char) status;
-    buffer[1]  = (char) ((packedMsg >> 8) & 0xFF);
-    buffer[2]  = (char) ((packedMsg >> 16) & 0xFF);
-    TRACE4("status: %d, data1: %d, data2: %d, length: %d\n", (int) buffer[0], (int) buffer[1], (int) buffer[2], getShortMessageLength(status));
-    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle, buffer, getShortMessageLength(status));
-    if (err < 0) {
-        ERROR1("  ERROR: MIDI_OUT_SendShortMessage(): snd_rawmidi_write() returned %d\n", err);
-    }
-
-    TRACE0("< MIDI_OUT_SendShortMessage()\n");
-    return err;
-}
-
-
-INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data,
-                               UINT32 size, UINT32 timestamp) {
-    int err;
-
-    TRACE2("> MIDI_OUT_SendLongMessage() size %u, time: %u\n", (unsigned int) size, (unsigned int) timestamp);
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!data) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): data is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle,
-                            data, size);
-    if (err < 0) {
-        ERROR1("  ERROR: MIDI_OUT_SendLongMessage(): snd_rawmidi_write() returned %d\n", err);
-    }
-
-    TRACE0("< MIDI_OUT_SendLongMessage()\n");
-    return err;
-}
-
-
-#endif /* USE_PLATFORM_MIDI_OUT */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,481 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
-#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
-#include 
-#include 
-
-static INT64 getTimeInMicroseconds() {
-    struct timeval tv;
-
-    gettimeofday(&tv, NULL);
-    return (tv.tv_sec * 1000000UL) + tv.tv_usec;
-}
-
-
-const char* getErrorStr(INT32 err) {
-        return snd_strerror((int) err);
-}
-
-
-
-// callback for iteration through devices
-// returns TRUE if iteration should continue
-typedef int (*DeviceIteratorPtr)(UINT32 deviceID,
-                                 snd_rawmidi_info_t* rawmidi_info,
-                                 snd_ctl_card_info_t* cardinfo,
-                                 void *userData);
-
-// for each ALSA device, call iterator. userData is passed to the iterator
-// returns total number of iterations
-static int iterateRawmidiDevices(snd_rawmidi_stream_t direction,
-                                 DeviceIteratorPtr iterator,
-                                 void* userData) {
-    int count = 0;
-    int subdeviceCount;
-    int card, dev, subDev;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_rawmidi_t *rawmidi;
-    snd_rawmidi_info_t *rawmidi_info;
-    snd_ctl_card_info_t *card_info, *defcardinfo = NULL;
-    UINT32 deviceID;
-    int doContinue = TRUE;
-
-    snd_rawmidi_info_malloc(&rawmidi_info);
-    snd_ctl_card_info_malloc(&card_info);
-
-    // 1st try "default" device
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_rawmidi_open(&rawmidi, NULL, ALSA_DEFAULT_DEVICE_NAME,
-                               SND_RAWMIDI_NONBLOCK);
-    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_open(NULL, &rawmidi, ALSA_DEFAULT_DEVICE_NAME,
-                               SND_RAWMIDI_NONBLOCK);
-    } else {
-        ERROR0("ERROR: iterateRawmidiDevices(): direction is neither"
-               " SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
-        err = MIDI_INVALID_ARGUMENT;
-    }
-    if (err < 0) {
-        ERROR1("ERROR: snd_rawmidi_open (\"default\"): %s\n",
-               snd_strerror(err));
-    } else {
-        err = snd_rawmidi_info(rawmidi, rawmidi_info);
-
-        snd_rawmidi_close(rawmidi);
-        if (err < 0) {
-            ERROR1("ERROR: snd_rawmidi_info (\"default\"): %s\n",
-                    snd_strerror(err));
-        } else {
-            // try to get card info
-            card = snd_rawmidi_info_get_card(rawmidi_info);
-            if (card >= 0) {
-                sprintf(devname, ALSA_HARDWARE_CARD, card);
-                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
-                    if (snd_ctl_card_info(handle, card_info) >= 0) {
-                        defcardinfo = card_info;
-                    }
-                    snd_ctl_close(handle);
-                }
-            }
-            // call calback function for the device
-            if (iterator != NULL) {
-                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, rawmidi_info,
-                                         defcardinfo, userData);
-            }
-            count++;
-        }
-    }
-
-    // iterate cards
-    card = -1;
-    TRACE0("testing for cards...\n");
-    if (snd_card_next(&card) >= 0) {
-        TRACE1("Found card %d\n", card);
-        while (doContinue && (card >= 0)) {
-            sprintf(devname, ALSA_HARDWARE_CARD, card);
-            TRACE1("Opening control for alsa rawmidi device \"%s\"...\n", devname);
-            err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
-            } else {
-                TRACE0("snd_ctl_open() SUCCESS\n");
-                err = snd_ctl_card_info(handle, card_info);
-                if (err < 0) {
-                    ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", card, snd_strerror(err));
-                } else {
-                    TRACE0("snd_ctl_card_info() SUCCESS\n");
-                    dev = -1;
-                    while (doContinue) {
-                        if (snd_ctl_rawmidi_next_device(handle, &dev) < 0) {
-                            ERROR0("snd_ctl_rawmidi_next_device\n");
-                        }
-                        TRACE0("snd_ctl_rawmidi_next_device() SUCCESS\n");
-                        if (dev < 0) {
-                            break;
-                        }
-                        snd_rawmidi_info_set_device(rawmidi_info, dev);
-                        snd_rawmidi_info_set_subdevice(rawmidi_info, 0);
-                        snd_rawmidi_info_set_stream(rawmidi_info, direction);
-                        err = snd_ctl_rawmidi_info(handle, rawmidi_info);
-                        TRACE0("after snd_ctl_rawmidi_info()\n");
-                        if (err < 0) {
-                            if (err != -ENOENT) {
-                                ERROR2("ERROR: snd_ctl_rawmidi_info, card=%d: %s", card, snd_strerror(err));
-                            }
-                        } else {
-                            TRACE0("snd_ctl_rawmidi_info() SUCCESS\n");
-                            subdeviceCount = needEnumerateSubdevices(ALSA_RAWMIDI)
-                                ? snd_rawmidi_info_get_subdevices_count(rawmidi_info)
-                                : 1;
-                            if (iterator!=NULL) {
-                                for (subDev = 0; subDev < subdeviceCount; subDev++) {
-                                    TRACE3("  Iterating %d,%d,%d\n", card, dev, subDev);
-                                    deviceID = encodeDeviceID(card, dev, subDev);
-                                    doContinue = (*iterator)(deviceID, rawmidi_info,
-                                                             card_info, userData);
-                                    count++;
-                                    TRACE0("returned from iterator\n");
-                                    if (!doContinue) {
-                                        break;
-                                    }
-                                }
-                            } else {
-                                count += subdeviceCount;
-                            }
-                        }
-                    } // of while(doContinue)
-                }
-                snd_ctl_close(handle);
-            }
-            if (snd_card_next(&card) < 0) {
-                break;
-            }
-        }
-    } else {
-        ERROR0("No cards found!\n");
-    }
-    snd_ctl_card_info_free(card_info);
-    snd_rawmidi_info_free(rawmidi_info);
-    return count;
-}
-
-
-
-int getMidiDeviceCount(snd_rawmidi_stream_t direction) {
-    int deviceCount;
-    TRACE0("> getMidiDeviceCount()\n");
-    initAlsaSupport();
-    deviceCount = iterateRawmidiDevices(direction, NULL, NULL);
-    TRACE0("< getMidiDeviceCount()\n");
-    return deviceCount;
-}
-
-
-
-/*
-  userData is assumed to be a pointer to ALSA_MIDIDeviceDescription.
-  ALSA_MIDIDeviceDescription->index has to be set to the index of the device
-  we want to get information of before this method is called the first time via
-  iterateRawmidiDevices(). On each call of this method,
-  ALSA_MIDIDeviceDescription->index is decremented. If it is equal to zero,
-  we have reached the desired device, so action is taken.
-  So after successful completion of iterateRawmidiDevices(),
-  ALSA_MIDIDeviceDescription->index is zero. If it isn't, this is an
-  indication of an error.
-*/
-static int deviceInfoIterator(UINT32 deviceID, snd_rawmidi_info_t *rawmidi_info,
-                              snd_ctl_card_info_t *cardinfo, void *userData) {
-    char buffer[300];
-    ALSA_MIDIDeviceDescription* desc = (ALSA_MIDIDeviceDescription*)userData;
-#ifdef ALSA_MIDI_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    TRACE0("deviceInfoIterator\n");
-    initAlsaSupport();
-    if (desc->index == 0) {
-        // we found the device with correct index
-        desc->deviceID = deviceID;
-
-        buffer[0]=' '; buffer[1]='[';
-        // buffer[300] is enough to store the actual device string w/o overrun
-        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_RAWMIDI);
-        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
-        strncpy(desc->name,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_id(cardinfo)
-                    : snd_rawmidi_info_get_id(rawmidi_info),
-                desc->strLen - strlen(buffer));
-        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
-        desc->description[0] = 0;
-        if (cardinfo != NULL) {
-            strncpy(desc->description, snd_ctl_card_info_get_name(cardinfo),
-                    desc->strLen);
-            strncat(desc->description, ", ",
-                    desc->strLen - strlen(desc->description));
-        }
-        strncat(desc->description, snd_rawmidi_info_get_id(rawmidi_info),
-                desc->strLen - strlen(desc->description));
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_rawmidi_info_get_name(rawmidi_info),
-                desc->strLen - strlen(desc->description));
-        TRACE2("Returning %s, %s\n", desc->name, desc->description);
-        return FALSE; // do not continue iteration
-    }
-    desc->index--;
-    return TRUE;
-}
-
-
-static int getMIDIDeviceDescriptionByIndex(snd_rawmidi_stream_t direction,
-                                           ALSA_MIDIDeviceDescription* desc) {
-    initAlsaSupport();
-    TRACE1(" getMIDIDeviceDescriptionByIndex (index = %d)\n", desc->index);
-    iterateRawmidiDevices(direction, &deviceInfoIterator, desc);
-    return (desc->index == 0) ? MIDI_SUCCESS : MIDI_INVALID_DEVICEID;
-}
-
-
-
-int initMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc, int index) {
-    int ret = MIDI_SUCCESS;
-    desc->index = index;
-    desc->strLen = 200;
-    desc->name = (char*) calloc(desc->strLen + 1, 1);
-    desc->description = (char*) calloc(desc->strLen + 1, 1);
-    if (! desc->name ||
-        ! desc->description) {
-        ret = MIDI_OUT_OF_MEMORY;
-    }
-    return ret;
-}
-
-
-void freeMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc) {
-    if (desc->name) {
-        free(desc->name);
-    }
-    if (desc->description) {
-        free(desc->description);
-    }
-}
-
-
-int getMidiDeviceName(snd_rawmidi_stream_t direction, int index, char *name,
-                      UINT32 nameLength) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    TRACE1("getMidiDeviceName: nameLength: %d\n", (int) nameLength);
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        TRACE0("getMidiDeviceName: initMIDIDeviceDescription() SUCCESS\n");
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
-            strncpy(name, desc.name, nameLength - 1);
-            name[nameLength - 1] = 0;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-int getMidiDeviceVendor(int index, char *name, UINT32 nameLength) {
-    strncpy(name, ALSA_VENDOR, nameLength - 1);
-    name[nameLength - 1] = 0;
-    return MIDI_SUCCESS;
-}
-
-
-int getMidiDeviceDescription(snd_rawmidi_stream_t direction,
-                             int index, char *name, UINT32 nameLength) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            strncpy(name, desc.description, nameLength - 1);
-            name[nameLength - 1] = 0;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-int getMidiDeviceVersion(int index, char *name, UINT32 nameLength) {
-    getALSAVersion(name, nameLength);
-    return MIDI_SUCCESS;
-}
-
-
-static int getMidiDeviceID(snd_rawmidi_stream_t direction, int index,
-                           UINT32* deviceID) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            // TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
-            *deviceID = desc.deviceID;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-/*
-  direction has to be either SND_RAWMIDI_STREAM_INPUT or
-  SND_RAWMIDI_STREAM_OUTPUT.
-  Returns 0 on success. Otherwise, MIDI_OUT_OF_MEMORY, MIDI_INVALID_ARGUMENT
-   or a negative ALSA error code is returned.
-*/
-INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
-                     MidiDeviceHandle** handle) {
-    snd_rawmidi_t* native_handle;
-    snd_midi_event_t* event_parser = NULL;
-    int err;
-    UINT32 deviceID = 0;
-    char devicename[100];
-#ifdef ALSA_MIDI_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    TRACE0("> openMidiDevice()\n");
-
-    (*handle) = (MidiDeviceHandle*) calloc(sizeof(MidiDeviceHandle), 1);
-    if (!(*handle)) {
-        ERROR0("ERROR: openDevice: out of memory\n");
-        return MIDI_OUT_OF_MEMORY;
-    }
-
-    // TODO: iterate to get dev ID from index
-    err = getMidiDeviceID(direction, deviceIndex, &deviceID);
-    TRACE1("  openMidiDevice(): deviceID: %d\n", (int) deviceID);
-    getDeviceStringFromDeviceID(devicename, deviceID,
-                                usePlugHw, ALSA_RAWMIDI);
-    TRACE1("  openMidiDevice(): deviceString: %s\n", devicename);
-
-    // finally open the device
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_rawmidi_open(&native_handle, NULL, devicename,
-                               SND_RAWMIDI_NONBLOCK);
-    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_open(NULL, &native_handle, devicename,
-                               SND_RAWMIDI_NONBLOCK);
-    } else {
-        ERROR0("  ERROR: openMidiDevice(): direction is neither SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
-        err = MIDI_INVALID_ARGUMENT;
-    }
-    if (err < 0) {
-        ERROR1("<  ERROR: openMidiDevice(): snd_rawmidi_open() returned %d\n", err);
-        free(*handle);
-        (*handle) = NULL;
-        return err;
-    }
-    /* We opened with non-blocking behaviour to not get hung if the device
-       is used by a different process. Writing, however, should
-       be blocking. So we change it here. */
-    if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_nonblock(native_handle, 0);
-        if (err < 0) {
-            ERROR1("  ERROR: openMidiDevice(): snd_rawmidi_nonblock() returned %d\n", err);
-            snd_rawmidi_close(native_handle);
-            free(*handle);
-            (*handle) = NULL;
-            return err;
-        }
-    }
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_midi_event_new(EVENT_PARSER_BUFSIZE, &event_parser);
-        if (err < 0) {
-            ERROR1("  ERROR: openMidiDevice(): snd_midi_event_new() returned %d\n", err);
-            snd_rawmidi_close(native_handle);
-            free(*handle);
-            (*handle) = NULL;
-            return err;
-        }
-    }
-
-    (*handle)->deviceHandle = (void*) native_handle;
-    (*handle)->startTime = getTimeInMicroseconds();
-    (*handle)->platformData = event_parser;
-    TRACE0("< openMidiDevice(): succeeded\n");
-    return err;
-}
-
-
-
-INT32 closeMidiDevice(MidiDeviceHandle* handle) {
-    int err;
-
-    TRACE0("> closeMidiDevice()\n");
-    if (!handle) {
-        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: closeMidiDevice(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    err = snd_rawmidi_close((snd_rawmidi_t*) handle->deviceHandle);
-    TRACE1("  snd_rawmidi_close() returns %d\n", err);
-    if (handle->platformData) {
-        snd_midi_event_free((snd_midi_event_t*) handle->platformData);
-    }
-    free(handle);
-    TRACE0("< closeMidiDevice: succeeded\n");
-    return err;
-}
-
-
-INT64 getMidiTimestamp(MidiDeviceHandle* handle) {
-    if (!handle) {
-        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    return getTimeInMicroseconds() - handle->startTime;
-}
-
-
-/* end */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.h
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.h	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2003, 2007, 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 
-#include "Utilities.h"
-#include "PlatformMidi.h"
-
-
-#ifndef PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
-#define PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
-
-#define EVENT_PARSER_BUFSIZE (2048)
-
-// if this is defined, use plughw: devices
-//#define ALSA_MIDI_USE_PLUGHW
-#undef ALSA_MIDI_USE_PLUGHW
-
-typedef struct tag_ALSA_MIDIDeviceDescription {
-        int index;          // in
-        int strLen;         // in
-        INT32 deviceID;    // out
-        char* name;         // out
-        char* description;  // out
-} ALSA_MIDIDeviceDescription;
-
-
-const char* getErrorStr(INT32 err);
-
-/* Returns the number of devices. */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceCount(snd_rawmidi_stream_t direction);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceName(snd_rawmidi_stream_t direction, int index,
-                      char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-int getMidiDeviceVendor(int index, char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceDescription(snd_rawmidi_stream_t direction, int index,
-                             char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-int getMidiDeviceVersion(int index, char *name, UINT32 nameLength);
-
-// returns 0 on success, otherwise MIDI_OUT_OF_MEMORY or ALSA error code
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
-                     MidiDeviceHandle** handle);
-
-// returns 0 on success, otherwise a (negative) ALSA error code
-INT32 closeMidiDevice(MidiDeviceHandle* handle);
-
-INT64 getMidiTimestamp(MidiDeviceHandle* handle);
-
-#endif // PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,941 +0,0 @@
-/*
- * Copyright (c) 2002, 2011, 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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_LinuxOS_ALSA_PCMUtils.h"
-#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
-#include "DirectAudio.h"
-
-#if USE_DAUDIO == TRUE
-
-// GetPosition method 1: based on how many bytes are passed to the kernel driver
-//                       + does not need much processor resources
-//                       - not very exact, "jumps"
-// GetPosition method 2: ask kernel about actual position of playback.
-//                       - very exact
-//                       - switch to kernel layer for each call
-// GetPosition method 3: use snd_pcm_avail() call - not yet in official ALSA
-// quick tests on a Pentium 200MMX showed max. 1.5% processor usage
-// for playing back a CD-quality file and printing 20x per second a line
-// on the console with the current time. So I guess performance is not such a
-// factor here.
-//#define GET_POSITION_METHOD1
-#define GET_POSITION_METHOD2
-
-
-// The default time for a period in microseconds.
-// For very small buffers, only 2 periods are used.
-#define DEFAULT_PERIOD_TIME 20000 /* 20ms */
-
-///// implemented functions of DirectAudio.h
-
-INT32 DAUDIO_GetDirectAudioDeviceCount() {
-    return (INT32) getAudioDeviceCount();
-}
-
-
-INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex, DirectAudioDeviceDescription* description) {
-    ALSA_AudioDeviceDescription adesc;
-
-    adesc.index = (int) mixerIndex;
-    adesc.strLen = DAUDIO_STRING_LENGTH;
-
-    adesc.maxSimultaneousLines = (int*) (&(description->maxSimulLines));
-    adesc.deviceID = &(description->deviceID);
-    adesc.name = description->name;
-    adesc.vendor = description->vendor;
-    adesc.description = description->description;
-    adesc.version = description->version;
-
-    return getAudioDeviceDescriptionByIndex(&adesc);
-}
-
-#define MAX_BIT_INDEX 6
-// returns
-// 6: for anything above 24-bit
-// 5: for 4 bytes sample size, 24-bit
-// 4: for 3 bytes sample size, 24-bit
-// 3: for 3 bytes sample size, 20-bit
-// 2: for 2 bytes sample size, 16-bit
-// 1: for 1 byte sample size, 8-bit
-// 0: for anything else
-int getBitIndex(int sampleSizeInBytes, int significantBits) {
-    if (significantBits > 24) return 6;
-    if (sampleSizeInBytes == 4 && significantBits == 24) return 5;
-    if (sampleSizeInBytes == 3) {
-        if (significantBits == 24) return 4;
-        if (significantBits == 20) return 3;
-    }
-    if (sampleSizeInBytes == 2 && significantBits == 16) return 2;
-    if (sampleSizeInBytes == 1 && significantBits == 8) return 1;
-    return 0;
-}
-
-int getSampleSizeInBytes(int bitIndex, int sampleSizeInBytes) {
-    switch(bitIndex) {
-    case 1: return 1;
-    case 2: return 2;
-    case 3: /* fall through */
-    case 4: return 3;
-    case 5: return 4;
-    }
-    return sampleSizeInBytes;
-}
-
-int getSignificantBits(int bitIndex, int significantBits) {
-    switch(bitIndex) {
-    case 1: return 8;
-    case 2: return 16;
-    case 3: return 20;
-    case 4: /* fall through */
-    case 5: return 24;
-    }
-    return significantBits;
-}
-
-void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
-    snd_pcm_t* handle;
-    snd_pcm_format_mask_t* formatMask;
-    snd_pcm_format_t format;
-    snd_pcm_hw_params_t* hwParams;
-    int handledBits[MAX_BIT_INDEX+1];
-
-    int ret;
-    int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc;
-    int origSampleSizeInBytes, origSignificantBits;
-    unsigned int channels, minChannels, maxChannels;
-    int rate, bitIndex;
-
-    for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE;
-    if (openPCMfromDeviceID(deviceID, &handle, isSource, TRUE /*query hardware*/) < 0) {
-        return;
-    }
-    ret = snd_pcm_format_mask_malloc(&formatMask);
-    if (ret != 0) {
-        ERROR1("snd_pcm_format_mask_malloc returned error %d\n", ret);
-    } else {
-        ret = snd_pcm_hw_params_malloc(&hwParams);
-        if (ret != 0) {
-            ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
-        } else {
-            ret = snd_pcm_hw_params_any(handle, hwParams);
-            /* snd_pcm_hw_params_any can return a positive value on success too */
-            if (ret < 0) {
-                 ERROR1("snd_pcm_hw_params_any returned error %d\n", ret);
-            } else {
-                /* for the logic following this code, set ret to 0 to indicate success */
-                ret = 0;
-            }
-        }
-        snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
-        if (ret == 0) {
-            ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels);
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_get_channels_min returned error %d\n", ret);
-            }
-        }
-        if (ret == 0) {
-            ret = snd_pcm_hw_params_get_channels_max(hwParams, &maxChannels);
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret);
-            }
-        }
-
-        // since we queried the hw: device, for many soundcards, it will only
-        // report the maximum number of channels (which is the only way to talk
-        // to the hw: device). Since we will, however, open the plughw: device
-        // when opening the Source/TargetDataLine, we can safely assume that
-        // also the channels 1..maxChannels are available.
-#ifdef ALSA_PCM_USE_PLUGHW
-        minChannels = 1;
-#endif
-        if (ret == 0) {
-            // plughw: supports any sample rate
-            rate = -1;
-            for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
-                if (snd_pcm_format_mask_test(formatMask, format)) {
-                    // format exists
-                    if (getFormatFromAlsaFormat(format, &origSampleSizeInBytes,
-                                                &origSignificantBits,
-                                                &isSigned, &isBigEndian, &enc)) {
-                        // now if we use plughw:, we can use any bit size below the
-                        // natively supported ones. Some ALSA drivers only support the maximum
-                        // bit size, so we add any sample rates below the reported one.
-                        // E.g. this iteration reports support for 16-bit.
-                        // getBitIndex will return 2, so it will add entries for
-                        // 16-bit (bitIndex=2) and in the next do-while loop iteration,
-                        // it will decrease bitIndex and will therefore add 8-bit support.
-                        bitIndex = getBitIndex(origSampleSizeInBytes, origSignificantBits);
-                        do {
-                            if (bitIndex == 0
-                                || bitIndex == MAX_BIT_INDEX
-                                || !handledBits[bitIndex]) {
-                                handledBits[bitIndex] = TRUE;
-                                sampleSizeInBytes = getSampleSizeInBytes(bitIndex, origSampleSizeInBytes);
-                                significantBits = getSignificantBits(bitIndex, origSignificantBits);
-                                if (maxChannels - minChannels > MAXIMUM_LISTED_CHANNELS) {
-                                    // avoid too many channels explicitly listed
-                                    // just add -1, min, and max
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          -1, -1, rate,
-                                                          enc, isSigned, isBigEndian);
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          sampleSizeInBytes * minChannels,
-                                                          minChannels, rate,
-                                                          enc, isSigned, isBigEndian);
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          sampleSizeInBytes * maxChannels,
-                                                          maxChannels, rate,
-                                                          enc, isSigned, isBigEndian);
-                                } else {
-                                    for (channels = minChannels; channels <= maxChannels; channels++) {
-                                        DAUDIO_AddAudioFormat(creator, significantBits,
-                                                              sampleSizeInBytes * channels,
-                                                              channels, rate,
-                                                              enc, isSigned, isBigEndian);
-                                    }
-                                }
-                            }
-#ifndef ALSA_PCM_USE_PLUGHW
-                            // without plugin, do not add fake formats
-                            break;
-#endif
-                        } while (--bitIndex > 0);
-                    } else {
-                        TRACE1("could not get format from alsa for format %d\n", format);
-                    }
-                } else {
-                    //TRACE1("Format %d not supported\n", format);
-                }
-            } // for loop
-            snd_pcm_hw_params_free(hwParams);
-        }
-        snd_pcm_format_mask_free(formatMask);
-    }
-    snd_pcm_close(handle);
-}
-
-/** Workaround for cr 7033899, 7030629:
- * dmix plugin doesn't like flush (snd_pcm_drop) when the buffer is empty
- * (just opened, underruned or already flushed).
- * Sometimes it causes PCM falls to -EBADFD error,
- * sometimes causes bufferSize change.
- * To prevent unnecessary flushes AlsaPcmInfo::isRunning & isFlushed are used.
- */
-/* ******* ALSA PCM INFO ******************** */
-typedef struct tag_AlsaPcmInfo {
-    snd_pcm_t* handle;
-    snd_pcm_hw_params_t* hwParams;
-    snd_pcm_sw_params_t* swParams;
-    int bufferSizeInBytes;
-    int frameSize; // storage size in Bytes
-    unsigned int periods;
-    snd_pcm_uframes_t periodSize;
-    short int isRunning;    // see comment above
-    short int isFlushed;    // see comment above
-#ifdef GET_POSITION_METHOD2
-    // to be used exclusively by getBytePosition!
-    snd_pcm_status_t* positionStatus;
-#endif
-} AlsaPcmInfo;
-
-
-int setStartThresholdNoCommit(AlsaPcmInfo* info, int useThreshold) {
-    int ret;
-    int threshold;
-
-    if (useThreshold) {
-        // start device whenever anything is written to the buffer
-        threshold = 1;
-    } else {
-        // never start the device automatically
-        threshold = 2000000000; /* near UINT_MAX */
-    }
-    ret = snd_pcm_sw_params_set_start_threshold(info->handle, info->swParams, threshold);
-    if (ret < 0) {
-        ERROR1("Unable to set start threshold mode: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-int setStartThreshold(AlsaPcmInfo* info, int useThreshold) {
-    int ret = 0;
-
-    if (!setStartThresholdNoCommit(info, useThreshold)) {
-        ret = -1;
-    }
-    if (ret == 0) {
-        // commit it
-        ret = snd_pcm_sw_params(info->handle, info->swParams);
-        if (ret < 0) {
-            ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
-        }
-    }
-    return (ret == 0)?TRUE:FALSE;
-}
-
-
-// returns TRUE if successful
-int setHWParams(AlsaPcmInfo* info,
-                float sampleRate,
-                int channels,
-                int bufferSizeInFrames,
-                snd_pcm_format_t format) {
-    unsigned int rrate, periodTime, periods;
-    int ret, dir;
-    snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames;
-
-    /* choose all parameters */
-    ret = snd_pcm_hw_params_any(info->handle, info->hwParams);
-    if (ret < 0) {
-        ERROR1("Broken configuration: no configurations available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the interleaved read/write format */
-    ret = snd_pcm_hw_params_set_access(info->handle, info->hwParams, SND_PCM_ACCESS_RW_INTERLEAVED);
-    if (ret < 0) {
-        ERROR1("SND_PCM_ACCESS_RW_INTERLEAVED access type not available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the sample format */
-    ret = snd_pcm_hw_params_set_format(info->handle, info->hwParams, format);
-    if (ret < 0) {
-        ERROR1("Sample format not available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the count of channels */
-    ret = snd_pcm_hw_params_set_channels(info->handle, info->hwParams, channels);
-    if (ret < 0) {
-        ERROR2("Channels count (%d) not available: %s\n", channels, snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the stream rate */
-    rrate = (int) (sampleRate + 0.5f);
-    dir = 0;
-    ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir);
-    if (ret < 0) {
-        ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret));
-        return FALSE;
-    }
-    if ((rrate-sampleRate > 2) || (rrate-sampleRate < - 2)) {
-        ERROR2("Rate doesn't match (requested %2.2fHz, got %dHz)\n", sampleRate, rrate);
-        return FALSE;
-    }
-    /* set the buffer time */
-    ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames);
-    if (ret < 0) {
-        ERROR2("Unable to set buffer size to %d frames: %s\n",
-               (int) alsaBufferSizeInFrames, snd_strerror(ret));
-        return FALSE;
-    }
-    bufferSizeInFrames = (int) alsaBufferSizeInFrames;
-    /* set the period time */
-    if (bufferSizeInFrames > 1024) {
-        dir = 0;
-        periodTime = DEFAULT_PERIOD_TIME;
-        ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir);
-        if (ret < 0) {
-            ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret));
-            return FALSE;
-        }
-    } else {
-        /* set the period count for very small buffer sizes to 2 */
-        dir = 0;
-        periods = 2;
-        ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir);
-        if (ret < 0) {
-            ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret));
-            return FALSE;
-        }
-    }
-    /* write the parameters to device */
-    ret = snd_pcm_hw_params(info->handle, info->hwParams);
-    if (ret < 0) {
-        ERROR1("Unable to set hw params: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-// returns 1 if successful
-int setSWParams(AlsaPcmInfo* info) {
-    int ret;
-
-    /* get the current swparams */
-    ret = snd_pcm_sw_params_current(info->handle, info->swParams);
-    if (ret < 0) {
-        ERROR1("Unable to determine current swparams: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* never start the transfer automatically */
-    if (!setStartThresholdNoCommit(info, FALSE /* don't use threshold */)) {
-        return FALSE;
-    }
-
-    /* allow the transfer when at least period_size samples can be processed */
-    ret = snd_pcm_sw_params_set_avail_min(info->handle, info->swParams, info->periodSize);
-    if (ret < 0) {
-        ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* write the parameters to the playback device */
-    ret = snd_pcm_sw_params(info->handle, info->swParams);
-    if (ret < 0) {
-        ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-static snd_output_t* ALSA_OUTPUT = NULL;
-
-void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
-                  int encoding, float sampleRate, int sampleSizeInBits,
-                  int frameSize, int channels,
-                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
-    snd_pcm_format_mask_t* formatMask;
-    snd_pcm_format_t format;
-    int dir;
-    int ret = 0;
-    AlsaPcmInfo* info = NULL;
-    /* snd_pcm_uframes_t is 64 bit on 64-bit systems */
-    snd_pcm_uframes_t alsaBufferSizeInFrames = 0;
-
-
-    TRACE0("> DAUDIO_Open\n");
-#ifdef USE_TRACE
-    // for using ALSA debug dump methods
-    if (ALSA_OUTPUT == NULL) {
-        snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
-    }
-#endif
-    if (channels <= 0) {
-        ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
-        return NULL;
-    }
-    info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
-    if (!info) {
-        ERROR0("Out of memory\n");
-        return NULL;
-    }
-    memset(info, 0, sizeof(AlsaPcmInfo));
-    // initial values are: stopped, flushed
-    info->isRunning = 0;
-    info->isFlushed = 1;
-
-    ret = openPCMfromDeviceID(deviceID, &(info->handle), isSource, FALSE /* do open device*/);
-    if (ret == 0) {
-        // set to blocking mode
-        snd_pcm_nonblock(info->handle, 0);
-        ret = snd_pcm_hw_params_malloc(&(info->hwParams));
-        if (ret != 0) {
-            ERROR1("  snd_pcm_hw_params_malloc returned error %d\n", ret);
-        } else {
-            ret = -1;
-            if (getAlsaFormatFromFormat(&format, frameSize / channels, sampleSizeInBits,
-                                        isSigned, isBigEndian, encoding)) {
-                if (setHWParams(info,
-                                sampleRate,
-                                channels,
-                                bufferSizeInBytes / frameSize,
-                                format)) {
-                    info->frameSize = frameSize;
-                    ret = snd_pcm_hw_params_get_period_size(info->hwParams, &info->periodSize, &dir);
-                    if (ret < 0) {
-                        ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret));
-                    }
-                    snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir);
-                    snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames);
-                    info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize;
-                    TRACE3("  DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n",
-                           (int) info->periodSize, info->periods, info->bufferSizeInBytes);
-                }
-            }
-        }
-        if (ret == 0) {
-            // set software parameters
-            ret = snd_pcm_sw_params_malloc(&(info->swParams));
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
-            } else {
-                if (!setSWParams(info)) {
-                    ret = -1;
-                }
-            }
-        }
-        if (ret == 0) {
-            // prepare device
-            ret = snd_pcm_prepare(info->handle);
-            if (ret < 0) {
-                ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
-            }
-        }
-
-#ifdef GET_POSITION_METHOD2
-        if (ret == 0) {
-            ret = snd_pcm_status_malloc(&(info->positionStatus));
-            if (ret != 0) {
-                ERROR1("ERROR in snd_pcm_status_malloc: %s\n", snd_strerror(ret));
-            }
-        }
-#endif
-    }
-    if (ret != 0) {
-        DAUDIO_Close((void*) info, isSource);
-        info = NULL;
-    } else {
-        // set to non-blocking mode
-        snd_pcm_nonblock(info->handle, 1);
-        TRACE1("< DAUDIO_Open: Opened device successfully. Handle=%p\n",
-               (void*) info->handle);
-    }
-    return (void*) info;
-}
-
-#ifdef USE_TRACE
-void printState(snd_pcm_state_t state) {
-    if (state == SND_PCM_STATE_OPEN) {
-        TRACE0("State: SND_PCM_STATE_OPEN\n");
-    }
-    else if (state == SND_PCM_STATE_SETUP) {
-        TRACE0("State: SND_PCM_STATE_SETUP\n");
-    }
-    else if (state == SND_PCM_STATE_PREPARED) {
-        TRACE0("State: SND_PCM_STATE_PREPARED\n");
-    }
-    else if (state == SND_PCM_STATE_RUNNING) {
-        TRACE0("State: SND_PCM_STATE_RUNNING\n");
-    }
-    else if (state == SND_PCM_STATE_XRUN) {
-        TRACE0("State: SND_PCM_STATE_XRUN\n");
-    }
-    else if (state == SND_PCM_STATE_DRAINING) {
-        TRACE0("State: SND_PCM_STATE_DRAINING\n");
-    }
-    else if (state == SND_PCM_STATE_PAUSED) {
-        TRACE0("State: SND_PCM_STATE_PAUSED\n");
-    }
-    else if (state == SND_PCM_STATE_SUSPENDED) {
-        TRACE0("State: SND_PCM_STATE_SUSPENDED\n");
-    }
-}
-#endif
-
-int DAUDIO_Start(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-    snd_pcm_state_t state;
-
-    TRACE0("> DAUDIO_Start\n");
-    // set to blocking mode
-    snd_pcm_nonblock(info->handle, 0);
-    // set start mode so that it always starts as soon as data is there
-    setStartThreshold(info, TRUE /* use threshold */);
-    state = snd_pcm_state(info->handle);
-    if (state == SND_PCM_STATE_PAUSED) {
-        // in case it was stopped previously
-        TRACE0("  Un-pausing...\n");
-        ret = snd_pcm_pause(info->handle, FALSE);
-        if (ret != 0) {
-            ERROR2("  NOTE: error in snd_pcm_pause:%d: %s\n", ret, snd_strerror(ret));
-        }
-    }
-    if (state == SND_PCM_STATE_SUSPENDED) {
-        TRACE0("  Resuming...\n");
-        ret = snd_pcm_resume(info->handle);
-        if (ret < 0) {
-            if ((ret != -EAGAIN) && (ret != -ENOSYS)) {
-                ERROR2("  ERROR: error in snd_pcm_resume:%d: %s\n", ret, snd_strerror(ret));
-            }
-        }
-    }
-    if (state == SND_PCM_STATE_SETUP) {
-        TRACE0("need to call prepare again...\n");
-        // prepare device
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
-        }
-    }
-    // in case there is still data in the buffers
-    ret = snd_pcm_start(info->handle);
-    if (ret != 0) {
-        if (ret != -EPIPE) {
-            ERROR2("  NOTE: error in snd_pcm_start: %d: %s\n", ret, snd_strerror(ret));
-        }
-    }
-    // set to non-blocking mode
-    ret = snd_pcm_nonblock(info->handle, 1);
-    if (ret != 0) {
-        ERROR1("  ERROR in snd_pcm_nonblock: %s\n", snd_strerror(ret));
-    }
-    state = snd_pcm_state(info->handle);
-#ifdef USE_TRACE
-    printState(state);
-#endif
-    ret = (state == SND_PCM_STATE_PREPARED)
-        || (state == SND_PCM_STATE_RUNNING)
-        || (state == SND_PCM_STATE_XRUN)
-        || (state == SND_PCM_STATE_SUSPENDED);
-    if (ret) {
-        info->isRunning = 1;
-        // source line should keep isFlushed value until Write() is called;
-        // for target data line reset it right now.
-        if (!isSource) {
-            info->isFlushed = 0;
-        }
-    }
-    TRACE1("< DAUDIO_Start %s\n", ret?"success":"error");
-    return ret?TRUE:FALSE;
-}
-
-int DAUDIO_Stop(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-
-    TRACE0("> DAUDIO_Stop\n");
-    // set to blocking mode
-    snd_pcm_nonblock(info->handle, 0);
-    setStartThreshold(info, FALSE /* don't use threshold */); // device will not start after buffer xrun
-    ret = snd_pcm_pause(info->handle, 1);
-    // set to non-blocking mode
-    snd_pcm_nonblock(info->handle, 1);
-    if (ret != 0) {
-        ERROR1("ERROR in snd_pcm_pause: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    info->isRunning = 0;
-    TRACE0("< DAUDIO_Stop success\n");
-    return TRUE;
-}
-
-void DAUDIO_Close(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-
-    TRACE0("DAUDIO_Close\n");
-    if (info != NULL) {
-        if (info->handle != NULL) {
-            snd_pcm_close(info->handle);
-        }
-        if (info->hwParams) {
-            snd_pcm_hw_params_free(info->hwParams);
-        }
-        if (info->swParams) {
-            snd_pcm_sw_params_free(info->swParams);
-        }
-#ifdef GET_POSITION_METHOD2
-        if (info->positionStatus) {
-            snd_pcm_status_free(info->positionStatus);
-        }
-#endif
-        free(info);
-    }
-}
-
-/*
- * Underrun and suspend recovery
- * returns
- * 0:  exit native and return 0
- * 1:  try again to write/read
- * -1: error - exit native with return value -1
- */
-int xrun_recovery(AlsaPcmInfo* info, int err) {
-    int ret;
-
-    if (err == -EPIPE) {    /* underrun / overflow */
-        TRACE0("xrun_recovery: underrun/overflow.\n");
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
-            return -1;
-        }
-        return 1;
-    } else if (err == -ESTRPIPE) {
-        TRACE0("xrun_recovery: suspended.\n");
-        ret = snd_pcm_resume(info->handle);
-        if (ret < 0) {
-            if (ret == -EAGAIN) {
-                return 0; /* wait until the suspend flag is released */
-            }
-            return -1;
-        }
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
-            return -1;
-        }
-        return 1;
-    } else if (err == -EAGAIN) {
-        TRACE0("xrun_recovery: EAGAIN try again flag.\n");
-        return 0;
-    }
-
-    TRACE2("xrun_recovery: unexpected error %d: %s\n", err, snd_strerror(err));
-    return -1;
-}
-
-// returns -1 on error
-int DAUDIO_Write(void* id, char* data, int byteSize) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret, count;
-    snd_pcm_sframes_t frameSize, writtenFrames;
-
-    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
-
-    /* sanity */
-    if (byteSize <= 0 || info->frameSize <= 0) {
-        ERROR2(" DAUDIO_Write: byteSize=%d, frameSize=%d!\n",
-               (int) byteSize, (int) info->frameSize);
-        TRACE0("< DAUDIO_Write returning -1\n");
-        return -1;
-    }
-
-    count = 2; // maximum number of trials to recover from underrun
-    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
-    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
-    do {
-        writtenFrames = snd_pcm_writei(info->handle, (const void*) data, (snd_pcm_uframes_t) frameSize);
-
-        if (writtenFrames < 0) {
-            ret = xrun_recovery(info, (int) writtenFrames);
-            if (ret <= 0) {
-                TRACE1("DAUDIO_Write: xrun recovery returned %d -> return.\n", ret);
-                return ret;
-            }
-            if (count-- <= 0) {
-                ERROR0("DAUDIO_Write: too many attempts to recover from xrun/suspend\n");
-                return -1;
-            }
-        } else {
-            break;
-        }
-    } while (TRUE);
-    //ret =  snd_pcm_frames_to_bytes(info->handle, writtenFrames);
-
-    if (writtenFrames > 0) {
-        // reset "flushed" flag
-        info->isFlushed = 0;
-    }
-
-    ret =  (int) (writtenFrames * info->frameSize);
-    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
-    return ret;
-}
-
-// returns -1 on error
-int DAUDIO_Read(void* id, char* data, int byteSize) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret, count;
-    snd_pcm_sframes_t frameSize, readFrames;
-
-    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
-    /*TRACE3("  info=%p, data=%p, byteSize=%d\n",
-      (void*) info, (void*) data, (int) byteSize);
-      TRACE2("  info->frameSize=%d, info->handle=%p\n",
-      (int) info->frameSize, (void*) info->handle);
-    */
-    /* sanity */
-    if (byteSize <= 0 || info->frameSize <= 0) {
-        ERROR2(" DAUDIO_Read: byteSize=%d, frameSize=%d!\n",
-               (int) byteSize, (int) info->frameSize);
-        TRACE0("< DAUDIO_Read returning -1\n");
-        return -1;
-    }
-    if (!info->isRunning && info->isFlushed) {
-        // PCM has nothing to read
-        return 0;
-    }
-
-    count = 2; // maximum number of trials to recover from error
-    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
-    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
-    do {
-        readFrames = snd_pcm_readi(info->handle, (void*) data, (snd_pcm_uframes_t) frameSize);
-        if (readFrames < 0) {
-            ret = xrun_recovery(info, (int) readFrames);
-            if (ret <= 0) {
-                TRACE1("DAUDIO_Read: xrun recovery returned %d -> return.\n", ret);
-                return ret;
-            }
-            if (count-- <= 0) {
-                ERROR0("DAUDIO_Read: too many attempts to recover from xrun/suspend\n");
-                return -1;
-            }
-        } else {
-            break;
-        }
-    } while (TRUE);
-    //ret =  snd_pcm_frames_to_bytes(info->handle, readFrames);
-    ret =  (int) (readFrames * info->frameSize);
-    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
-    return ret;
-}
-
-
-int DAUDIO_GetBufferSize(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-
-    return info->bufferSizeInBytes;
-}
-
-int DAUDIO_StillDraining(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    snd_pcm_state_t state;
-
-    state = snd_pcm_state(info->handle);
-    //printState(state);
-    //TRACE1("Still draining: %s\n", (state != SND_PCM_STATE_XRUN)?"TRUE":"FALSE");
-    return (state == SND_PCM_STATE_RUNNING)?TRUE:FALSE;
-}
-
-
-int DAUDIO_Flush(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-
-    TRACE0("DAUDIO_Flush\n");
-
-    if (info->isFlushed) {
-        // nothing to drop
-        return 1;
-    }
-
-    ret = snd_pcm_drop(info->handle);
-    if (ret != 0) {
-        ERROR1("ERROR in snd_pcm_drop: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-
-    info->isFlushed = 1;
-    if (info->isRunning) {
-        ret = DAUDIO_Start(id, isSource);
-    }
-    return ret;
-}
-
-int DAUDIO_GetAvailable(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    snd_pcm_sframes_t availableInFrames;
-    snd_pcm_state_t state;
-    int ret;
-
-    state = snd_pcm_state(info->handle);
-    if (info->isFlushed || state == SND_PCM_STATE_XRUN) {
-        // if in xrun state then we have the entire buffer available,
-        // not 0 as alsa reports
-        ret = info->bufferSizeInBytes;
-    } else {
-        availableInFrames = snd_pcm_avail_update(info->handle);
-        if (availableInFrames < 0) {
-            ret = 0;
-        } else {
-            //ret = snd_pcm_frames_to_bytes(info->handle, availableInFrames);
-            ret = (int) (availableInFrames * info->frameSize);
-        }
-    }
-    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
-    return ret;
-}
-
-INT64 estimatePositionFromAvail(AlsaPcmInfo* info, int isSource, INT64 javaBytePos, int availInBytes) {
-    // estimate the current position with the buffer size and
-    // the available bytes to read or write in the buffer.
-    // not an elegant solution - bytePos will stop on xruns,
-    // and in race conditions it may jump backwards
-    // Advantage is that it is indeed based on the samples that go through
-    // the system (rather than time-based methods)
-    if (isSource) {
-        // javaBytePos is the position that is reached when the current
-        // buffer is played completely
-        return (INT64) (javaBytePos - info->bufferSizeInBytes + availInBytes);
-    } else {
-        // javaBytePos is the position that was when the current buffer was empty
-        return (INT64) (javaBytePos + availInBytes);
-    }
-}
-
-INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-    INT64 result = javaBytePos;
-    snd_pcm_state_t state;
-    state = snd_pcm_state(info->handle);
-
-    if (!info->isFlushed && state != SND_PCM_STATE_XRUN) {
-#ifdef GET_POSITION_METHOD2
-        snd_timestamp_t* ts;
-        snd_pcm_uframes_t framesAvail;
-
-        // note: slight race condition if this is called simultaneously from 2 threads
-        ret = snd_pcm_status(info->handle, info->positionStatus);
-        if (ret != 0) {
-            ERROR1("ERROR in snd_pcm_status: %s\n", snd_strerror(ret));
-            result = javaBytePos;
-        } else {
-            // calculate from time value, or from available bytes
-            framesAvail = snd_pcm_status_get_avail(info->positionStatus);
-            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
-        }
-#endif
-#ifdef GET_POSITION_METHOD3
-        snd_pcm_uframes_t framesAvail;
-        ret = snd_pcm_avail(info->handle, &framesAvail);
-        if (ret != 0) {
-            ERROR1("ERROR in snd_pcm_avail: %s\n", snd_strerror(ret));
-            result = javaBytePos;
-        } else {
-            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
-        }
-#endif
-#ifdef GET_POSITION_METHOD1
-        result = estimatePositionFromAvail(info, isSource, javaBytePos, DAUDIO_GetAvailable(id, isSource));
-#endif
-    }
-    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
-    return result;
-}
-
-
-
-void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    /* save to ignore, since GetBytePosition
-     * takes the javaBytePos param into account
-     */
-}
-
-int DAUDIO_RequiresServicing(void* id, int isSource) {
-    // never need servicing on Linux
-    return FALSE;
-}
-
-void DAUDIO_Service(void* id, int isSource) {
-    // never need servicing on Linux
-}
-
-
-#endif // USE_DAUDIO
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-//#define USE_ERROR
-//#define USE_TRACE
-
-#include "PLATFORM_API_LinuxOS_ALSA_PCMUtils.h"
-#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
-
-
-
-// callback for iteration through devices
-// returns TRUE if iteration should continue
-// NOTE: cardinfo may be NULL (for "default" device)
-typedef int (*DeviceIteratorPtr)(UINT32 deviceID, snd_pcm_info_t* pcminfo,
-                             snd_ctl_card_info_t* cardinfo, void *userData);
-
-// for each ALSA device, call iterator. userData is passed to the iterator
-// returns total number of iterations
-int iteratePCMDevices(DeviceIteratorPtr iterator, void* userData) {
-    int count = 0;
-    int subdeviceCount;
-    int card, dev, subDev;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_pcm_t *pcm;
-    snd_pcm_info_t* pcminfo;
-    snd_ctl_card_info_t *cardinfo, *defcardinfo = NULL;
-    UINT32 deviceID;
-    int doContinue = TRUE;
-
-    snd_pcm_info_malloc(&pcminfo);
-    snd_ctl_card_info_malloc(&cardinfo);
-
-    // 1st try "default" device
-    err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
-                       SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
-    if (err < 0) {
-        // try with the other direction
-        err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
-                           SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
-    }
-    if (err < 0) {
-        ERROR1("ERROR: snd_pcm_open (\"default\"): %s\n", snd_strerror(err));
-    } else {
-        err = snd_pcm_info(pcm, pcminfo);
-        snd_pcm_close(pcm);
-        if (err < 0) {
-            ERROR1("ERROR: snd_pcm_info (\"default\"): %s\n",
-                    snd_strerror(err));
-        } else {
-            // try to get card info
-            card = snd_pcm_info_get_card(pcminfo);
-            if (card >= 0) {
-                sprintf(devname, ALSA_HARDWARE_CARD, card);
-                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
-                    if (snd_ctl_card_info(handle, cardinfo) >= 0) {
-                        defcardinfo = cardinfo;
-                    }
-                    snd_ctl_close(handle);
-                }
-            }
-            // call callback function for the device
-            if (iterator != NULL) {
-                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, pcminfo,
-                                         defcardinfo, userData);
-            }
-            count++;
-        }
-    }
-
-    // iterate cards
-    card = -1;
-    while (doContinue) {
-        if (snd_card_next(&card) < 0) {
-            break;
-        }
-        if (card < 0) {
-            break;
-        }
-        sprintf(devname, ALSA_HARDWARE_CARD, card);
-        TRACE1("Opening alsa device \"%s\"...\n", devname);
-        err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
-        if (err < 0) {
-            ERROR2("ERROR: snd_ctl_open, card=%d: %s\n",
-                    card, snd_strerror(err));
-        } else {
-            err = snd_ctl_card_info(handle, cardinfo);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n",
-                        card, snd_strerror(err));
-            } else {
-                dev = -1;
-                while (doContinue) {
-                    if (snd_ctl_pcm_next_device(handle, &dev) < 0) {
-                        ERROR0("snd_ctl_pcm_next_device\n");
-                    }
-                    if (dev < 0) {
-                        break;
-                    }
-                    snd_pcm_info_set_device(pcminfo, dev);
-                    snd_pcm_info_set_subdevice(pcminfo, 0);
-                    snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
-                    err = snd_ctl_pcm_info(handle, pcminfo);
-                    if (err == -ENOENT) {
-                        // try with the other direction
-                        snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
-                        err = snd_ctl_pcm_info(handle, pcminfo);
-                    }
-                    if (err < 0) {
-                        if (err != -ENOENT) {
-                            ERROR2("ERROR: snd_ctl_pcm_info, card=%d: %s",
-                                    card, snd_strerror(err));
-                        }
-                    } else {
-                        subdeviceCount = needEnumerateSubdevices(ALSA_PCM) ?
-                            snd_pcm_info_get_subdevices_count(pcminfo) : 1;
-                        if (iterator!=NULL) {
-                            for (subDev = 0; subDev < subdeviceCount; subDev++) {
-                                deviceID = encodeDeviceID(card, dev, subDev);
-                                doContinue = (*iterator)(deviceID, pcminfo,
-                                                         cardinfo, userData);
-                                count++;
-                                if (!doContinue) {
-                                    break;
-                                }
-                            }
-                        } else {
-                            count += subdeviceCount;
-                        }
-                    }
-                } // of while(doContinue)
-            }
-            snd_ctl_close(handle);
-        }
-    }
-    snd_ctl_card_info_free(cardinfo);
-    snd_pcm_info_free(pcminfo);
-    return count;
-}
-
-int getAudioDeviceCount() {
-    initAlsaSupport();
-    return iteratePCMDevices(NULL, NULL);
-}
-
-int deviceInfoIterator(UINT32 deviceID, snd_pcm_info_t* pcminfo,
-                       snd_ctl_card_info_t* cardinfo, void* userData) {
-    char buffer[300];
-    ALSA_AudioDeviceDescription* desc = (ALSA_AudioDeviceDescription*)userData;
-#ifdef ALSA_PCM_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    initAlsaSupport();
-    if (desc->index == 0) {
-        // we found the device with correct index
-        *(desc->maxSimultaneousLines) = needEnumerateSubdevices(ALSA_PCM) ?
-                1 : snd_pcm_info_get_subdevices_count(pcminfo);
-        *desc->deviceID = deviceID;
-        buffer[0]=' '; buffer[1]='[';
-        // buffer[300] is enough to store the actual device string w/o overrun
-        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_PCM);
-        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
-        strncpy(desc->name,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_id(cardinfo)
-                    : snd_pcm_info_get_id(pcminfo),
-                desc->strLen - strlen(buffer));
-        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
-        strncpy(desc->vendor, "ALSA (http://www.alsa-project.org)", desc->strLen);
-        strncpy(desc->description,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_name(cardinfo)
-                    : snd_pcm_info_get_name(pcminfo),
-                desc->strLen);
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_pcm_info_get_id(pcminfo), desc->strLen - strlen(desc->description));
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_pcm_info_get_name(pcminfo), desc->strLen - strlen(desc->description));
-        getALSAVersion(desc->version, desc->strLen);
-        TRACE4("Returning %s, %s, %s, %s\n", desc->name, desc->vendor, desc->description, desc->version);
-        return FALSE; // do not continue iteration
-    }
-    desc->index--;
-    return TRUE;
-}
-
-// returns 0 if successful
-int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware) {
-    char buffer[200];
-    int ret;
-
-    initAlsaSupport();
-    getDeviceStringFromDeviceID(buffer, deviceID, !hardware, ALSA_PCM);
-
-    TRACE1("Opening ALSA device %s\n", buffer);
-    ret = snd_pcm_open(handle, buffer,
-                       isSource?SND_PCM_STREAM_PLAYBACK:SND_PCM_STREAM_CAPTURE,
-                       SND_PCM_NONBLOCK);
-    if (ret != 0) {
-        ERROR1("snd_pcm_open returned error code %d \n", ret);
-        *handle = NULL;
-    }
-    return ret;
-}
-
-
-int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc) {
-    initAlsaSupport();
-    TRACE1(" getAudioDeviceDescriptionByIndex(mixerIndex = %d\n", desc->index);
-    iteratePCMDevices(&deviceInfoIterator, desc);
-    return (desc->index == 0)?TRUE:FALSE;
-}
-
-// returns 1 if successful
-// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
-int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
-                            int* sampleSizeInBytes, int* significantBits,
-                            int* isSigned, int* isBigEndian, int* enc) {
-
-    *sampleSizeInBytes = (snd_pcm_format_physical_width(alsaFormat) + 7) / 8;
-    *significantBits = snd_pcm_format_width(alsaFormat);
-
-    // defaults
-    *enc = 0; // PCM
-    *isSigned = (snd_pcm_format_signed(alsaFormat) > 0);
-    *isBigEndian = (snd_pcm_format_big_endian(alsaFormat) > 0);
-
-    // non-PCM formats
-    if (alsaFormat == SND_PCM_FORMAT_MU_LAW) { // Mu-Law
-        *sampleSizeInBytes = 8; *enc = 1; *significantBits = *sampleSizeInBytes;
-    }
-    else if (alsaFormat == SND_PCM_FORMAT_A_LAW) {     // A-Law
-        *sampleSizeInBytes = 8; *enc = 2; *significantBits = *sampleSizeInBytes;
-    }
-    else if (snd_pcm_format_linear(alsaFormat) < 1) {
-        return 0;
-    }
-    return (*sampleSizeInBytes > 0);
-}
-
-// returns 1 if successful
-int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
-                            int sampleSizeInBytes, int significantBits,
-                            int isSigned, int isBigEndian, int enc) {
-    *alsaFormat = SND_PCM_FORMAT_UNKNOWN;
-
-    if (enc == 0) {
-        *alsaFormat = snd_pcm_build_linear_format(significantBits,
-                                                  sampleSizeInBytes * 8,
-                                                  isSigned?0:1,
-                                                  isBigEndian?1:0);
-    }
-    else if ((sampleSizeInBytes == 1) && (significantBits == 8)) {
-        if (enc == 1) { // ULAW
-            *alsaFormat = SND_PCM_FORMAT_MU_LAW;
-        }
-        else if (enc == 2) { // ALAW
-            *alsaFormat = SND_PCM_FORMAT_A_LAW;
-        }
-    }
-    return (*alsaFormat == SND_PCM_FORMAT_UNKNOWN)?0:1;
-}
-
-
-/* end */
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, 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.
- */
-
-// define this with a later version of ALSA than 0.9.0rc3
-// (starting from 1.0.0 it became default behaviour)
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#include 
-#include "Utilities.h"
-
-#ifndef PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
-#define PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
-
-// if this is defined, use plughw: devices
-#define ALSA_PCM_USE_PLUGHW
-//#undef ALSA_PCM_USE_PLUGHW
-
-
-// maximum number of channels that is listed in the formats. If more, than
-// just -1 for channel count is used.
-#define MAXIMUM_LISTED_CHANNELS 32
-
-typedef struct tag_ALSA_AudioDeviceDescription {
-    int index;          // in
-    int strLen;         // in
-    INT32* deviceID;    // out
-    int* maxSimultaneousLines; // out
-    char* name;         // out
-    char* vendor;       // out
-    char* description;  // out
-    char* version;      // out
-} ALSA_AudioDeviceDescription;
-
-
-
-int getAudioDeviceCount();
-int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc);
-
-// returns ALSA error code, or 0 if successful
-int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware);
-
-// returns 1 if successful
-// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
-int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
-                            int* sampleSizeInBytes, int* significantBits,
-                            int* isSigned, int* isBigEndian, int* enc);
-
-int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
-                            int sampleSizeInBytes, int significantBits,
-                            int isSigned, int isBigEndian, int enc);
-
-#endif // PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,724 +0,0 @@
-/*
- * 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.  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.
- */
-
-#define USE_ERROR
-//#define USE_TRACE
-
-#include "Ports.h"
-#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
-#include 
-
-#if USE_PORTS == TRUE
-
-#define MAX_ELEMS (300)
-#define MAX_CONTROLS (MAX_ELEMS * 4)
-
-#define CHANNELS_MONO (SND_MIXER_SCHN_LAST + 1)
-#define CHANNELS_STEREO (SND_MIXER_SCHN_LAST + 2)
-
-typedef struct {
-    snd_mixer_elem_t* elem;
-    INT32 portType; /* one of PORT_XXX_xx */
-    char* controlType; /* one of CONTROL_TYPE_xx */
-    /* Values: either SND_MIXER_SCHN_FRONT_xx, CHANNELS_MONO or CHANNELS_STEREO.
-       For SND_MIXER_SCHN_FRONT_xx, exactly this channel is set/retrieved directly.
-       For CHANNELS_MONO, ALSA channel SND_MIXER_SCHN_MONO is set/retrieved directly.
-       For CHANNELS_STEREO, ALSA channels SND_MIXER_SCHN_FRONT_LEFT and SND_MIXER_SCHN_FRONT_RIGHT
-       are set after a calculation that takes balance into account. Retrieved? Average of both
-       channels? (Using a cached value is not a good idea since the value in the HW may have been
-       altered.) */
-    INT32 channel;
-} PortControl;
-
-
-typedef struct tag_PortMixer {
-    snd_mixer_t* mixer_handle;
-    /* Number of array elements used in elems and types. */
-    int numElems;
-    snd_mixer_elem_t** elems;
-    /* Array of port types (PORT_SRC_UNKNOWN etc.). Indices are the same as in elems. */
-    INT32* types;
-    /* Number of array elements used in controls. */
-    int numControls;
-    PortControl* controls;
-} PortMixer;
-
-
-///// implemented functions of Ports.h
-
-INT32 PORT_GetPortMixerCount() {
-    INT32 mixerCount;
-    int card;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_ctl_card_info_t* info;
-
-    TRACE0("> PORT_GetPortMixerCount\n");
-
-    initAlsaSupport();
-
-    snd_ctl_card_info_malloc(&info);
-    card = -1;
-    mixerCount = 0;
-    if (snd_card_next(&card) >= 0) {
-        while (card >= 0) {
-            sprintf(devname, ALSA_HARDWARE_CARD, card);
-            TRACE1("PORT_GetPortMixerCount: Opening alsa device \"%s\"...\n", devname);
-            err = snd_ctl_open(&handle, devname, 0);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
-            } else {
-                mixerCount++;
-                snd_ctl_close(handle);
-            }
-            if (snd_card_next(&card) < 0) {
-                break;
-            }
-        }
-    }
-    snd_ctl_card_info_free(info);
-    TRACE0("< PORT_GetPortMixerCount\n");
-    return mixerCount;
-}
-
-
-INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
-    snd_ctl_t* handle;
-    snd_ctl_card_info_t* card_info;
-    char devname[16];
-    int err;
-    char buffer[100];
-
-    TRACE0("> PORT_GetPortMixerDescription\n");
-    snd_ctl_card_info_malloc(&card_info);
-
-    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
-    TRACE1("Opening alsa device \"%s\"...\n", devname);
-    err = snd_ctl_open(&handle, devname, 0);
-    if (err < 0) {
-        ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
-        return FALSE;
-    }
-    err = snd_ctl_card_info(handle, card_info);
-    if (err < 0) {
-        ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
-    }
-    strncpy(description->name, snd_ctl_card_info_get_id(card_info), PORT_STRING_LENGTH - 1);
-    sprintf(buffer, " [%s]", devname);
-    strncat(description->name, buffer, PORT_STRING_LENGTH - 1 - strlen(description->name));
-    strncpy(description->vendor, "ALSA (http://www.alsa-project.org)", PORT_STRING_LENGTH - 1);
-    strncpy(description->description, snd_ctl_card_info_get_name(card_info), PORT_STRING_LENGTH - 1);
-    strncat(description->description, ", ", PORT_STRING_LENGTH - 1 - strlen(description->description));
-    strncat(description->description, snd_ctl_card_info_get_mixername(card_info), PORT_STRING_LENGTH - 1 - strlen(description->description));
-    getALSAVersion(description->version, PORT_STRING_LENGTH - 1);
-
-    snd_ctl_close(handle);
-    snd_ctl_card_info_free(card_info);
-    TRACE0("< PORT_GetPortMixerDescription\n");
-    return TRUE;
-}
-
-
-void* PORT_Open(INT32 mixerIndex) {
-    char devname[16];
-    snd_mixer_t* mixer_handle;
-    int err;
-    PortMixer* handle;
-
-    TRACE0("> PORT_Open\n");
-    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
-    if ((err = snd_mixer_open(&mixer_handle, 0)) < 0) {
-        ERROR2("Mixer %s open error: %s", devname, snd_strerror(err));
-        return NULL;
-    }
-    if ((err = snd_mixer_attach(mixer_handle, devname)) < 0) {
-        ERROR2("Mixer attach %s error: %s", devname, snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    if ((err = snd_mixer_selem_register(mixer_handle, NULL, NULL)) < 0) {
-        ERROR1("Mixer register error: %s", snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    err = snd_mixer_load(mixer_handle);
-    if (err < 0) {
-        ERROR2("Mixer %s load error: %s", devname, snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    handle = (PortMixer*) calloc(1, sizeof(PortMixer));
-    if (handle == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    handle->numElems = 0;
-    handle->elems = (snd_mixer_elem_t**) calloc(MAX_ELEMS, sizeof(snd_mixer_elem_t*));
-    if (handle->elems == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle);
-        return NULL;
-    }
-    handle->types = (INT32*) calloc(MAX_ELEMS, sizeof(INT32));
-    if (handle->types == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle->elems);
-        free(handle);
-        return NULL;
-    }
-    handle->controls = (PortControl*) calloc(MAX_CONTROLS, sizeof(PortControl));
-    if (handle->controls == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle->elems);
-        free(handle->types);
-        free(handle);
-        return NULL;
-    }
-    handle->mixer_handle = mixer_handle;
-    // necessary to initialize data structures
-    PORT_GetPortCount(handle);
-    TRACE0("< PORT_Open\n");
-    return handle;
-}
-
-
-void PORT_Close(void* id) {
-    TRACE0("> PORT_Close\n");
-    if (id != NULL) {
-        PortMixer* handle = (PortMixer*) id;
-        if (handle->mixer_handle != NULL) {
-            snd_mixer_close(handle->mixer_handle);
-        }
-        if (handle->elems != NULL) {
-            free(handle->elems);
-        }
-        if (handle->types != NULL) {
-            free(handle->types);
-        }
-        if (handle->controls != NULL) {
-            free(handle->controls);
-        }
-        free(handle);
-    }
-    TRACE0("< PORT_Close\n");
-}
-
-
-
-INT32 PORT_GetPortCount(void* id) {
-    PortMixer* portMixer;
-    snd_mixer_elem_t *elem;
-
-    TRACE0("> PORT_GetPortCount\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portMixer->numElems == 0) {
-        for (elem = snd_mixer_first_elem(portMixer->mixer_handle); elem; elem = snd_mixer_elem_next(elem)) {
-            if (!snd_mixer_selem_is_active(elem))
-                continue;
-            TRACE2("Simple mixer control '%s',%i\n",
-                   snd_mixer_selem_get_name(elem),
-                   snd_mixer_selem_get_index(elem));
-            if (snd_mixer_selem_has_playback_volume(elem)) {
-                portMixer->elems[portMixer->numElems] = elem;
-                portMixer->types[portMixer->numElems] = PORT_DST_UNKNOWN;
-                portMixer->numElems++;
-            }
-            // to prevent buffer overflow
-            if (portMixer->numElems >= MAX_ELEMS) {
-                break;
-            }
-            /* If an element has both playback an capture volume, it is put into the arrays
-               twice. */
-            if (snd_mixer_selem_has_capture_volume(elem)) {
-                portMixer->elems[portMixer->numElems] = elem;
-                portMixer->types[portMixer->numElems] = PORT_SRC_UNKNOWN;
-                portMixer->numElems++;
-            }
-            // to prevent buffer overflow
-            if (portMixer->numElems >= MAX_ELEMS) {
-                break;
-            }
-        }
-    }
-    TRACE0("< PORT_GetPortCount\n");
-    return portMixer->numElems;
-}
-
-
-INT32 PORT_GetPortType(void* id, INT32 portIndex) {
-    PortMixer* portMixer;
-    INT32 type;
-    TRACE0("> PORT_GetPortType\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        // $$mp: Should become a descriptive error code (index out of bounds).
-        return -1;
-    }
-    type = portMixer->types[portIndex];
-    TRACE0("< PORT_GetPortType\n");
-    return type;
-}
-
-
-INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
-    PortMixer* portMixer;
-    const char* nam;
-
-    TRACE0("> PORT_GetPortName\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        // $$mp: Should become a descriptive error code (index out of bounds).
-        return -1;
-    }
-    nam = snd_mixer_selem_get_name(portMixer->elems[portIndex]);
-    strncpy(name, nam, len - 1);
-    name[len - 1] = 0;
-    TRACE0("< PORT_GetPortName\n");
-    return TRUE;
-}
-
-
-static int isPlaybackFunction(INT32 portType) {
-        return (portType & PORT_DST_MASK);
-}
-
-
-/* Sets portControl to a pointer to the next free array element in the PortControl (pointer)
-   array of the passed portMixer. Returns TRUE if successful. May return FALSE if there is no
-   free slot. In this case, portControl is not altered */
-static int getControlSlot(PortMixer* portMixer, PortControl** portControl) {
-    if (portMixer->numControls >= MAX_CONTROLS) {
-        return FALSE;
-    } else {
-        *portControl = &(portMixer->controls[portMixer->numControls]);
-        portMixer->numControls++;
-        return TRUE;
-    }
-}
-
-
-/* Protect against illegal min-max values, preventing divisions by zero.
- */
-inline static long getRange(long min, long max) {
-    if (max > min) {
-        return max - min;
-    } else {
-        return 1;
-    }
-}
-
-
-/* Idea: we may specify that if unit is an empty string, the values are linear and if unit is "dB",
-   the values are logarithmic.
-*/
-static void* createVolumeControl(PortControlCreator* creator,
-                                 PortControl* portControl,
-                                 snd_mixer_elem_t* elem, int isPlayback) {
-    void* control;
-    float precision;
-    long min, max;
-
-    if (isPlayback) {
-        snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
-    }
-    /* $$mp: The volume values retrieved with the ALSA API are strongly supposed to be logarithmic.
-       So the following calculation is wrong. However, there is no correct calculation, since
-       for equal-distant logarithmic steps, the precision expressed in linear varies over the
-       scale. */
-    precision = 1.0F / getRange(min, max);
-    control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_VOLUME, 0.0F, +1.0F, precision, "");
-    return control;
-}
-
-
-void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
-    PortMixer* portMixer;
-    snd_mixer_elem_t* elem;
-    void* control;
-    PortControl* portControl;
-    void* controls[10];
-    int numControls;
-    char* portName;
-    int isPlayback = 0;
-    int isMono;
-    int isStereo;
-    char* type;
-    snd_mixer_selem_channel_id_t channel;
-    memset(controls, 0, sizeof(controls));
-
-    TRACE0("> PORT_GetControls\n");
-    if (id == NULL) {
-        ERROR0("Invalid handle!");
-        // $$mp: an error code should be returned.
-        return;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        ERROR0("Port index out of range!");
-        // $$mp: an error code should be returned.
-        return;
-    }
-    numControls = 0;
-    elem = portMixer->elems[portIndex];
-    if (snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_capture_volume(elem)) {
-        /* Since we've split/duplicated elements with both playback and capture on the recovery
-           of elements, we now can assume that we handle only to deal with either playback or
-           capture. */
-        isPlayback = isPlaybackFunction(portMixer->types[portIndex]);
-        isMono = (isPlayback && snd_mixer_selem_is_playback_mono(elem)) ||
-            (!isPlayback && snd_mixer_selem_is_capture_mono(elem));
-        isStereo = (isPlayback &&
-                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
-                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) ||
-            (!isPlayback &&
-             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
-             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT));
-        // single volume control
-        if (isMono || isStereo) {
-            if (getControlSlot(portMixer, &portControl)) {
-                portControl->elem = elem;
-                portControl->portType = portMixer->types[portIndex];
-                portControl->controlType = CONTROL_TYPE_VOLUME;
-                if (isMono) {
-                    portControl->channel = CHANNELS_MONO;
-                } else {
-                    portControl->channel = CHANNELS_STEREO;
-                }
-                control = createVolumeControl(creator, portControl, elem, isPlayback);
-                if (control != NULL) {
-                    controls[numControls++] = control;
-                }
-            }
-        } else { // more than two channels, each channels has its own control.
-            for (channel = SND_MIXER_SCHN_FRONT_LEFT; channel <= SND_MIXER_SCHN_LAST; channel++) {
-                if ((isPlayback && snd_mixer_selem_has_playback_channel(elem, channel)) ||
-                    (!isPlayback && snd_mixer_selem_has_capture_channel(elem, channel))) {
-                    if (getControlSlot(portMixer, &portControl)) {
-                        portControl->elem = elem;
-                        portControl->portType = portMixer->types[portIndex];
-                        portControl->controlType = CONTROL_TYPE_VOLUME;
-                        portControl->channel = channel;
-                        control = createVolumeControl(creator, portControl, elem, isPlayback);
-                        // We wrap in a compound control to provide the channel name.
-                        if (control != NULL) {
-                            /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
-                               declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
-                               to take a const char* parameter. */
-                            control = (creator->newCompoundControl)(creator, (char*) snd_mixer_selem_channel_name(channel), &control, 1);
-                        }
-                        if (control != NULL) {
-                            controls[numControls++] = control;
-                        }
-                    }
-                }
-            }
-        }
-        // BALANCE control
-        if (isStereo) {
-            if (getControlSlot(portMixer, &portControl)) {
-                portControl->elem = elem;
-                portControl->portType = portMixer->types[portIndex];
-                portControl->controlType = CONTROL_TYPE_BALANCE;
-                portControl->channel = CHANNELS_STEREO;
-                /* $$mp: The value for precision is chosen more or less arbitrarily. */
-                control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_BALANCE, -1.0F, 1.0F, 0.01F, "");
-                if (control != NULL) {
-                    controls[numControls++] = control;
-                }
-            }
-        }
-    }
-    if (snd_mixer_selem_has_playback_switch(elem) || snd_mixer_selem_has_capture_switch(elem)) {
-        if (getControlSlot(portMixer, &portControl)) {
-            type = isPlayback ? CONTROL_TYPE_MUTE : CONTROL_TYPE_SELECT;
-            portControl->elem = elem;
-            portControl->portType = portMixer->types[portIndex];
-            portControl->controlType = type;
-            control = (creator->newBooleanControl)(creator, portControl, type);
-            if (control != NULL) {
-                controls[numControls++] = control;
-            }
-        }
-    }
-    /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
-       declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
-       to take a const char* parameter. */
-    portName = (char*) snd_mixer_selem_get_name(elem);
-    control = (creator->newCompoundControl)(creator, portName, controls, numControls);
-    if (control != NULL) {
-        (creator->addControl)(creator, control);
-    }
-    TRACE0("< PORT_GetControls\n");
-}
-
-
-INT32 PORT_GetIntValue(void* controlIDV) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    int value = 0;
-    snd_mixer_selem_channel_id_t channel;
-
-    if (portControl != NULL) {
-        switch (portControl->channel) {
-        case CHANNELS_MONO:
-            channel = SND_MIXER_SCHN_MONO;
-            break;
-
-        case CHANNELS_STEREO:
-            channel = SND_MIXER_SCHN_FRONT_LEFT;
-            break;
-
-        default:
-            channel = portControl->channel;
-        }
-        if (portControl->controlType == CONTROL_TYPE_MUTE ||
-            portControl->controlType == CONTROL_TYPE_SELECT) {
-            if (isPlaybackFunction(portControl->portType)) {
-                snd_mixer_selem_get_playback_switch(portControl->elem, channel, &value);
-            } else {
-                snd_mixer_selem_get_capture_switch(portControl->elem, channel, &value);
-            }
-            if (portControl->controlType == CONTROL_TYPE_MUTE) {
-                value = ! value;
-            }
-        } else {
-            ERROR1("PORT_GetIntValue(): inappropriate control type: %s\n",
-                   portControl->controlType);
-        }
-    }
-    return (INT32) value;
-}
-
-
-void PORT_SetIntValue(void* controlIDV, INT32 value) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    snd_mixer_selem_channel_id_t channel;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_MUTE) {
-            value = ! value;
-        }
-        if (portControl->controlType == CONTROL_TYPE_MUTE ||
-            portControl->controlType == CONTROL_TYPE_SELECT) {
-            if (isPlaybackFunction(portControl->portType)) {
-                snd_mixer_selem_set_playback_switch_all(portControl->elem, value);
-            } else {
-                snd_mixer_selem_set_capture_switch_all(portControl->elem, value);
-            }
-        } else {
-            ERROR1("PORT_SetIntValue(): inappropriate control type: %s\n",
-                   portControl->controlType);
-        }
-    }
-}
-
-
-static float scaleVolumeValueToNormalized(long value, long min, long max) {
-    return (float) (value - min) / getRange(min, max);
-}
-
-
-static long scaleVolumeValueToHardware(float value, long min, long max) {
-    return (long)(value * getRange(min, max) + min);
-}
-
-
-float getRealVolume(PortControl* portControl,
-                    snd_mixer_selem_channel_id_t channel) {
-    float fValue;
-    long lValue = 0;
-    long min = 0;
-    long max = 0;
-
-    if (isPlaybackFunction(portControl->portType)) {
-        snd_mixer_selem_get_playback_volume_range(portControl->elem,
-                                                  &min, &max);
-        snd_mixer_selem_get_playback_volume(portControl->elem,
-                                            channel, &lValue);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(portControl->elem,
-                                                 &min, &max);
-        snd_mixer_selem_get_capture_volume(portControl->elem,
-                                           channel, &lValue);
-    }
-    fValue = scaleVolumeValueToNormalized(lValue, min, max);
-    return fValue;
-}
-
-
-void setRealVolume(PortControl* portControl,
-                   snd_mixer_selem_channel_id_t channel, float value) {
-    long lValue = 0;
-    long min = 0;
-    long max = 0;
-
-    if (isPlaybackFunction(portControl->portType)) {
-        snd_mixer_selem_get_playback_volume_range(portControl->elem,
-                                                  &min, &max);
-        lValue = scaleVolumeValueToHardware(value, min, max);
-        snd_mixer_selem_set_playback_volume(portControl->elem,
-                                            channel, lValue);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(portControl->elem,
-                                                 &min, &max);
-        lValue = scaleVolumeValueToHardware(value, min, max);
-        snd_mixer_selem_set_capture_volume(portControl->elem,
-                                           channel, lValue);
-    }
-}
-
-
-static float getFakeBalance(PortControl* portControl) {
-    float volL, volR;
-
-    // pan is the ratio of left and right
-    volL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
-    volR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
-    if (volL > volR) {
-        return -1.0f + (volR / volL);
-    }
-    else if (volR > volL) {
-        return 1.0f - (volL / volR);
-    }
-    return 0.0f;
-}
-
-
-static float getFakeVolume(PortControl* portControl) {
-    float valueL;
-    float valueR;
-    float value;
-
-    valueL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
-    valueR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
-    // volume is the greater value of both
-    value = valueL > valueR ? valueL : valueR ;
-    return value;
-}
-
-
-/*
- * sets the unsigned values for left and right volume according to
- * the given volume (0...1) and balance (-1..0..+1)
- */
-static void setFakeVolume(PortControl* portControl, float vol, float bal) {
-    float volumeLeft;
-    float volumeRight;
-
-    if (bal < 0.0f) {
-        volumeLeft = vol;
-        volumeRight = vol * (bal + 1.0f);
-    } else {
-        volumeLeft = vol * (1.0f - bal);
-        volumeRight = vol;
-    }
-    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT, volumeLeft);
-    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT, volumeRight);
-}
-
-
-float PORT_GetFloatValue(void* controlIDV) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    float value = 0.0F;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
-            switch (portControl->channel) {
-            case CHANNELS_MONO:
-                value = getRealVolume(portControl, SND_MIXER_SCHN_MONO);
-                break;
-
-            case CHANNELS_STEREO:
-                value = getFakeVolume(portControl);
-                break;
-
-            default:
-                value = getRealVolume(portControl, portControl->channel);
-            }
-        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
-            if (portControl->channel == CHANNELS_STEREO) {
-                value = getFakeBalance(portControl);
-            } else {
-                ERROR0("PORT_GetFloatValue(): Balance only allowed for stereo channels!\n");
-            }
-        } else {
-            ERROR1("PORT_GetFloatValue(): inappropriate control type: %s!\n",
-                   portControl->controlType);
-        }
-    }
-    return value;
-}
-
-
-void PORT_SetFloatValue(void* controlIDV, float value) {
-    PortControl* portControl = (PortControl*) controlIDV;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
-            switch (portControl->channel) {
-            case CHANNELS_MONO:
-                setRealVolume(portControl, SND_MIXER_SCHN_MONO, value);
-                break;
-
-            case CHANNELS_STEREO:
-                setFakeVolume(portControl, value, getFakeBalance(portControl));
-                break;
-
-            default:
-                setRealVolume(portControl, portControl->channel, value);
-            }
-        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
-            if (portControl->channel == CHANNELS_STEREO) {
-                setFakeVolume(portControl, getFakeVolume(portControl), value);
-            } else {
-                ERROR0("PORT_SetFloatValue(): Balance only allowed for stereo channels!\n");
-            }
-        } else {
-            ERROR1("PORT_SetFloatValue(): inappropriate control type: %s!\n",
-                   portControl->controlType);
-        }
-    }
-}
-
-
-#endif // USE_PORTS
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,626 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_SolarisOS_Utils.h"
-#include "DirectAudio.h"
-
-#if USE_DAUDIO == TRUE
-
-
-// The default buffer time
-#define DEFAULT_PERIOD_TIME_MILLIS 50
-
-///// implemented functions of DirectAudio.h
-
-INT32 DAUDIO_GetDirectAudioDeviceCount() {
-    return (INT32) getAudioDeviceCount();
-}
-
-
-INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex,
-                                             DirectAudioDeviceDescription* description) {
-    AudioDeviceDescription desc;
-
-    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) {
-        description->maxSimulLines = desc.maxSimulLines;
-        strncpy(description->name, desc.name, DAUDIO_STRING_LENGTH-1);
-        description->name[DAUDIO_STRING_LENGTH-1] = 0;
-        strncpy(description->vendor, desc.vendor, DAUDIO_STRING_LENGTH-1);
-        description->vendor[DAUDIO_STRING_LENGTH-1] = 0;
-        strncpy(description->version, desc.version, DAUDIO_STRING_LENGTH-1);
-        description->version[DAUDIO_STRING_LENGTH-1] = 0;
-        /*strncpy(description->description, desc.description, DAUDIO_STRING_LENGTH-1);*/
-        strncpy(description->description, "Solaris Mixer", DAUDIO_STRING_LENGTH-1);
-        description->description[DAUDIO_STRING_LENGTH-1] = 0;
-        return TRUE;
-    }
-    return FALSE;
-
-}
-
-#define MAX_SAMPLE_RATES   20
-
-void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
-    int fd = -1;
-    AudioDeviceDescription desc;
-    am_sample_rates_t      *sr;
-    /* hardcoded bits and channels */
-    int bits[] = {8, 16};
-    int bitsCount = 2;
-    int channels[] = {1, 2};
-    int channelsCount = 2;
-    /* for querying sample rates */
-    int err;
-    int ch, b, s;
-
-    TRACE2("DAUDIO_GetFormats, mixer %d, isSource=%d\n", mixerIndex, isSource);
-    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
-        fd = open(desc.pathctl, O_RDONLY);
-    }
-    if (fd < 0) {
-        ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex);
-        return;
-    }
-
-    /* get sample rates */
-    sr = (am_sample_rates_t*) malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(MAX_SAMPLE_RATES));
-    if (sr == NULL) {
-        ERROR1("DAUDIO_GetFormats: out of memory for mixer %d\n", (int) mixerIndex);
-        close(fd);
-        return;
-    }
-
-    sr->num_samp_rates = MAX_SAMPLE_RATES;
-    sr->type = isSource?AUDIO_PLAY:AUDIO_RECORD;
-    sr->samp_rates[0] = -2;
-    err = ioctl(fd, AUDIO_MIXER_GET_SAMPLE_RATES, sr);
-    if (err < 0) {
-        ERROR1("  DAUDIO_GetFormats: AUDIO_MIXER_GET_SAMPLE_RATES failed for mixer %d!\n",
-               (int)mixerIndex);
-        ERROR2(" -> num_sample_rates=%d sample_rates[0] = %d\n",
-               (int) sr->num_samp_rates,
-               (int) sr->samp_rates[0]);
-        /* Some Solaris 8 drivers fail for get sample rates!
-         * Do as if we support all sample rates
-         */
-        sr->flags = MIXER_SR_LIMITS;
-    }
-    if ((sr->flags & MIXER_SR_LIMITS)
-        || (sr->num_samp_rates > MAX_SAMPLE_RATES)) {
-#ifdef USE_TRACE
-        if ((sr->flags & MIXER_SR_LIMITS)) {
-            TRACE1("  DAUDIO_GetFormats: floating sample rate allowed by mixer %d\n",
-                   (int)mixerIndex);
-        }
-        if (sr->num_samp_rates > MAX_SAMPLE_RATES) {
-            TRACE2("  DAUDIO_GetFormats: more than %d formats. Use -1 for sample rates mixer %d\n",
-                   MAX_SAMPLE_RATES, (int)mixerIndex);
-        }
-#endif
-        /*
-         * Fake it to have only one sample rate: -1
-         */
-        sr->num_samp_rates = 1;
-        sr->samp_rates[0] = -1;
-    }
-    close(fd);
-
-    for (ch = 0; ch < channelsCount; ch++) {
-        for (b = 0; b < bitsCount; b++) {
-            for (s = 0; s < sr->num_samp_rates; s++) {
-                DAUDIO_AddAudioFormat(creator,
-                                      bits[b], /* significant bits */
-                                      0, /* frameSize: let it be calculated */
-                                      channels[ch],
-                                      (float) ((int) sr->samp_rates[s]),
-                                      DAUDIO_PCM, /* encoding - let's only do PCM */
-                                      (bits[b] > 8)?TRUE:TRUE, /* isSigned */
-#ifdef _LITTLE_ENDIAN
-                                      FALSE /* little endian */
-#else
-                                      (bits[b] > 8)?TRUE:FALSE  /* big endian */
-#endif
-                                      );
-            }
-        }
-    }
-    free(sr);
-}
-
-
-typedef struct {
-    int fd;
-    audio_info_t info;
-    int bufferSizeInBytes;
-    int frameSize; /* storage size in Bytes */
-    /* how many bytes were written or read */
-    INT32 transferedBytes;
-    /* if transferedBytes exceed 32-bit boundary,
-     * it will be reset and positionOffset will receive
-     * the offset
-     */
-    INT64 positionOffset;
-} SolPcmInfo;
-
-
-void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
-                  int encoding, float sampleRate, int sampleSizeInBits,
-                  int frameSize, int channels,
-                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
-    int err = 0;
-    int openMode;
-    AudioDeviceDescription desc;
-    SolPcmInfo* info;
-
-    TRACE0("> DAUDIO_Open\n");
-    if (encoding != DAUDIO_PCM) {
-        ERROR1(" DAUDIO_Open: invalid encoding %d\n", (int) encoding);
-        return NULL;
-    }
-    if (channels <= 0) {
-        ERROR1(" DAUDIO_Open: Invalid number of channels=%d!\n", channels);
-        return NULL;
-    }
-
-    info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo));
-    if (!info) {
-        ERROR0("Out of memory\n");
-        return NULL;
-    }
-    memset(info, 0, sizeof(SolPcmInfo));
-    info->frameSize = frameSize;
-    info->fd = -1;
-
-    if (isSource) {
-        openMode = O_WRONLY;
-    } else {
-        openMode = O_RDONLY;
-    }
-
-#ifndef __linux__
-    /* blackdown does not use NONBLOCK */
-    openMode |= O_NONBLOCK;
-#endif
-
-    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
-        info->fd = open(desc.path, openMode);
-    }
-    if (info->fd < 0) {
-        ERROR1("Couldn't open audio device for mixer %d!\n", mixerIndex);
-        free(info);
-        return NULL;
-    }
-    /* set to multiple open */
-    if (ioctl(info->fd, AUDIO_MIXER_MULTIPLE_OPEN, NULL) >= 0) {
-        TRACE1("DAUDIO_Open: %s set to multiple open\n", desc.path);
-    } else {
-        ERROR1("DAUDIO_Open: ioctl AUDIO_MIXER_MULTIPLE_OPEN failed on %s!\n", desc.path);
-    }
-
-    AUDIO_INITINFO(&(info->info));
-    /* need AUDIO_GETINFO ioctl to get this to work on solaris x86  */
-    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
-
-    /* not valid to call AUDIO_SETINFO ioctl with all the fields from AUDIO_GETINFO. */
-    AUDIO_INITINFO(&(info->info));
-
-    if (isSource) {
-        info->info.play.sample_rate = sampleRate;
-        info->info.play.precision = sampleSizeInBits;
-        info->info.play.channels = channels;
-        info->info.play.encoding = AUDIO_ENCODING_LINEAR;
-        info->info.play.buffer_size = bufferSizeInBytes;
-        info->info.play.pause = 1;
-    } else {
-        info->info.record.sample_rate = sampleRate;
-        info->info.record.precision = sampleSizeInBits;
-        info->info.record.channels = channels;
-        info->info.record.encoding = AUDIO_ENCODING_LINEAR;
-        info->info.record.buffer_size = bufferSizeInBytes;
-        info->info.record.pause = 1;
-    }
-    err = ioctl(info->fd, AUDIO_SETINFO,  &(info->info));
-    if (err < 0) {
-        ERROR0("DAUDIO_Open: could not set info!\n");
-        DAUDIO_Close((void*) info, isSource);
-        return NULL;
-    }
-    DAUDIO_Flush((void*) info, isSource);
-
-    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
-    if (err >= 0) {
-        if (isSource) {
-            info->bufferSizeInBytes = info->info.play.buffer_size;
-        } else {
-            info->bufferSizeInBytes = info->info.record.buffer_size;
-        }
-        TRACE2("DAUDIO: buffersize in bytes: requested=%d, got %d\n",
-               (int) bufferSizeInBytes,
-               (int) info->bufferSizeInBytes);
-    } else {
-        ERROR0("DAUDIO_Open: cannot get info!\n");
-        DAUDIO_Close((void*) info, isSource);
-        return NULL;
-    }
-    TRACE0("< DAUDIO_Open: Opened device successfully.\n");
-    return (void*) info;
-}
-
-
-int DAUDIO_Start(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int err, modified;
-    audio_info_t audioInfo;
-
-    TRACE0("> DAUDIO_Start\n");
-
-    AUDIO_INITINFO(&audioInfo);
-    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
-    if (err >= 0) {
-        // unpause
-        modified = FALSE;
-        if (isSource && audioInfo.play.pause) {
-            audioInfo.play.pause = 0;
-            modified = TRUE;
-        }
-        if (!isSource && audioInfo.record.pause) {
-            audioInfo.record.pause = 0;
-            modified = TRUE;
-        }
-        if (modified) {
-            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
-        }
-    }
-
-    TRACE1("< DAUDIO_Start %s\n", (err>=0)?"success":"error");
-    return (err >= 0)?TRUE:FALSE;
-}
-
-int DAUDIO_Stop(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int err, modified;
-    audio_info_t audioInfo;
-
-    TRACE0("> DAUDIO_Stop\n");
-
-    AUDIO_INITINFO(&audioInfo);
-    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
-    if (err >= 0) {
-        // pause
-        modified = FALSE;
-        if (isSource && !audioInfo.play.pause) {
-            audioInfo.play.pause = 1;
-            modified = TRUE;
-        }
-        if (!isSource && !audioInfo.record.pause) {
-            audioInfo.record.pause = 1;
-            modified = TRUE;
-        }
-        if (modified) {
-            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
-        }
-    }
-
-    TRACE1("< DAUDIO_Stop %s\n", (err>=0)?"success":"error");
-    return (err >= 0)?TRUE:FALSE;
-}
-
-void DAUDIO_Close(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-
-    TRACE0("DAUDIO_Close\n");
-    if (info != NULL) {
-        if (info->fd >= 0) {
-            DAUDIO_Flush(id, isSource);
-            close(info->fd);
-        }
-        free(info);
-    }
-}
-
-#ifndef USE_TRACE
-/* close to 2^31 */
-#define POSITION_MAX 2000000000
-#else
-/* for testing */
-#define POSITION_MAX 1000000
-#endif
-
-void resetErrorFlagAndAdjustPosition(SolPcmInfo* info, int isSource, int count) {
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-    int err;
-    int offset = -1;
-    int underrun = FALSE;
-    int devBytes = 0;
-
-    if (count > 0) {
-        info->transferedBytes += count;
-
-        if (isSource) {
-            prinfo = &(audioInfo.play);
-        } else {
-            prinfo = &(audioInfo.record);
-        }
-        AUDIO_INITINFO(&audioInfo);
-        err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
-        if (err >= 0) {
-            underrun = prinfo->error;
-            devBytes = prinfo->samples * info->frameSize;
-        }
-        AUDIO_INITINFO(&audioInfo);
-        if (underrun) {
-            /* if an underrun occurred, reset */
-            ERROR1("DAUDIO_Write/Read: Underrun/overflow: adjusting positionOffset by %d:\n",
-                   (devBytes - info->transferedBytes));
-            ERROR1("    devBytes from %d to 0, ", devBytes);
-            ERROR2(" positionOffset from %d to %d ",
-                   (int) info->positionOffset,
-                   (int) (info->positionOffset + info->transferedBytes));
-            ERROR1(" transferedBytes from %d to 0\n",
-                   (int) info->transferedBytes);
-            prinfo->samples = 0;
-            info->positionOffset += info->transferedBytes;
-            info->transferedBytes = 0;
-        }
-        else if (info->transferedBytes > POSITION_MAX) {
-            /* we will reset transferedBytes and
-             * the samples field in prinfo
-             */
-            offset = devBytes;
-            prinfo->samples = 0;
-        }
-        /* reset error flag */
-        prinfo->error = 0;
-
-        err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
-        if (err >= 0) {
-            if (offset > 0) {
-                /* upon exit of AUDIO_SETINFO, the samples parameter
-                 * was set to the previous value. This is our
-                 * offset.
-                 */
-                TRACE1("Adjust samplePos: offset=%d, ", (int) offset);
-                TRACE2("transferedBytes=%d -> %d, ",
-                       (int) info->transferedBytes,
-                       (int) (info->transferedBytes - offset));
-                TRACE2("positionOffset=%d -> %d\n",
-                       (int) (info->positionOffset),
-                       (int) (((int) info->positionOffset) + offset));
-                info->transferedBytes -= offset;
-                info->positionOffset += offset;
-            }
-        } else {
-            ERROR0("DAUDIO: resetErrorFlagAndAdjustPosition ioctl failed!\n");
-        }
-    }
-}
-
-// returns -1 on error
-int DAUDIO_Write(void* id, char* data, int byteSize) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int ret = -1;
-
-    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
-    if (info!=NULL) {
-        ret = write(info->fd, data, byteSize);
-        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
-        /* sets ret to -1 if buffer full, no error! */
-        if (ret < 0) {
-            ret = 0;
-        }
-    }
-    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
-    return ret;
-}
-
-// returns -1 on error
-int DAUDIO_Read(void* id, char* data, int byteSize) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int ret = -1;
-
-    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
-    if (info != NULL) {
-        ret = read(info->fd, data, byteSize);
-        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
-        /* sets ret to -1 if buffer full, no error! */
-        if (ret < 0) {
-            ret = 0;
-        }
-    }
-    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
-    return ret;
-}
-
-
-int DAUDIO_GetBufferSize(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    if (info) {
-        return info->bufferSizeInBytes;
-    }
-    return 0;
-}
-
-int DAUDIO_StillDraining(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-    int ret = FALSE;
-
-    if (info!=NULL) {
-        if (isSource) {
-            prinfo = &(audioInfo.play);
-        } else {
-            prinfo = &(audioInfo.record);
-        }
-        /* check error flag */
-        AUDIO_INITINFO(&audioInfo);
-        ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
-        ret = (prinfo->error != 0)?FALSE:TRUE;
-    }
-    return ret;
-}
-
-
-int getDevicePosition(SolPcmInfo* info, int isSource) {
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-    int err;
-
-    if (isSource) {
-        prinfo = &(audioInfo.play);
-    } else {
-        prinfo = &(audioInfo.record);
-    }
-    AUDIO_INITINFO(&audioInfo);
-    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
-    if (err >= 0) {
-        /*TRACE2("---> device paused: %d  eof=%d\n",
-               prinfo->pause, prinfo->eof);
-        */
-        return (int) (prinfo->samples * info->frameSize);
-    }
-    ERROR0("DAUDIO: getDevicePosition: ioctl failed!\n");
-    return -1;
-}
-
-int DAUDIO_Flush(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int err = -1;
-    int pos;
-
-    TRACE0("DAUDIO_Flush\n");
-    if (info) {
-        if (isSource) {
-            err = ioctl(info->fd, I_FLUSH, FLUSHW);
-        } else {
-            err = ioctl(info->fd, I_FLUSH, FLUSHR);
-        }
-        if (err >= 0) {
-            /* resets the transferedBytes parameter to
-             * the current samples count of the device
-             */
-            pos = getDevicePosition(info, isSource);
-            if (pos >= 0) {
-                info->transferedBytes = pos;
-            }
-        }
-    }
-    if (err < 0) {
-        ERROR0("ERROR in DAUDIO_Flush\n");
-    }
-    return (err < 0)?FALSE:TRUE;
-}
-
-int DAUDIO_GetAvailable(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int ret = 0;
-    int pos;
-
-    if (info) {
-        /* unfortunately, the STREAMS architecture
-         * seems to not have a method for querying
-         * the available bytes to read/write!
-         * estimate it...
-         */
-        pos = getDevicePosition(info, isSource);
-        if (pos >= 0) {
-            if (isSource) {
-                /* we usually have written more bytes
-                 * to the queue than the device position should be
-                 */
-                ret = (info->bufferSizeInBytes) - (info->transferedBytes - pos);
-            } else {
-                /* for record, the device stream should
-                 * be usually ahead of our read actions
-                 */
-                ret = pos - info->transferedBytes;
-            }
-            if (ret > info->bufferSizeInBytes) {
-                ERROR2("DAUDIO_GetAvailable: available=%d, too big at bufferSize=%d!\n",
-                       (int) ret, (int) info->bufferSizeInBytes);
-                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
-                       (int) pos, (int) info->transferedBytes);
-                ret = info->bufferSizeInBytes;
-            }
-            else if (ret < 0) {
-                ERROR1("DAUDIO_GetAvailable: available=%d, in theory not possible!\n",
-                       (int) ret);
-                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
-                       (int) pos, (int) info->transferedBytes);
-                ret = 0;
-            }
-        }
-    }
-
-    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
-    return ret;
-}
-
-INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int ret;
-    int pos;
-    INT64 result = javaBytePos;
-
-    if (info) {
-        pos = getDevicePosition(info, isSource);
-        if (pos >= 0) {
-            result = info->positionOffset + pos;
-        }
-    }
-
-    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
-    return result;
-}
-
-
-void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int ret;
-    int pos;
-
-    if (info) {
-        pos = getDevicePosition(info, isSource);
-        if (pos >= 0) {
-            info->positionOffset = javaBytePos - pos;
-        }
-    }
-}
-
-int DAUDIO_RequiresServicing(void* id, int isSource) {
-    // never need servicing on Solaris
-    return FALSE;
-}
-
-void DAUDIO_Service(void* id, int isSource) {
-    // never need servicing on Solaris
-}
-
-
-#endif // USE_DAUDIO
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Ports.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Ports.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,600 +0,0 @@
-/*
- * 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.  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.
- */
-
-#define USE_ERROR
-//#define USE_TRACE
-
-#include "Ports.h"
-#include "PLATFORM_API_SolarisOS_Utils.h"
-
-#if USE_PORTS == TRUE
-
-#define MONITOR_GAIN_STRING "Monitor Gain"
-
-#define ALL_TARGET_PORT_COUNT 6
-
-// define the following to not use audio_prinfo_t.mod_ports
-#define SOLARIS7_COMPATIBLE
-
-// Solaris audio defines
-static int targetPorts[ALL_TARGET_PORT_COUNT] = {
-    AUDIO_SPEAKER,
-    AUDIO_HEADPHONE,
-    AUDIO_LINE_OUT,
-    AUDIO_AUX1_OUT,
-    AUDIO_AUX2_OUT,
-    AUDIO_SPDIF_OUT
-};
-
-static char* targetPortNames[ALL_TARGET_PORT_COUNT] = {
-    "Speaker",
-    "Headphone",
-    "Line Out",
-    "AUX1 Out",
-    "AUX2 Out",
-    "SPDIF Out"
-};
-
-// defined in Ports.h
-static int targetPortJavaSoundMapping[ALL_TARGET_PORT_COUNT] = {
-    PORT_DST_SPEAKER,
-    PORT_DST_HEADPHONE,
-    PORT_DST_LINE_OUT,
-    PORT_DST_UNKNOWN,
-    PORT_DST_UNKNOWN,
-    PORT_DST_UNKNOWN,
-};
-
-#define ALL_SOURCE_PORT_COUNT 7
-
-// Solaris audio defines
-static int sourcePorts[ALL_SOURCE_PORT_COUNT] = {
-    AUDIO_MICROPHONE,
-    AUDIO_LINE_IN,
-    AUDIO_CD,
-    AUDIO_AUX1_IN,
-    AUDIO_AUX2_IN,
-    AUDIO_SPDIF_IN,
-    AUDIO_CODEC_LOOPB_IN
-};
-
-static char* sourcePortNames[ALL_SOURCE_PORT_COUNT] = {
-    "Microphone In",
-    "Line In",
-    "Compact Disc In",
-    "AUX1 In",
-    "AUX2 In",
-    "SPDIF In",
-    "Internal Loopback"
-};
-
-// Ports.h defines
-static int sourcePortJavaSoundMapping[ALL_SOURCE_PORT_COUNT] = {
-    PORT_SRC_MICROPHONE,
-    PORT_SRC_LINE_IN,
-    PORT_SRC_COMPACT_DISC,
-    PORT_SRC_UNKNOWN,
-    PORT_SRC_UNKNOWN,
-    PORT_SRC_UNKNOWN,
-    PORT_SRC_UNKNOWN
-};
-
-struct tag_PortControlID;
-
-typedef struct tag_PortInfo {
-    int fd;                    // file descriptor of the pseudo device
-    audio_info_t audioInfo;
-    // ports
-    int targetPortCount;
-    int sourcePortCount;
-    // indexes to sourcePorts/targetPorts
-    // contains first target ports, then source ports
-    int ports[ALL_TARGET_PORT_COUNT + ALL_SOURCE_PORT_COUNT];
-    // controls
-    int maxControlCount;       // upper bound of number of controls
-    int usedControlIDs;        // number of items already filled in controlIDs
-    struct tag_PortControlID* controlIDs; // the control IDs themselves
-} PortInfo;
-
-#define PORT_CONTROL_TYPE_PLAY          0x4000000
-#define PORT_CONTROL_TYPE_RECORD        0x8000000
-#define PORT_CONTROL_TYPE_SELECT_PORT   1
-#define PORT_CONTROL_TYPE_GAIN          2
-#define PORT_CONTROL_TYPE_BALANCE       3
-#define PORT_CONTROL_TYPE_MONITOR_GAIN  10
-#define PORT_CONTROL_TYPE_OUTPUT_MUTED  11
-#define PORT_CONTROL_TYPE_PLAYRECORD_MASK PORT_CONTROL_TYPE_PLAY | PORT_CONTROL_TYPE_RECORD
-#define PORT_CONTROL_TYPE_MASK 0xFFFFFF
-
-
-typedef struct tag_PortControlID {
-    PortInfo*  portInfo;
-    INT32                 controlType;  // PORT_CONTROL_TYPE_XX
-    uint_t                port;
-} PortControlID;
-
-
-///// implemented functions of Ports.h
-
-INT32 PORT_GetPortMixerCount() {
-    return (INT32) getAudioDeviceCount();
-}
-
-
-INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
-    AudioDeviceDescription desc;
-
-    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) {
-        strncpy(description->name, desc.name, PORT_STRING_LENGTH-1);
-        description->name[PORT_STRING_LENGTH-1] = 0;
-        strncpy(description->vendor, desc.vendor, PORT_STRING_LENGTH-1);
-        description->vendor[PORT_STRING_LENGTH-1] = 0;
-        strncpy(description->version, desc.version, PORT_STRING_LENGTH-1);
-        description->version[PORT_STRING_LENGTH-1] = 0;
-        /*strncpy(description->description, desc.description, PORT_STRING_LENGTH-1);*/
-        strncpy(description->description, "Solaris Ports", PORT_STRING_LENGTH-1);
-        description->description[PORT_STRING_LENGTH-1] = 0;
-        return TRUE;
-    }
-    return FALSE;
-}
-
-
-void* PORT_Open(INT32 mixerIndex) {
-    PortInfo* info = NULL;
-    int fd = -1;
-    AudioDeviceDescription desc;
-    int success = FALSE;
-
-    TRACE0("PORT_Open\n");
-    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
-        fd = open(desc.pathctl, O_RDWR);
-    }
-    if (fd < 0) {
-        ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex);
-        return NULL;
-    }
-
-    info = (PortInfo*) malloc(sizeof(PortInfo));
-    if (info != NULL) {
-        memset(info, 0, sizeof(PortInfo));
-        info->fd = fd;
-        success = TRUE;
-    }
-    if (!success) {
-        if (fd >= 0) {
-            close(fd);
-        }
-        PORT_Close((void*) info);
-        info = NULL;
-    }
-    return info;
-}
-
-void PORT_Close(void* id) {
-    TRACE0("PORT_Close\n");
-    if (id != NULL) {
-        PortInfo* info = (PortInfo*) id;
-        if (info->fd >= 0) {
-            close(info->fd);
-            info->fd = -1;
-        }
-        if (info->controlIDs) {
-            free(info->controlIDs);
-            info->controlIDs = NULL;
-        }
-        free(info);
-    }
-}
-
-
-
-INT32 PORT_GetPortCount(void* id) {
-    int ret = 0;
-    PortInfo* info = (PortInfo*) id;
-    if (info != NULL) {
-        if (!info->targetPortCount && !info->sourcePortCount) {
-            int i;
-            AUDIO_INITINFO(&info->audioInfo);
-            if (ioctl(info->fd, AUDIO_GETINFO, &info->audioInfo) >= 0) {
-                for (i = 0; i < ALL_TARGET_PORT_COUNT; i++) {
-                    if (info->audioInfo.play.avail_ports & targetPorts[i]) {
-                        info->ports[info->targetPortCount] = i;
-                        info->targetPortCount++;
-                    }
-#ifdef SOLARIS7_COMPATIBLE
-                    TRACE3("Target %d %s: avail=%d\n", i, targetPortNames[i],
-                           info->audioInfo.play.avail_ports & targetPorts[i]);
-#else
-                    TRACE4("Target %d %s: avail=%d  mod=%d\n", i, targetPortNames[i],
-                           info->audioInfo.play.avail_ports & targetPorts[i],
-                           info->audioInfo.play.mod_ports & targetPorts[i]);
-#endif
-                }
-                for (i = 0; i < ALL_SOURCE_PORT_COUNT; i++) {
-                    if (info->audioInfo.record.avail_ports & sourcePorts[i]) {
-                        info->ports[info->targetPortCount + info->sourcePortCount] = i;
-                        info->sourcePortCount++;
-                    }
-#ifdef SOLARIS7_COMPATIBLE
-                    TRACE3("Source %d %s: avail=%d\n", i, sourcePortNames[i],
-                           info->audioInfo.record.avail_ports & sourcePorts[i]);
-#else
-                    TRACE4("Source %d %s: avail=%d  mod=%d\n", i, sourcePortNames[i],
-                           info->audioInfo.record.avail_ports & sourcePorts[i],
-                           info->audioInfo.record.mod_ports & sourcePorts[i]);
-#endif
-                }
-            }
-        }
-        ret = info->targetPortCount + info->sourcePortCount;
-    }
-    return ret;
-}
-
-int isSourcePort(PortInfo* info, INT32 portIndex) {
-    return (portIndex >= info->targetPortCount);
-}
-
-INT32 PORT_GetPortType(void* id, INT32 portIndex) {
-    PortInfo* info = (PortInfo*) id;
-    if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) {
-        if (isSourcePort(info, portIndex)) {
-            return sourcePortJavaSoundMapping[info->ports[portIndex]];
-        } else {
-            return targetPortJavaSoundMapping[info->ports[portIndex]];
-        }
-    }
-    return 0;
-}
-
-// pre-condition: portIndex must have been verified!
-char* getPortName(PortInfo* info, INT32 portIndex) {
-    char* ret = NULL;
-
-    if (isSourcePort(info, portIndex)) {
-        ret = sourcePortNames[info->ports[portIndex]];
-    } else {
-        ret = targetPortNames[info->ports[portIndex]];
-    }
-    return ret;
-}
-
-INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
-    PortInfo* info = (PortInfo*) id;
-    char* n;
-
-    if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) {
-        n = getPortName(info, portIndex);
-        if (n) {
-            strncpy(name, n, len-1);
-            name[len-1] = 0;
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-void createPortControl(PortInfo* info, PortControlCreator* creator, INT32 portIndex,
-                       INT32 type, void** controlObjects, int* controlCount) {
-    PortControlID* controlID;
-    void* newControl = NULL;
-    int controlIndex;
-    char* jsType = NULL;
-    int isBoolean = FALSE;
-
-    TRACE0(">createPortControl\n");
-
-    // fill the ControlID structure and add this control
-    if (info->usedControlIDs >= info->maxControlCount) {
-        ERROR1("not enough free controlIDs !! maxControlIDs = %d\n", info->maxControlCount);
-        return;
-    }
-    controlID = &(info->controlIDs[info->usedControlIDs]);
-    controlID->portInfo = info;
-    controlID->controlType = type;
-    controlIndex = info->ports[portIndex];
-    if (isSourcePort(info, portIndex)) {
-        controlID->port = sourcePorts[controlIndex];
-    } else {
-        controlID->port = targetPorts[controlIndex];
-    }
-    switch (type & PORT_CONTROL_TYPE_MASK) {
-    case PORT_CONTROL_TYPE_SELECT_PORT:
-        jsType = CONTROL_TYPE_SELECT; isBoolean = TRUE; break;
-    case PORT_CONTROL_TYPE_GAIN:
-        jsType = CONTROL_TYPE_VOLUME;  break;
-    case PORT_CONTROL_TYPE_BALANCE:
-        jsType = CONTROL_TYPE_BALANCE; break;
-    case PORT_CONTROL_TYPE_MONITOR_GAIN:
-        jsType = CONTROL_TYPE_VOLUME; break;
-    case PORT_CONTROL_TYPE_OUTPUT_MUTED:
-        jsType = CONTROL_TYPE_MUTE; isBoolean = TRUE; break;
-    }
-    if (isBoolean) {
-        TRACE0(" PORT_CONTROL_TYPE_BOOLEAN\n");
-        newControl = (creator->newBooleanControl)(creator, controlID, jsType);
-    }
-    else if (jsType == CONTROL_TYPE_BALANCE) {
-        TRACE0(" PORT_CONTROL_TYPE_BALANCE\n");
-        newControl = (creator->newFloatControl)(creator, controlID, jsType,
-                                                -1.0f, 1.0f, 2.0f / 65.0f, "");
-    } else {
-        TRACE0(" PORT_CONTROL_TYPE_FLOAT\n");
-        newControl = (creator->newFloatControl)(creator, controlID, jsType,
-                                                0.0f, 1.0f, 1.0f / 256.0f, "");
-    }
-    if (newControl) {
-        controlObjects[*controlCount] = newControl;
-        (*controlCount)++;
-        info->usedControlIDs++;
-    }
-    TRACE0("addCompoundControl %d controls\n", *controlCount);
-    if (*controlCount) {
-        // create compound control and add it to the vector
-        compControl = (creator->newCompoundControl)(creator, name, controlObjects, *controlCount);
-        if (compControl) {
-            TRACE1(" addCompoundControl: calling addControl %p\n", compControl);
-            (creator->addControl)(creator, compControl);
-        }
-        *controlCount = 0;
-    }
-    TRACE0("addAllControl\n");
-    // go through all controls and add them to the vector
-    for (i = 0; i < *controlCount; i++) {
-        (creator->addControl)(creator, controlObjects[i]);
-    }
-    *controlCount = 0;
-    TRACE0("PORT_GetControls(id=%p, portIndex=%d). controlIDs=%p, maxControlCount=%d\n",
-           id, portIndex, info->controlIDs, info->maxControlCount);
-    if ((portIndex >= 0) && (portIndex < portCount)) {
-        // if the memory isn't reserved for the control structures, allocate it
-        if (!info->controlIDs) {
-            int maxCount = 0;
-            TRACE0("getControl: allocate mem\n");
-            // get a maximum number of controls:
-            // each port has a select, balance, and volume control.
-            maxCount = 3 * portCount;
-            // then there is monitorGain and outputMuted
-            maxCount += (2 * info->targetPortCount);
-            info->maxControlCount = maxCount;
-            info->controlIDs = (PortControlID*) malloc(sizeof(PortControlID) * maxCount);
-        }
-        if (!isSourcePort(info, portIndex)) {
-            type = PORT_CONTROL_TYPE_PLAY;
-            // add master mute control
-            createPortControl(info, creator, portIndex,
-                              type | PORT_CONTROL_TYPE_OUTPUT_MUTED,
-                              controls, &controlCount);
-            addAllControls(info, creator, controls, &controlCount);
-#ifdef SOLARIS7_COMPATIBLE
-            selectable = info->audioInfo.play.avail_ports & targetPorts[info->ports[portIndex]];
-#else
-            selectable = info->audioInfo.play.mod_ports & targetPorts[info->ports[portIndex]];
-#endif
-        } else {
-            type = PORT_CONTROL_TYPE_RECORD;
-#ifdef SOLARIS7_COMPATIBLE
-            selectable = info->audioInfo.record.avail_ports & sourcePorts[info->ports[portIndex]];
-#else
-            selectable = info->audioInfo.record.mod_ports & sourcePorts[info->ports[portIndex]];
-#endif
-        }
-        // add a mixer strip with volume, ...
-        createPortControl(info, creator, portIndex,
-                          type | PORT_CONTROL_TYPE_GAIN,
-                          controls, &controlCount);
-        // ... balance, ...
-        createPortControl(info, creator, portIndex,
-                          type | PORT_CONTROL_TYPE_BALANCE,
-                          controls, &controlCount);
-        // ... and select control (if not always on)...
-        if (selectable) {
-            createPortControl(info, creator, portIndex,
-                              type | PORT_CONTROL_TYPE_SELECT_PORT,
-                              controls, &controlCount);
-        }
-        // ... packaged in a compound control.
-        addCompoundControl(info, creator, getPortName(info, portIndex), controls, &controlCount);
-
-        if (type == PORT_CONTROL_TYPE_PLAY) {
-            // add a single strip for source ports with monitor gain
-            createPortControl(info, creator, portIndex,
-                              type | PORT_CONTROL_TYPE_MONITOR_GAIN,
-                              controls, &controlCount);
-            // also in a compound control
-            addCompoundControl(info, creator, MONITOR_GAIN_STRING, controls, &controlCount);
-        }
-    }
-    TRACE0("< PORT_getControls\n");
-}
-
-INT32 PORT_GetIntValue(void* controlIDV) {
-    PortControlID* controlID = (PortControlID*) controlIDV;
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-
-    AUDIO_INITINFO(&audioInfo);
-    if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
-        if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
-            prinfo = &(audioInfo.play);
-        } else {
-            prinfo = &(audioInfo.record);
-        }
-        switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
-        case PORT_CONTROL_TYPE_SELECT_PORT:
-            return (prinfo->port & controlID->port)?TRUE:FALSE;
-        case PORT_CONTROL_TYPE_OUTPUT_MUTED:
-            return (audioInfo.output_muted)?TRUE:FALSE;
-        default:
-            ERROR1("PORT_GetIntValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
-        }
-    }
-    ERROR0("PORT_GetIntValue: Could not ioctl!\n");
-    return 0;
-}
-
-void PORT_SetIntValue(void* controlIDV, INT32 value) {
-    PortControlID* controlID = (PortControlID*) controlIDV;
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-    int setPort;
-
-    if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
-        prinfo = &(audioInfo.play);
-    } else {
-        prinfo = &(audioInfo.record);
-    }
-    switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
-    case PORT_CONTROL_TYPE_SELECT_PORT:
-        // first try to just add this port. if that fails, set ONLY to this port.
-        AUDIO_INITINFO(&audioInfo);
-        if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
-            if (value) {
-                setPort = (prinfo->port | controlID->port);
-            } else {
-                setPort = (prinfo->port - controlID->port);
-            }
-            AUDIO_INITINFO(&audioInfo);
-            prinfo->port = setPort;
-            if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
-                // didn't work. Either this line doesn't support to select several
-                // ports at once (e.g. record), or a real error
-                if (value) {
-                    // set to ONLY this port (and disable any other currently selected ports)
-                    AUDIO_INITINFO(&audioInfo);
-                    prinfo->port = controlID->port;
-                    if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
-                        ERROR2("Error setting output select port %d to port %d!\n", controlID->port, controlID->port);
-                    }
-                } else {
-                    // assume it's an error
-                    ERROR2("Error setting output select port %d to port %d!\n", controlID->port, setPort);
-                }
-            }
-            break;
-        case PORT_CONTROL_TYPE_OUTPUT_MUTED:
-            AUDIO_INITINFO(&audioInfo);
-            audioInfo.output_muted = (value?TRUE:FALSE);
-            if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
-                ERROR2("Error setting output muted on port %d to %d!\n", controlID->port, value);
-            }
-            break;
-        default:
-            ERROR1("PORT_SetIntValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
-        }
-    }
-}
-
-float PORT_GetFloatValue(void* controlIDV) {
-    PortControlID* controlID = (PortControlID*) controlIDV;
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-
-    AUDIO_INITINFO(&audioInfo);
-    if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
-        if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
-            prinfo = &(audioInfo.play);
-        } else {
-            prinfo = &(audioInfo.record);
-        }
-        switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
-        case PORT_CONTROL_TYPE_GAIN:
-            return ((float) (prinfo->gain - AUDIO_MIN_GAIN))
-                / ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN));
-        case PORT_CONTROL_TYPE_BALANCE:
-            return ((float) ((prinfo->balance - AUDIO_LEFT_BALANCE - AUDIO_MID_BALANCE) << 1))
-                / ((float) (AUDIO_RIGHT_BALANCE - AUDIO_LEFT_BALANCE));
-        case PORT_CONTROL_TYPE_MONITOR_GAIN:
-            return ((float) (audioInfo.monitor_gain - AUDIO_MIN_GAIN))
-                / ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN));
-        default:
-            ERROR1("PORT_GetFloatValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
-        }
-    }
-    ERROR0("PORT_GetFloatValue: Could not ioctl!\n");
-    return 0.0f;
-}
-
-void PORT_SetFloatValue(void* controlIDV, float value) {
-    PortControlID* controlID = (PortControlID*) controlIDV;
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-
-    AUDIO_INITINFO(&audioInfo);
-
-    if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
-        prinfo = &(audioInfo.play);
-    } else {
-        prinfo = &(audioInfo.record);
-    }
-    switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
-    case PORT_CONTROL_TYPE_GAIN:
-        prinfo->gain = AUDIO_MIN_GAIN
-            + (int) ((value * ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + 0.5f);
-        break;
-    case PORT_CONTROL_TYPE_BALANCE:
-        prinfo->balance =  AUDIO_LEFT_BALANCE + AUDIO_MID_BALANCE
-            + ((int) (value * ((float) ((AUDIO_RIGHT_BALANCE - AUDIO_LEFT_BALANCE) >> 1))) + 0.5f);
-        break;
-    case PORT_CONTROL_TYPE_MONITOR_GAIN:
-        audioInfo.monitor_gain = AUDIO_MIN_GAIN
-            + (int) ((value * ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + 0.5f);
-        break;
-    default:
-        ERROR1("PORT_SetFloatValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
-        return;
-    }
-    if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
-        ERROR0("PORT_SetFloatValue: Could not ioctl!\n");
-    }
-}
-
-#endif // USE_PORTS
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Utils.c
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Utils.c	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2002, 2007, 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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_SolarisOS_Utils.h"
-
-#define MAX_AUDIO_DEVICES 20
-
-// not thread safe...
-static AudioDevicePath globalADPaths[MAX_AUDIO_DEVICES];
-static int globalADCount = -1;
-static int globalADCacheTime = -1;
-/* how many seconds do we cache devices */
-#define AD_CACHE_TIME 30
-
-// return seconds
-long getTimeInSeconds() {
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    return tv.tv_sec;
-}
-
-
-int getAudioDeviceCount() {
-    int count = MAX_AUDIO_DEVICES;
-
-    getAudioDevices(globalADPaths, &count);
-    return count;
-}
-
-/* returns TRUE if the path exists at all */
-int addAudioDevice(char* path, AudioDevicePath* adPath, int* count) {
-    int i;
-    int found = 0;
-    int fileExists = 0;
-    // not thread safe...
-    static struct stat statBuf;
-
-    // get stats on the file
-    if (stat(path, &statBuf) == 0) {
-        // file exists.
-        fileExists = 1;
-        // If it is not yet in the adPath array, add it to the array
-        for (i = 0; i < *count; i++) {
-            if (adPath[i].st_ino == statBuf.st_ino
-                && adPath[i].st_dev == statBuf.st_dev) {
-                found = 1;
-                break;
-            }
-        }
-        if (!found) {
-            adPath[*count].st_ino = statBuf.st_ino;
-            adPath[*count].st_dev = statBuf.st_dev;
-            strncpy(adPath[*count].path, path, MAX_NAME_LENGTH);
-            adPath[*count].path[MAX_NAME_LENGTH - 1] = 0;
-            (*count)++;
-            TRACE1("Added audio device %s\n", path);
-        }
-    }
-    return fileExists;
-}
-
-
-void getAudioDevices(AudioDevicePath* adPath, int* count) {
-    int maxCount = *count;
-    char* audiodev;
-    char devsound[15];
-    int i;
-    long timeInSeconds = getTimeInSeconds();
-
-    if (globalADCount < 0
-        || (getTimeInSeconds() - globalADCacheTime) > AD_CACHE_TIME
-        || (adPath != globalADPaths)) {
-        *count = 0;
-        // first device, if set, is AUDIODEV variable
-        audiodev = getenv("AUDIODEV");
-        if (audiodev != NULL && audiodev[0] != 0) {
-            addAudioDevice(audiodev, adPath, count);
-        }
-        // then try /dev/audio
-        addAudioDevice("/dev/audio", adPath, count);
-        // then go through all of the /dev/sound/? devices
-        for (i = 0; i < 100; i++) {
-            sprintf(devsound, "/dev/sound/%d", i);
-            if (!addAudioDevice(devsound, adPath, count)) {
-                break;
-            }
-        }
-        if (adPath == globalADPaths) {
-            /* commit cache */
-            globalADCount = *count;
-            /* set cache time */
-            globalADCacheTime = timeInSeconds;
-        }
-    } else {
-        /* return cache */
-        *count = globalADCount;
-    }
-    // that's it
-}
-
-int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames) {
-    int count = MAX_AUDIO_DEVICES;
-    int ret = 0;
-
-    getAudioDevices(globalADPaths, &count);
-    if (index>=0 && index < count) {
-        ret = getAudioDeviceDescription(globalADPaths[index].path, adDesc, getNames);
-    }
-    return ret;
-}
-
-int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames) {
-    int fd;
-    int mixerMode;
-    int len;
-    audio_info_t info;
-    audio_device_t deviceInfo;
-
-    strncpy(adDesc->path, path, MAX_NAME_LENGTH);
-    adDesc->path[MAX_NAME_LENGTH] = 0;
-    strcpy(adDesc->pathctl, adDesc->path);
-    strcat(adDesc->pathctl, "ctl");
-    strcpy(adDesc->name, adDesc->path);
-    adDesc->vendor[0] = 0;
-    adDesc->version[0] = 0;
-    adDesc->description[0] = 0;
-    adDesc->maxSimulLines = 1;
-
-    // try to open the pseudo device and get more information
-    fd = open(adDesc->pathctl, O_WRONLY | O_NONBLOCK);
-    if (fd >= 0) {
-        close(fd);
-        if (getNames) {
-            fd = open(adDesc->pathctl, O_RDONLY);
-            if (fd >= 0) {
-                if (ioctl(fd, AUDIO_GETDEV, &deviceInfo) >= 0) {
-                    strncpy(adDesc->vendor, deviceInfo.name, MAX_AUDIO_DEV_LEN);
-                    adDesc->vendor[MAX_AUDIO_DEV_LEN] = 0;
-                    strncpy(adDesc->version, deviceInfo.version, MAX_AUDIO_DEV_LEN);
-                    adDesc->version[MAX_AUDIO_DEV_LEN] = 0;
-                    /* add config string to the dev name
-                     * creates a string like "/dev/audio (onboard1)"
-                     */
-                    len = strlen(adDesc->name) + 1;
-                    if (MAX_NAME_LENGTH - len > 3) {
-                        strcat(adDesc->name, " (");
-                        strncat(adDesc->name, deviceInfo.config, MAX_NAME_LENGTH - len);
-                        strcat(adDesc->name, ")");
-                    }
-                    adDesc->name[MAX_NAME_LENGTH-1] = 0;
-                }
-                if (ioctl(fd, AUDIO_MIXERCTL_GET_MODE, &mixerMode) >= 0) {
-                    if (mixerMode == AM_MIXER_MODE) {
-                        TRACE1(" getAudioDeviceDescription: %s is in mixer mode\n", adDesc->path);
-                        adDesc->maxSimulLines = -1;
-                    }
-                } else {
-                    ERROR1("ioctl AUDIO_MIXERCTL_GET_MODE failed on %s!\n", adDesc->path);
-                }
-                close(fd);
-            } else {
-                ERROR1("could not open %s!\n", adDesc->pathctl);
-            }
-        }
-        return 1;
-    }
-    return 0;
-}
diff -r eb72d194235c -r 514c68575523 src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Utils.h
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Utils.h	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include 
-#include 
-#include 
-#include 
-/* does not work on Solaris 2.7 */
-#include 
-#include 
-#include 
-#ifndef __linux__
-#include 
-#endif
-#include 
-#include 
-#include 
-
-#ifndef PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
-#define PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
-
-/* defines for Solaris 2.7
-   #ifndef AUDIO_AUX1_OUT
-   #define AUDIO_AUX1_OUT   (0x08)  // output to aux1 out
-   #define AUDIO_AUX2_OUT   (0x10)  // output to aux2 out
-   #define AUDIO_SPDIF_OUT  (0x20)  // output to SPDIF port
-   #define AUDIO_AUX1_IN    (0x08)    // input from aux1 in
-   #define AUDIO_AUX2_IN    (0x10)    // input from aux2 in
-   #define AUDIO_SPDIF_IN   (0x20)    // input from SPDIF port
-   #endif
-*/
-
-/* input from Codec inter. loopback */
-#ifndef AUDIO_CODEC_LOOPB_IN
-#define AUDIO_CODEC_LOOPB_IN       (0x40)
-#endif
-
-
-#define MAX_NAME_LENGTH 300
-
-typedef struct tag_AudioDevicePath {
-    char path[MAX_NAME_LENGTH];
-    ino_t st_ino; // inode number to detect duplicate devices
-    dev_t st_dev; // device ID to detect duplicate audio devices
-} AudioDevicePath;
-
-typedef struct tag_AudioDeviceDescription {
-    INT32 maxSimulLines;
-    char path[MAX_NAME_LENGTH+1];
-    char pathctl[MAX_NAME_LENGTH+4];
-    char name[MAX_NAME_LENGTH+1];
-    char vendor[MAX_NAME_LENGTH+1];
-    char version[MAX_NAME_LENGTH+1];
-    char description[MAX_NAME_LENGTH+1];
-} AudioDeviceDescription;
-
-int getAudioDeviceCount();
-
-/*
- * adPath is an array of AudioDevicePath structures
- * count contains initially the number of elements in adPath
- *       and will be set to the returned number of paths.
- */
-void getAudioDevices(AudioDevicePath* adPath, int* count);
-
-/*
- * fills adDesc from the audio device given in path
- * returns 0 if an error occurred
- * if getNames is 0, only path and pathctl are filled
- */
-int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames);
-int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames);
-
-
-#endif // PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
diff -r eb72d194235c -r 514c68575523 src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java
--- a/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java	Fri Mar 23 18:44:47 2018 +0000
@@ -38,7 +38,6 @@
 import java.awt.peer.WindowPeer;
 import java.util.ArrayList;
 
-import jdk.internal.perf.PerfCounter;
 import sun.awt.AWTAccessor;
 import sun.awt.AWTAccessor.ComponentAccessor;
 import sun.awt.Win32GraphicsDevice;
@@ -70,9 +69,6 @@
         if (d3dAvailable) {
             // we don't use pixel formats for the d3d pipeline
             pfDisabled = true;
-            PerfCounter.getD3DAvailable().set(1);
-        } else {
-            PerfCounter.getD3DAvailable().set(0);
         }
     }
 
diff -r eb72d194235c -r 514c68575523 src/java.desktop/windows/native/libawt/windows/awt_Component.cpp
--- a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Fri Mar 23 18:44:47 2018 +0000
@@ -7127,9 +7127,9 @@
 {
     TRY;
 
-    return (jboolean)AwtToolkit::GetInstance().SyncCall(
+    return (jboolean)((intptr_t)AwtToolkit::GetInstance().SyncCall(
         (void *(*)(void *))AwtComponent::_NativeHandlesWheelScrolling,
-        env->NewGlobalRef(self));
+        env->NewGlobalRef(self)));
     // global ref is deleted in _NativeHandlesWheelScrolling
 
     CATCH_BAD_ALLOC_RET(NULL);
@@ -7148,9 +7148,9 @@
 
     jobject selfGlobalRef = env->NewGlobalRef(self);
 
-    return (jboolean)AwtToolkit::GetInstance().SyncCall(
+    return (jboolean)((intptr_t)AwtToolkit::GetInstance().SyncCall(
         (void*(*)(void*))AwtComponent::_IsObscured,
-        (void *)selfGlobalRef);
+        (void *)selfGlobalRef));
     // selfGlobalRef is deleted in _IsObscured
 
     CATCH_BAD_ALLOC_RET(NULL);
diff -r eb72d194235c -r 514c68575523 src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp
--- a/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp	Fri Mar 23 18:44:47 2018 +0000
@@ -92,7 +92,7 @@
     JNU_ReleaseStringPlatformChars(env, fileOrUri_j, fileOrUri_c);
     JNU_ReleaseStringPlatformChars(env, verb_j, verb_c);
 
-    if ((int)retval <= 32) {
+    if ((int)((intptr_t)retval) <= 32) {
         // ShellExecute failed.
         LPTSTR buffer = NULL;
         int len = ::FormatMessage(
diff -r eb72d194235c -r 514c68575523 src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp
--- a/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp	Fri Mar 23 18:44:47 2018 +0000
@@ -1607,7 +1607,7 @@
             DWORD fThread = ::GetWindowThreadProcessId(fHWnd, NULL);
             if (fThread != AwtToolkit::GetInstance().MainThread()) {
                 // check if this thread has been already blocked
-                BlockedThreadStruct *blockedThread = (BlockedThreadStruct *)sm_BlockedThreads.get((void *)fThread);
+                BlockedThreadStruct *blockedThread = (BlockedThreadStruct *)sm_BlockedThreads.get((void *)((intptr_t)fThread));
                 if (blocked) {
                     if (blockedThread == NULL) {
                         blockedThread = new BlockedThreadStruct;
@@ -1616,7 +1616,7 @@
                                                                       0, fThread);
                         blockedThread->mouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)AwtDialog::MouseHookProc_NonTT,
                                                                       0, fThread);
-                        sm_BlockedThreads.put((void *)fThread, blockedThread);
+                        sm_BlockedThreads.put((void *)((intptr_t)fThread), blockedThread);
                     } else {
                         blockedThread->framesCount++;
                     }
@@ -1628,7 +1628,7 @@
                         if ((blockedThread->framesCount) == 1) {
                             ::UnhookWindowsHookEx(blockedThread->modalHook);
                             ::UnhookWindowsHookEx(blockedThread->mouseHook);
-                            sm_BlockedThreads.remove((void *)fThread);
+                            sm_BlockedThreads.remove((void *)((intptr_t)fThread));
                             delete blockedThread;
                         } else {
                             blockedThread->framesCount--;
diff -r eb72d194235c -r 514c68575523 src/java.desktop/windows/native/libawt/windows/awt_List.cpp
--- a/src/java.desktop/windows/native/libawt/windows/awt_List.cpp	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/windows/native/libawt/windows/awt_List.cpp	Fri Mar 23 18:44:47 2018 +0000
@@ -823,9 +823,9 @@
 
     jobject selfGlobalRef = env->NewGlobalRef(self);
 
-    return (jint)AwtToolkit::GetInstance().SyncCall(
+    return (jint)((intptr_t)AwtToolkit::GetInstance().SyncCall(
         (void *(*)(void *))AwtList::_GetMaxWidth,
-        (void *)selfGlobalRef);
+        (void *)selfGlobalRef));
     // selfGlobalRef is deleted in _GetMaxWidth
 
     CATCH_BAD_ALLOC_RET(0);
@@ -1011,8 +1011,8 @@
     ses->list = env->NewGlobalRef(self);
     ses->index = index;
 
-    return (jboolean)AwtToolkit::GetInstance().SyncCall(
-        (void *(*)(void *))AwtList::_IsSelected, ses);
+    return (jboolean)((intptr_t)AwtToolkit::GetInstance().SyncCall(
+        (void *(*)(void *))AwtList::_IsSelected, ses));
     // global ref and ses are deleted in _IsSelected
 
     CATCH_BAD_ALLOC_RET(FALSE);
diff -r eb72d194235c -r 514c68575523 src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
--- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Fri Mar 23 18:44:47 2018 +0000
@@ -1106,7 +1106,7 @@
           if (comp != NULL)
           {
               comp->SetInputMethod(self, useNativeCompWindow);
-              comp->ImmAssociateContext((HIMC)context);
+              comp->ImmAssociateContext((HIMC)((intptr_t)context));
           }
 
           if (peer != NULL) {
@@ -3139,7 +3139,7 @@
         (m_touchKbrdExeFilePath != NULL)) {
         HINSTANCE retVal = ::ShellExecute(NULL, _T("open"),
             m_touchKbrdExeFilePath, NULL, NULL, SW_SHOW);
-        if ((int)retVal <= 32) {
+        if ((int)((intptr_t)retVal) <= 32) {
             DTRACE_PRINTLN1("AwtToolkit::ShowTouchKeyboard: Failed"
                 ", retVal='%d'", (int)retVal);
         }
diff -r eb72d194235c -r 514c68575523 src/java.desktop/windows/native/libawt/windows/awt_Window.cpp
--- a/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp	Fri Mar 23 18:44:47 2018 +0000
@@ -3915,8 +3915,8 @@
     rfs->component = selfGlobalRef;
     rfs->isMouseEventCause = isMouseEventCause;
 
-    return (jboolean)AwtToolkit::GetInstance().SyncCall(
-        (void*(*)(void*))AwtWindow::_RequestWindowFocus, rfs);
+    return (jboolean)((intptr_t)AwtToolkit::GetInstance().SyncCall(
+        (void*(*)(void*))AwtWindow::_RequestWindowFocus, rfs));
     // global refs and rfs are deleted in _RequestWindowFocus
 
     CATCH_BAD_ALLOC_RET(JNI_FALSE);
diff -r eb72d194235c -r 514c68575523 src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspector.cpp
--- a/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspector.cpp	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspector.cpp	Fri Mar 23 18:44:47 2018 +0000
@@ -1526,7 +1526,8 @@
     size_t messageNumber = g_MessageHistory.GetCurrentMessageIndex() + 1;
     char text [32] = {0};
     if ( 0 != messageCount ) {
-        ::_snprintf(text, sizeof(text), "%d of %d", messageNumber, messageCount);
+        ::_snprintf(text, sizeof(text), "%d of %d", (int)messageNumber,
+                                                    (int) messageCount);
     }
     return ::SetWindowText(dlgItem, text);
 }
diff -r eb72d194235c -r 514c68575523 src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp
--- a/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp	Fri Mar 23 18:44:47 2018 +0000
@@ -527,7 +527,7 @@
         tvi.mask = TVIF_PARAM | TVIF_TEXT;
         tvi.pszText = (char *) s; // Accessible name and role
         tvi.cchTextMax = (int)strlen(s);
-        tvi.lParam = (long) newNode; // Accessibility information
+        tvi.lParam = (LPARAM) newNode; // Accessibility information
 
         TVINSERTSTRUCT tvis;
         tvis.hParent = treeNodeParent;
@@ -544,13 +544,13 @@
         char s[LINE_BUFSIZE];
         sprintf( s,
             "ERROR calling GetAccessibleContextInfo; vmID = %X, context = %p",
-            vmID, context );
+            vmID, (void*)context );
 
         TVITEM tvi;
         tvi.mask = TVIF_PARAM | TVIF_TEXT;  // text and lParam are only valid parts
         tvi.pszText = (char *) s;
         tvi.cchTextMax = (int)strlen(s);
-        tvi.lParam = (long) newNode;
+        tvi.lParam = (LPARAM) newNode;
 
         TVINSERTSTRUCT tvis;
         tvis.hParent = treeNodeParent;
diff -r eb72d194235c -r 514c68575523 src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c
--- a/src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, 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
@@ -231,7 +231,7 @@
     int table_size = sizeof(error_messages) / sizeof(error_messages[0]);
     int i;
 
-    for (i=0; iGetArrayLength(env, args);
 
-    for (i=0; iGetObjectArrayElement(env, args, i);
         if (obj != NULL) {
             cstr = JNU_GetStringPlatformChars(env, obj, &isCopy);
@@ -314,6 +314,15 @@
                     return -1;
                 }
             }
+        } else {
+            char* newbuf = (char*)realloc(buf, size + 1);
+            if (newbuf == NULL) {
+                free(buf);
+                JNU_ThrowOutOfMemoryError(env, "realloc failed");
+                return -1;
+            }
+            buf = newbuf;
+            buf[size++] = 0;
         }
         if ((*env)->ExceptionOccurred(env)) {
             free(buf);
diff -r eb72d194235c -r 514c68575523 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Fri Mar 23 18:44:47 2018 +0000
@@ -828,7 +828,7 @@
         return buf.toList();
     }
 
-    boolean checkDenotable(Type t) {
+    public boolean checkDenotable(Type t) {
         return denotableChecker.visit(t, null);
     }
         // where
diff -r eb72d194235c -r 514c68575523 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Mar 23 18:44:47 2018 +0000
@@ -43,6 +43,7 @@
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.code.Types.UniqueType;
+import com.sun.tools.javac.comp.Check;
 import com.sun.tools.javac.file.PathFileObject;
 import com.sun.tools.javac.jvm.Pool.DynamicMethod;
 import com.sun.tools.javac.jvm.Pool.Method;
@@ -101,6 +102,8 @@
     /** Type utilities. */
     private Types types;
 
+    private Check check;
+
     /**
      * If true, class files will be written in module-specific subdirectories
      * of the CLASS_OUTPUT location.
@@ -178,6 +181,7 @@
         target = Target.instance(context);
         source = Source.instance(context);
         types = Types.instance(context);
+        check = Check.instance(context);
         fileManager = context.get(JavaFileManager.class);
         signatureGen = new CWSignatureGenerator(types);
 
@@ -1294,10 +1298,10 @@
     //where
     private boolean needsLocalVariableTypeEntry(Type t) {
         //a local variable needs a type-entry if its type T is generic
-        //(i.e. |T| != T) and if it's not an intersection type (not supported
-        //in signature attribute grammar)
-        return (!types.isSameType(t, types.erasure(t)) &&
-                !t.isCompound());
+        //(i.e. |T| != T) and if it's not an non-denotable type (non-denotable
+        // types are not supported in signature attribute grammar!)
+        return !types.isSameType(t, types.erasure(t)) &&
+                check.checkDenotable(t);
     }
 
     void writeStackMap(Code code) {
diff -r eb72d194235c -r 514c68575523 test/hotspot/jtreg/ProblemList.txt
--- a/test/hotspot/jtreg/ProblemList.txt	Fri Mar 23 18:01:52 2018 +0000
+++ b/test/hotspot/jtreg/ProblemList.txt	Fri Mar 23 18:44:47 2018 +0000
@@ -44,6 +44,7 @@
 compiler/codecache/stress/OverloadCompileQueueTest.java 8166554 generic-all
 compiler/codegen/Test6896617.java 8193479 generic-all
 compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java 8140405 generic-all
+compiler/jvmci/compilerToVM/GetExceptionTableTest.java 8200135 generic-all
 compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java 8158860 generic-all
 compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java 8163894 generic-all
 compiler/tiered/LevelTransitionTest.java 8067651 generic-all
diff -r eb72d194235c -r 514c68575523 test/jdk/java/awt/Frame/UnfocusableMaximizedFrameResizablity/UnfocusableMaximizedFrameResizablity.java
--- a/test/jdk/java/awt/Frame/UnfocusableMaximizedFrameResizablity/UnfocusableMaximizedFrameResizablity.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/test/jdk/java/awt/Frame/UnfocusableMaximizedFrameResizablity/UnfocusableMaximizedFrameResizablity.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, 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
@@ -24,389 +24,97 @@
 /*
   @test
   @key headful
-  @bug 4980161
+  @bug 4980161 7158623
   @summary Setting focusable window state to false makes the maximized frame resizable
-  @author anthony.petrov@...: area=awt.toplevel
-  @library ../../regtesthelpers
-  @build Util
+  @compile UnfocusableMaximizedFrameResizablity.java
   @run main UnfocusableMaximizedFrameResizablity
 */
 
-/**
- * UnfocusableMaximizedFrameResizablity.java
- *
- * summary:  Tests whether a maximized unfocusable frame connot be resized by the user
- */
+import java.awt.Toolkit;
+import java.awt.Frame;
+import java.awt.Rectangle;
+import java.awt.AWTException;
+import java.awt.event.InputEvent;
+import java.awt.Robot;
 
-import java.awt.*;
-import java.awt.event.*;
-import test.java.awt.regtesthelpers.Util;
-
-public class UnfocusableMaximizedFrameResizablity
-{
-
-    //*** test-writer defined static variables go here ***
-
+public class UnfocusableMaximizedFrameResizablity {
 
-    private static void init()
-    {
-        //*** Create instructions for the user here ***
+    private static Frame frame;
+    private static Robot robot;
+    private static boolean isProgInterruption = false;
+    private static Thread mainThread = null;
+    private static int sleepTime = 300000;
 
-        String[] instructions =
-        {
-            "This is an AUTOMATIC test, simply wait until it is done.",
-            "The result (passed or failed) will be shown in the",
-            "message window below."
-        };
-        Sysout.createDialog( );
-        Sysout.printInstructions( instructions );
+    private static void createAndShowFrame() {
 
+        //The MAXIMIZED_BOTH state is not supported by the toolkit. Nothing to test.
         if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
-            System.out.println("The MAXIMIZED_BOTH state is not supported by the toolkit. Nothing to test.");
-            pass();
             return;
         }
 
-        // Create the maximized unfocusable frame
-        final Frame f = new Frame("Unfocusable frame");
-        f.setMaximizedBounds(new Rectangle(0, 0, 300, 300));
-        f.setSize(200, 200);
-        f.setVisible(true);
-        f.setExtendedState(Frame.MAXIMIZED_BOTH);
-        f.setFocusableWindowState(false);
+        frame = new Frame("Unfocusable frame");
+        frame.setMaximizedBounds(new Rectangle(0, 0, 300, 300));
+        frame.setSize(200, 200);
+        frame.setVisible(true);
+        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
+        frame.setFocusableWindowState(false);
 
-        Robot robot = Util.createRobot();
-        robot.setAutoDelay(20);
-
-        Util.waitForIdle(robot);
+        try {
+            robot = new Robot();
+        } catch (AWTException e) {
+            throw new RuntimeException("Robot creation failed");
+        }
+        robot.delay(2000);
 
         // The initial bounds of the frame
-        final Rectangle bounds = f.getBounds();
-        System.out.println("Initial frame bounds: " + bounds);
+        final Rectangle bounds = frame.getBounds();
 
         // Let's move the mouse pointer to the bottom-right coner of the frame (the "size-grip")
         robot.mouseMove(bounds.x + bounds.width - 2, bounds.y + bounds.height - 2);
+        robot.waitForIdle();
 
         // ... and start resizing
-        robot.mousePress( InputEvent.BUTTON1_MASK );
-        Util.waitForIdle(robot);
+        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        robot.waitForIdle();
         robot.mouseMove(bounds.x + bounds.width + 20, bounds.y + bounds.height + 15);
-        Util.waitForIdle(robot);
-        robot.mouseRelease( InputEvent.BUTTON1_MASK );
-        Util.waitForIdle(robot);
+        robot.waitForIdle();
+
+        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+        robot.waitForIdle();
 
         // The bounds of the frame after the attempt of resizing is made
-        final Rectangle finalBounds = f.getBounds();
-        System.out.println("Final frame bounds: " + finalBounds);
+        final Rectangle finalBounds = frame.getBounds();
 
         if (!finalBounds.equals(bounds)) {
-            fail("The maximized unfocusable frame can be resized.");
-            return;
+            cleanup();
+            throw new RuntimeException("The maximized unfocusable frame can be resized.");
         }
-
-        UnfocusableMaximizedFrameResizablity.pass();
-
-    }//End  init()
-
-
-
-    /*****************************************************
-     * 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-
-     * 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;
+        cleanup();
+    }
 
-    // Not sure about what happens if multiple of this test are
-    //  instantiated in the same VM.  Being static (and using
-    //  static vars), it aint gonna work.  Not worrying about
-    //  it for now.
-    public static void main( String args[] ) throws InterruptedException
-    {
-        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 pass nor test fail has been
-        // called -- either would have thrown an exception and ended the
-        // test, so we know we have multiple threads.
+    private static void cleanup() {
+        frame.dispose();
+        isProgInterruption = true;
+        mainThread.interrupt();
+    }
+
+    public static void main(String args[]) throws InterruptedException {
 
-        //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)
-        {
-            //The test harness may have interrupted the test.  If so, rethrow the exception
-            // so that the harness gets it and deals with it.
-            if( ! testGeneratedInterrupt ) throw e;
+        mainThread = Thread.currentThread();
 
-            //reset flag in case hit this code more than once for some reason (just safety)
-            testGeneratedInterrupt = false;
-
-            if ( theTestPassed == false )
-            {
-                throw new RuntimeException( failureMessage );
+        try {
+            createAndShowFrame();
+            mainThread.sleep(sleepTime);
+        } catch (InterruptedException e) {
+            if (!isProgInterruption) {
+                throw e;
             }
         }
 
-    }//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();
+        if (!isProgInterruption) {
+            throw new RuntimeException("Timed out after " + sleepTime / 1000
+                    + " seconds");
         }
-        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 UnfocusableMaximizedFrameResizablity
-
-//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 ****************
-
-// if want to make listeners, here is the recommended place for them, then 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
-
-         UnfocusableMaximizedFrameResizablity.pass();
-       }
-      else if( tries == 20 )
-       {
-         //tried too many times without getting enough events so fail
-
-         UnfocusableMaximizedFrameResizablity.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.setVisible(true);
-        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.setVisible(true);
-        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 );
-        System.out.println(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
-{
-
-    TextArea instructionsText;
-    TextArea messageText;
-    int maxStringLength = 80;
-
-    //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);
-
-        pack();
-
-        setVisible(true);
-    }// 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" );
-        System.out.println(messageIn);
-    }
-
-}// TestDialog  class
diff -r eb72d194235c -r 514c68575523 test/jdk/java/awt/event/SequencedEvent/SequencedEventTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/event/SequencedEvent/SequencedEventTest.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2018, 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 8152974
+ * @key headful
+ * @summary AWT hang occurrs when sequenced events arrive out of sequence
+ * @run main SequencedEventTest
+ */
+import sun.awt.AppContext;
+import sun.awt.SunToolkit;
+
+import java.awt.Robot;
+import java.awt.Point;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.AWTEvent;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
+import java.lang.reflect.Constructor;
+import java.util.concurrent.CountDownLatch;
+
+import javax.swing.JFrame;
+import javax.swing.JButton;
+import javax.swing.SwingUtilities;
+import javax.swing.JTextArea;
+
+public class SequencedEventTest extends JFrame implements ActionListener {
+    private JButton spamMeButton;
+    private static Robot robot;
+    private static SequencedEventTest window;
+    private static AppContext context;
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(() ->  {
+            window = new SequencedEventTest();
+            window.setVisible(true);
+        });
+
+        robot = new Robot();
+        robot.waitForIdle();
+
+        Point pt  = window.spamMeButton.getLocationOnScreen();
+        Dimension d = window.spamMeButton.getSize();
+
+        robot.mouseMove(pt.x + d.width / 2, pt.y + d.height / 2);
+        robot.waitForIdle();
+        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+        /*
+         *Cannot have robot.waitForIdle() here since it will block the test forever,
+         * in the case of failure and the test will timeout.
+         */
+
+        try {
+            /*
+             * Wait for 2 seconds, and then see if all the sequenced events are dispatched.
+             */
+            Thread.sleep(2000);
+            AWTEvent ev = Toolkit.getDefaultToolkit().getSystemEventQueue().
+                    peekEvent(java.awt.event.FocusEvent.FOCUS_LAST + 1);
+
+            if (ev != null)
+                throw new RuntimeException("Test case failed!");
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Test case failed." + e.getMessage());
+        }
+
+        /*
+         * In the case of failure, the cleanup job cannot be executed, since it
+         * will block the test.
+         */
+        System.out.println("Test case succeeded.");
+        context.dispose();
+        SwingUtilities.invokeAndWait(() -> window.dispose());
+    }
+
+    public SequencedEventTest() {
+        super("Test Window");
+
+        setLayout(new FlowLayout());
+        JTextArea textBlock = new JTextArea("Lorem ipsum dolor sit amet...");
+        add(textBlock);
+
+        spamMeButton = new JButton("Press me!");
+        spamMeButton.addActionListener(this);
+        add(spamMeButton);
+        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        pack();
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if(e.getSource() == spamMeButton) {
+            AWTEvent eventOne = getSequencedEvent();
+            AWTEvent eventFour = getSequencedEvent();
+            ThreadGroup tg = new ThreadGroup("TestThreadGroup" );
+            CountDownLatch latch = new CountDownLatch(1);
+            Thread t = new Thread(tg, () -> {
+                context = SunToolkit.createNewAppContext();
+                AWTEvent eventTwo = getSequencedEvent();
+                AWTEvent eventThree = getSequencedEvent();
+
+                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(eventThree);
+                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new ActionEvent(this, 0, null));
+                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new ActionEvent(this, 1, null));
+                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(eventTwo);
+
+                latch.countDown();
+            });
+
+            t.start();
+            try {
+                latch.await();
+            }catch (InterruptedException ex) {
+                throw new RuntimeException("Test case failed.");
+            }
+
+            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(eventFour);
+            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new ActionEvent(this, 2, null));
+            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new ActionEvent(this, 3, null));
+            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(eventOne);
+
+            try {
+                t.join();
+            } catch (InterruptedException ex) {
+                throw new RuntimeException("Test case failed.");
+            }
+        }
+    }
+
+    private AWTEvent getSequencedEvent()
+    {
+        AWTEvent wrapMe = new AWTEvent(this, AWTEvent.RESERVED_ID_MAX) {};
+
+        try {
+            /*
+             * SequencedEvent is a package private class, which cannot be instantiated
+             * by importing. So use reflection to create an instance.
+             */
+            Class seqClass = (Class) Class.forName("java.awt.SequencedEvent");
+            Constructor seqConst = seqClass.getConstructor(AWTEvent.class);
+            seqConst.setAccessible(true);;
+            return seqConst.newInstance(wrapMe);
+        } catch (Throwable err) {
+            throw new RuntimeException("Unable to instantiate SequencedEvent",err);
+        }
+    }
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/java/io/ByteArrayInputStream/ReadAllReadNTransferTo.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/io/ByteArrayInputStream/ReadAllReadNTransferTo.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018, 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.util.Arrays;
+import java.util.Objects;
+import java.util.Random;
+import jdk.test.lib.RandomFactory;
+
+/* @test
+ * @library /test/lib
+ * @build jdk.test.lib.RandomFactory
+ * @run main ReadAllReadNTransferTo
+ * @bug 8180451
+ * @summary Verify ByteArrayInputStream readAllBytes, readNBytes, and transferTo
+ * @key randomness
+ */
+public class ReadAllReadNTransferTo {
+    private static final int SIZE = 0x4d4d;
+
+    private static Random random = RandomFactory.getRandom();
+
+    public static void main(String... args) throws IOException {
+        byte[] buf = new byte[SIZE];
+        random.nextBytes(buf);
+        int position = random.nextInt(SIZE/2);
+        int size = random.nextInt(SIZE - position);
+
+        ByteArrayInputStream bais =
+            new ByteArrayInputStream(buf, position, size);
+        int off = random.nextInt(size / 2);
+        int len = random.nextInt(size - off);
+
+        byte[] bN = new byte[off + len];
+        if (bais.readNBytes(bN, off, len) != len) {
+            throw new RuntimeException("readNBytes return value");
+        }
+        if (!Arrays.equals(bN, off, off + len,
+            buf, position, position + len)) {
+            throw new RuntimeException("readNBytes content");
+        }
+
+        byte[] bAll = bais.readAllBytes();
+        Objects.requireNonNull(bAll, "readAllBytes return value");
+        if (bAll.length != size - len) {
+            throw new RuntimeException("readAllBytes return value length");
+        }
+        if (!Arrays.equals(bAll, 0, bAll.length,
+            buf, position + len, position + len + bAll.length)) {
+            throw new RuntimeException("readAllBytes content");
+        }
+
+        // XXX transferTo()
+        bais = new ByteArrayInputStream(buf);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(buf.length);
+        if (bais.transferTo(baos) != buf.length) {
+            throw new RuntimeException("transferTo return value length");
+        }
+        if (!Arrays.equals(buf, baos.toByteArray())) {
+            throw new RuntimeException("transferTo content");
+        }
+    }
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/java/nio/Buffer/EqualsCompareTest.java
--- a/test/jdk/java/nio/Buffer/EqualsCompareTest.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/test/jdk/java/nio/Buffer/EqualsCompareTest.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -45,7 +45,7 @@
 
 /*
  * @test
- * @bug 8193085
+ * @bug 8193085 8199773
  * @summary tests for buffer equals and compare
  * @run testng EqualsCompareTest
  */
@@ -120,8 +120,9 @@
         abstract T construct(int length, ByteOrder bo);
 
         @SuppressWarnings("unchecked")
-        T slice(T a, int from, int to) {
-            return (T) a.position(from).limit(to).slice();
+        T slice(T a, int from, int to, boolean dupOtherwiseSlice) {
+            a = (T) a.position(from).limit(to);
+            return (T) (dupOtherwiseSlice ? a.duplicate() : a.slice());
         }
 
         @SuppressWarnings("unchecked")
@@ -607,60 +608,62 @@
                         BiFunction bConstructor) {
         int n = arraySizeFor(bt.elementType);
 
-        for (int s : ranges(0, n)) {
-            B a = aConstructor.apply(bt, s);
-            B b = bConstructor.apply(bt, s);
+        for (boolean dupOtherwiseSlice : new boolean[]{ false, true }) {
+            for (int s : ranges(0, n)) {
+                B a = aConstructor.apply(bt, s);
+                B b = bConstructor.apply(bt, s);
 
-            for (int aFrom : ranges(0, s)) {
-                for (int aTo : ranges(aFrom, s)) {
-                    int aLength = aTo - aFrom;
+                for (int aFrom : ranges(0, s)) {
+                    for (int aTo : ranges(aFrom, s)) {
+                        int aLength = aTo - aFrom;
 
-                    B as = aLength != s
-                           ? bt.slice(a, aFrom, aTo)
-                           : a;
+                        B as = aLength != s
+                               ? bt.slice(a, aFrom, aTo, dupOtherwiseSlice)
+                               : a;
 
-                    for (int bFrom : ranges(0, s)) {
-                        for (int bTo : ranges(bFrom, s)) {
-                            int bLength = bTo - bFrom;
+                        for (int bFrom : ranges(0, s)) {
+                            for (int bTo : ranges(bFrom, s)) {
+                                int bLength = bTo - bFrom;
+
+                                B bs = bLength != s
+                                       ? bt.slice(b, bFrom, bTo, dupOtherwiseSlice)
+                                       : b;
 
-                            B bs = bLength != s
-                                   ? bt.slice(b, bFrom, bTo)
-                                   : b;
+                                boolean eq = bt.pairWiseEquals(as, bs);
+                                Assert.assertEquals(bt.equals(as, bs), eq);
+                                Assert.assertEquals(bt.equals(bs, as), eq);
+                                if (eq) {
+                                    Assert.assertEquals(bt.compare(as, bs), 0);
+                                    Assert.assertEquals(bt.compare(bs, as), 0);
+                                }
+                                else {
+                                    int aCb = bt.compare(as, bs);
+                                    int bCa = bt.compare(bs, as);
+                                    int v = Integer.signum(aCb) * Integer.signum(bCa);
+                                    Assert.assertTrue(v == -1);
+                                }
+                            }
+                        }
 
-                            boolean eq = bt.pairWiseEquals(as, bs);
-                            Assert.assertEquals(bt.equals(as, bs), eq);
-                            Assert.assertEquals(bt.equals(bs, as), eq);
-                            if (eq) {
-                                Assert.assertEquals(bt.compare(as, bs), 0);
-                                Assert.assertEquals(bt.compare(bs, as), 0);
-                            }
-                            else {
-                                int aCb = bt.compare(as, bs);
-                                int bCa = bt.compare(bs, as);
-                                int v = Integer.signum(aCb) * Integer.signum(bCa);
+                        if (aLength > 0 && !a.isReadOnly()) {
+                            for (int i = aFrom; i < aTo; i++) {
+                                B c = aConstructor.apply(bt, a.capacity());
+                                B cs = aLength != s
+                                       ? bt.slice(c, aFrom, aTo, dupOtherwiseSlice)
+                                       : c;
+
+                                // Create common prefix with a length of i - aFrom
+                                bt.set(c, i, -1);
+
+                                Assert.assertFalse(bt.equals(c, a));
+
+                                int cCa = bt.compare(cs, as);
+                                int aCc = bt.compare(as, cs);
+                                int v = Integer.signum(cCa) * Integer.signum(aCc);
                                 Assert.assertTrue(v == -1);
                             }
                         }
                     }
-
-                    if (aLength > 0 && !a.isReadOnly()) {
-                        for (int i = aFrom; i < aTo; i++) {
-                            B c = aConstructor.apply(bt, a.capacity());
-                            B cs = aLength != s
-                                   ? bt.slice(c, aFrom, aTo)
-                                   : c;
-
-                            // Create common prefix with a length of i - aFrom
-                            bt.set(c, i, -1);
-
-                            Assert.assertFalse(bt.equals(c, a));
-
-                            int cCa = bt.compare(cs, as);
-                            int aCc = bt.compare(as, cs);
-                            int v = Integer.signum(cCa) * Integer.signum(aCc);
-                            Assert.assertTrue(v == -1);
-                        }
-                    }
                 }
             }
         }
diff -r eb72d194235c -r 514c68575523 test/jdk/java/nio/channels/DatagramChannel/Connect.java
--- a/test/jdk/java/nio/channels/DatagramChannel/Connect.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/test/jdk/java/nio/channels/DatagramChannel/Connect.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -102,7 +102,7 @@
                 try {
                     dc.send(bb, bogus);
                     throw new RuntimeException("Allowed bogus send while connected");
-                } catch (IllegalArgumentException iae) {
+                } catch (AlreadyConnectedException ace) {
                     // Correct behavior
                 }
 
diff -r eb72d194235c -r 514c68575523 test/jdk/java/nio/channels/DatagramChannel/ConnectExceptions.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/channels/DatagramChannel/ConnectExceptions.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2018, 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 8198753
+ * @summary Test DatagramChannel connect exceptions
+ * @library ..
+ * @run testng ConnectExceptions
+ */
+
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+import java.nio.channels.*;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class ConnectExceptions {
+    static DatagramChannel sndChannel;
+    static DatagramChannel rcvChannel;
+    static InetSocketAddress sender;
+    static InetSocketAddress receiver;
+
+    @BeforeTest
+    public static void setup() throws Exception {
+        sndChannel = DatagramChannel.open();
+        sndChannel.bind(null);
+        InetAddress address = InetAddress.getLocalHost();
+        if (address.isLoopbackAddress()) {
+            address = InetAddress.getLoopbackAddress();
+        }
+        sender = new InetSocketAddress(address,
+            sndChannel.socket().getLocalPort());
+
+        rcvChannel = DatagramChannel.open();
+        rcvChannel.bind(null);
+        receiver = new InetSocketAddress(address,
+            rcvChannel.socket().getLocalPort());
+    }
+
+    @Test(expectedExceptions = UnsupportedAddressTypeException.class)
+    public static void unsupportedAddressTypeException() throws Exception {
+        rcvChannel.connect(sender);
+        sndChannel.connect(new SocketAddress() {});
+    }
+
+    @Test(expectedExceptions = UnresolvedAddressException.class)
+    public static void unresolvedAddressException() throws Exception {
+        String host = TestUtil.UNRESOLVABLE_HOST;
+        InetSocketAddress unresolvable = new InetSocketAddress (host, 37);
+        sndChannel.connect(unresolvable);
+    }
+
+    @Test(expectedExceptions = AlreadyConnectedException.class)
+    public static void alreadyConnectedException() throws Exception {
+        sndChannel.connect(receiver);
+        InetSocketAddress random = new InetSocketAddress(0);
+        sndChannel.connect(random);
+    }
+
+    @AfterTest
+    public static void cleanup() throws Exception {
+        rcvChannel.close();
+        sndChannel.close();
+    }
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/java/nio/channels/DatagramChannel/ConnectedSend.java
--- a/test/jdk/java/nio/channels/DatagramChannel/ConnectedSend.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/test/jdk/java/nio/channels/DatagramChannel/ConnectedSend.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -24,6 +24,8 @@
 /* @test
  * @bug 4849277 7183800
  * @summary Test DatagramChannel send while connected
+ * @library ..
+ * @run testng ConnectedSend
  * @author Mike McCloskey
  */
 
@@ -32,20 +34,16 @@
 import java.nio.*;
 import java.nio.channels.*;
 import java.nio.charset.*;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
 
 public class ConnectedSend {
-
-    public static void main(String[] args) throws Exception {
-        test1();
-        test2();
-    }
-
     // Check if DatagramChannel.send while connected can include
     // address without throwing
-    private static void test1() throws Exception {
-
+    @Test
+    public static void sendToConnectedAddress() throws Exception {
         DatagramChannel sndChannel = DatagramChannel.open();
-        sndChannel.socket().bind(null);
+        sndChannel.bind(null);
         InetAddress address = InetAddress.getLocalHost();
         if (address.isLoopbackAddress()) {
             address = InetAddress.getLoopbackAddress();
@@ -55,7 +53,7 @@
             sndChannel.socket().getLocalPort());
 
         DatagramChannel rcvChannel = DatagramChannel.open();
-        rcvChannel.socket().bind(null);
+        rcvChannel.bind(null);
         InetSocketAddress receiver = new InetSocketAddress(
             address,
             rcvChannel.socket().getLocalPort());
@@ -71,8 +69,7 @@
         rcvChannel.receive(bb);
         bb.flip();
         CharBuffer cb = Charset.forName("US-ASCII").newDecoder().decode(bb);
-        if (!cb.toString().startsWith("h"))
-            throw new RuntimeException("Test failed");
+        assertTrue(cb.toString().startsWith("h"), "Unexpected message content");
 
         rcvChannel.close();
         sndChannel.close();
@@ -81,9 +78,10 @@
     // Check if the datagramsocket adaptor can send with a packet
     // that has not been initialized with an address; the legacy
     // datagram socket will send in this case
-    private static void test2() throws Exception {
+    @Test
+    public static void sendAddressedPacket() throws Exception {
         DatagramChannel sndChannel = DatagramChannel.open();
-        sndChannel.socket().bind(null);
+        sndChannel.bind(null);
         InetAddress address = InetAddress.getLocalHost();
         if (address.isLoopbackAddress()) {
             address = InetAddress.getLoopbackAddress();
@@ -93,7 +91,7 @@
             sndChannel.socket().getLocalPort());
 
         DatagramChannel rcvChannel = DatagramChannel.open();
-        rcvChannel.socket().bind(null);
+        rcvChannel.bind(null);
         InetSocketAddress receiver = new InetSocketAddress(
             address,
             rcvChannel.socket().getLocalPort());
@@ -109,13 +107,12 @@
         rcvChannel.receive(bb);
         bb.flip();
         CharBuffer cb = Charset.forName("US-ASCII").newDecoder().decode(bb);
-        if (!cb.toString().startsWith("h"))
-            throw new RuntimeException("Test failed");
+        assertTrue(cb.toString().startsWith("h"), "Unexpected message content");
 
         // Check that the pkt got set with the target address;
         // This is legacy behavior
-        if (!pkt.getSocketAddress().equals(receiver))
-            throw new RuntimeException("Test failed");
+        assertEquals(pkt.getSocketAddress(), receiver,
+            "Unexpected address set on packet");
 
         rcvChannel.close();
         sndChannel.close();
diff -r eb72d194235c -r 514c68575523 test/jdk/java/nio/channels/DatagramChannel/SendExceptions.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/channels/DatagramChannel/SendExceptions.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2018, 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 4675045 8198753
+ * @summary Test DatagramChannel send exceptions
+ * @library ..
+ * @run testng SendExceptions
+ */
+
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+import java.nio.channels.*;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class SendExceptions {
+    static DatagramChannel sndChannel;
+    static DatagramChannel rcvChannel;
+    static InetSocketAddress sender;
+    static InetSocketAddress receiver;
+    static ByteBuffer buf = ByteBuffer.allocate(17);
+
+    @BeforeTest
+    public static void setup() throws Exception {
+        sndChannel = DatagramChannel.open();
+        sndChannel.bind(null);
+        InetAddress address = InetAddress.getLocalHost();
+        if (address.isLoopbackAddress()) {
+            address = InetAddress.getLoopbackAddress();
+        }
+        sender = new InetSocketAddress(address,
+            sndChannel.socket().getLocalPort());
+
+        rcvChannel = DatagramChannel.open();
+        rcvChannel.bind(null);
+        receiver = new InetSocketAddress(address,
+            rcvChannel.socket().getLocalPort());
+    }
+
+    @Test(expectedExceptions = UnsupportedAddressTypeException.class)
+    public static void unsupportedAddressTypeException() throws Exception {
+        rcvChannel.connect(sender);
+        sndChannel.send(buf, new SocketAddress() {});
+    }
+
+    @Test(expectedExceptions = UnresolvedAddressException.class)
+    public static void unresolvedAddressException() throws Exception {
+        String host = TestUtil.UNRESOLVABLE_HOST;
+        InetSocketAddress unresolvable = new InetSocketAddress (host, 37);
+        sndChannel.send(buf, unresolvable);
+    }
+
+    @Test(expectedExceptions = AlreadyConnectedException.class)
+    public static void alreadyConnectedException() throws Exception {
+        sndChannel.connect(receiver);
+        InetSocketAddress random = new InetSocketAddress(0);
+        sndChannel.send(buf, random);
+    }
+
+    @AfterTest
+    public static void cleanup() throws Exception {
+        rcvChannel.close();
+        sndChannel.close();
+    }
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/java/nio/channels/DatagramChannel/SendToUnresolved.java
--- a/test/jdk/java/nio/channels/DatagramChannel/SendToUnresolved.java	Fri Mar 23 18:01:52 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4675045
- * @summary Test DatagramChannel send to unresolved address
- * @library ..
- */
-
-import java.io.*;
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
-
-public class SendToUnresolved {
-    public static void main(String [] argv) throws Exception {
-        String host = TestUtil.UNRESOLVABLE_HOST;
-        DatagramChannel dc = DatagramChannel.open();
-        ByteBuffer bb = ByteBuffer.allocate(4);
-        InetSocketAddress sa = new InetSocketAddress (host, 37);
-        InetAddress inetaddr = sa.getAddress();
-        try {
-            dc.send(bb, sa);
-            throw new RuntimeException("Expected exception not thrown");
-        } catch (IOException | UnresolvedAddressException e) {
-            // Correct result
-        }
-        dc.close();
-    }
-}
diff -r eb72d194235c -r 514c68575523 test/jdk/java/nio/channels/Selector/CloseWhenKeyIdle.java
--- a/test/jdk/java/nio/channels/Selector/CloseWhenKeyIdle.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/test/jdk/java/nio/channels/Selector/CloseWhenKeyIdle.java	Fri Mar 23 18:44:47 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, 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
@@ -62,22 +62,6 @@
 
     public static void main(String[] args) throws Exception {
 
-        // Skip test on pre-2.6 kernels until the poll SelectorProvider
-        // is updated
-        String osname = System.getProperty("os.name");
-        if (osname.equals("Linux")) {
-            String[] ver = System.getProperty("os.version").split("\\.", 0);
-            if (ver.length >=2 ) {
-                int major = Integer.parseInt(ver[0]);
-                int minor = Integer.parseInt(ver[1]);
-                if (major < 2 || (major == 2 && minor < 6)) {
-                    System.out.println("Test passing on pre-2.6 kernel");
-                    return;
-                }
-            }
-        }
-
-
         // establish loopback connection
 
         ServerSocketChannel ssc = ServerSocketChannel.open();
diff -r eb72d194235c -r 514c68575523 test/jdk/java/util/Collection/MOAT.java
--- a/test/jdk/java/util/Collection/MOAT.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/test/jdk/java/util/Collection/MOAT.java	Fri Mar 23 18:44:47 2018 +0000
@@ -26,7 +26,7 @@
  * @bug     6207984 6272521 6192552 6269713 6197726 6260652 5073546 4137464
  *          4155650 4216399 4294891 6282555 6318622 6355327 6383475 6420753
  *          6431845 4802633 6570566 6570575 6570631 6570924 6691185 6691215
- *          4802647 7123424 8024709
+ *          4802647 7123424 8024709 8193128
  * @summary Run many tests on many Collection and Map implementations
  * @author  Martin Buchholz
  * @modules java.base/java.util:open
@@ -212,8 +212,11 @@
 
         // Immutable List
         testEmptyList(List.of());
+        testEmptyList(List.of().subList(0,0));
         testListMutatorsAlwaysThrow(List.of());
+        testListMutatorsAlwaysThrow(List.of().subList(0,0));
         testEmptyListMutatorsAlwaysThrow(List.of());
+        testEmptyListMutatorsAlwaysThrow(List.of().subList(0,0));
         for (List list : Arrays.asList(
                 List.of(),
                 List.of(1),
@@ -230,6 +233,17 @@
             testCollection(list);
             testImmutableList(list);
             testListMutatorsAlwaysThrow(list);
+            if (list.size() >= 1) {
+                // test subLists
+                List headList = list.subList(0, list.size() - 1);
+                List tailList = list.subList(1, list.size());
+                testCollection(headList);
+                testCollection(tailList);
+                testImmutableList(headList);
+                testImmutableList(tailList);
+                testListMutatorsAlwaysThrow(headList);
+                testListMutatorsAlwaysThrow(tailList);
+            }
         }
 
         List listCopy = List.copyOf(Arrays.asList(1, 2, 3));
@@ -243,6 +257,44 @@
         testImmutableList(listCollected);
         testListMutatorsAlwaysThrow(listCollected);
 
+        // List indexOf / lastIndexOf
+
+        // 0 element
+        System.out.println("testListIndexOf size 0");
+        testListIndexOf(-1, -1);
+
+        System.out.println("testListIndexOf size 1");
+        testListIndexOf(-1, -1, 0);
+        testListIndexOf(0, 0, 1);
+
+        System.out.println("testListIndexOf size 2");
+        testListIndexOf(-1, -1, 0, 0);
+        testListIndexOf(0, 0, 1, 0);
+        testListIndexOf(0, 1, 1, 1);
+        testListIndexOf(1, 1, 0, 1);
+
+
+        System.out.println("testListIndexOf size 3");
+        testListIndexOf(-1, -1, 0, 0, 0);
+        testListIndexOf(0, 0, 1, 0, 0);
+        testListIndexOf(0, 1, 1, 1, 0);
+        testListIndexOf(1, 2, 0, 1, 1);
+        testListIndexOf(2, 2, 0, 0, 1);
+
+        System.out.println("testListIndexOf size N");
+        testListIndexOf(-1, -1, 0, 0, 0, 0, 0, 0, 0);
+        testListIndexOf(2, 6, 0, 0, 1, 0, 1, 0, 1);
+        testListIndexOf(4, 4, 0, 0, 0, 0, 1, 0, 0);
+        testListIndexOf(0, 6, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 7, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
+        testListIndexOf(-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
         // Immutable Set
         testEmptySet(Set.of());
         testCollMutatorsAlwaysThrow(Set.of());
@@ -963,6 +1015,37 @@
         equal(it.next(), 4);
     }
 
+    // for any array of integer values, check that the result of lastIndexOf(1)
+    // and indexOf(1) match assumptions for all types of List we can
+    // construct
+    private static void testListIndexOf(final int index,
+                                        final int lastIndex,
+                                        final Integer ... values) {
+        if (values.length == 0) {
+            checkListIndexOf(emptyList(), index, lastIndex);
+        } else if (values.length == 1) {
+            checkListIndexOf(singletonList(values[0]), index, lastIndex);
+            checkListIndexOf(nCopies(25, values[0]), index, lastIndex == 0 ? 24 : -1);
+        }
+        List l = List.of(values);
+        checkListIndexOf(l, index, lastIndex);
+        checkListIndexOf(Arrays.asList(values), index, lastIndex);
+        checkListIndexOf(new ArrayList(l), index, lastIndex);
+        checkListIndexOf(new LinkedList(l), index, lastIndex);
+        checkListIndexOf(new Vector(l), index, lastIndex);
+        checkListIndexOf(new CopyOnWriteArrayList(l), index, lastIndex);
+    }
+
+    private static void checkListIndexOf(final List list,
+                                         final int index,
+                                         final int lastIndex) {
+        String msg = list.getClass().toString();
+        equal(list.indexOf(1), index, msg);
+        equal(list.lastIndexOf(1), lastIndex, msg);
+        equal(list.subList(0, list.size()).indexOf(1), index, msg);
+        equal(list.subList(0, list.size()).lastIndexOf(1), lastIndex, msg);
+    }
+
     private static void testList(final List l) {
         //----------------------------------------------------------------
         // 4802633: (coll) AbstractList.addAll(-1,emptyCollection)
@@ -1629,6 +1712,9 @@
     static void equal(Object x, Object y) {
         if (x == null ? y == null : x.equals(y)) pass();
         else {System.out.println(x + " not equal to " + y); fail();}}
+    static void equal(Object x, Object y, String msg) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else {System.out.println(x + " not equal to " + y + " : " + msg); fail();}}
     static void equal2(Object x, Object y) {equal(x, y); equal(y, x);}
     public static void main(String[] args) throws Throwable {
         try { realMain(args); } catch (Throwable t) { unexpected(t); }
diff -r eb72d194235c -r 514c68575523 test/jdk/java/util/Collection/SetFactories.java
--- a/test/jdk/java/util/Collection/SetFactories.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/test/jdk/java/util/Collection/SetFactories.java	Fri Mar 23 18:44:47 2018 +0000
@@ -266,6 +266,11 @@
         Set.of((Object[])null);
     }
 
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void containsNullShouldThrowNPE(Set act, Set exp) {
+        act.contains(null);
+    }
+
     @Test(dataProvider="all")
     public void serialEquality(Set act, Set exp) {
         // assume that act.equals(exp) tested elsewhere
diff -r eb72d194235c -r 514c68575523 test/jdk/java/util/List/ListFactories.java
--- a/test/jdk/java/util/List/ListFactories.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/test/jdk/java/util/List/ListFactories.java	Fri Mar 23 18:44:47 2018 +0000
@@ -26,6 +26,7 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -72,7 +73,7 @@
     @DataProvider(name="empty")
     public Iterator empty() {
         return Collections.singletonList(
-            a(List.of(), Collections.emptyList())
+            a(List.of(), asList())
         ).iterator();
     }
 
@@ -104,11 +105,50 @@
         ).iterator();
     }
 
+    @DataProvider(name="sublists")
+    public Iterator sublists() {
+        return asList(
+            a(List.of().subList(0,0),
+               asList()),
+            a(List.of("a").subList(0,0),
+               asList("a").subList(0,0)),
+            a(List.of("a", "b").subList(0,1),
+               asList("a", "b").subList(0,1)),
+            a(List.of("a", "b", "c").subList(1,3),
+               asList("a", "b", "c").subList(1,3)),
+            a(List.of("a", "b", "c", "d").subList(0,4),
+               asList("a", "b", "c", "d").subList(0,4)),
+            a(List.of("a", "b", "c", "d", "e").subList(0,3),
+               asList("a", "b", "c", "d", "e").subList(0,3)),
+            a(List.of("a", "b", "c", "d", "e", "f").subList(3, 5),
+               asList("a", "b", "c", "d", "e", "f").subList(3, 5)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g").subList(0, 7),
+               asList("a", "b", "c", "d", "e", "f", "g").subList(0, 7)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h").subList(0, 0),
+               asList("a", "b", "c", "d", "e", "f", "g", "h").subList(0, 0)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i").subList(4, 5),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i").subList(4, 5)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j").subList(1,10),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j").subList(1,10)),
+            a(List.of(stringArray).subList(5, NUM_STRINGS),
+               asList(Arrays.copyOfRange(stringArray, 5, NUM_STRINGS)))
+                ).iterator();
+    }
+
     @DataProvider(name="all")
     public Iterator all() {
         List all = new ArrayList<>();
         empty().forEachRemaining(all::add);
         nonempty().forEachRemaining(all::add);
+        sublists().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @DataProvider(name="nonsublists")
+    public Iterator nonsublists() {
+        List all = new ArrayList<>();
+        empty().forEachRemaining(all::add);
+        nonempty().forEachRemaining(all::add);
         return all.iterator();
     }
 
@@ -212,7 +252,29 @@
         assertEquals(list, Arrays.asList(stringArray));
     }
 
-    @Test(dataProvider="all")
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void containsNullShouldThrowNPE(List act, List exp) {
+        act.contains(null);
+    }
+
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void indexOfNullShouldThrowNPE(List act, List exp) {
+        act.indexOf(null);
+    }
+
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void lastIndexOfNullShouldThrowNPE(List act, List exp) {
+        act.lastIndexOf(null);
+    }
+
+    // List.of().subList views should not be Serializable
+    @Test(dataProvider="sublists")
+    public void isNotSerializable(List act, List exp) {
+        assertFalse(act instanceof Serializable);
+    }
+
+    // ... but List.of() should be
+    @Test(dataProvider="nonsublists")
     public void serialEquality(List act, List exp) {
         // assume that act.equals(exp) tested elsewhere
         List copy = serialClone(act);
diff -r eb72d194235c -r 514c68575523 test/jdk/java/util/Locale/LocaleCmdOverrides.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/Locale/LocaleCmdOverrides.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.List;
+
+/*
+ * @test
+ * @modules java.management
+ * @summary verify that overriddes on the command line affect *.display and *.format properties
+ * @run main/othervm
+ *          LocaleCmdOverrides
+ * @run main/othervm -Duser.language=XX
+ *                   -Duser.country=X1
+ *                   -Duser.script=X2
+ *                   -Duser.variant=X3
+ *          LocaleCmdOverrides
+ * @run main/othervm -Duser.language=XX -Duser.language.display=YY
+ *                   -Duser.country=X1 -Duser.country.display=Y1
+ *                   -Duser.script=X2 -Duser.script.display=Y2
+ *                   -Duser.variant=X3 -Duser.variant.display=Y3
+ *          LocaleCmdOverrides
+ * @run main/othervm -Duser.language=XX -Duser.language.display=YY -Duser.language.format=ZZ
+ *                   -Duser.country=X1 -Duser.country.display=Y1 -Duser.country.format=Z1
+ *                   -Duser.script=X2 -Duser.script.display=Y2 -Duser.script.format=Z2
+ *                   -Duser.variant=X3 -Duser.variant.display=Y3 -Duser.variant.format=Z3
+ *          LocaleCmdOverrides
+ * @run main/othervm -Duser.language=XX -Duser.language.format=ZZ
+ *                   -Duser.country=X1 -Duser.country.format=Z1
+ *                   -Duser.script=X2 -Duser.script.format=Z2
+ *                   -Duser.variant=X3 -Duser.variant.format=Z3
+ *          LocaleCmdOverrides
+ * @run main/othervm -Duser.language=XX -Duser.language.display=XX
+ *                   -Duser.country=X1 -Duser.country.display=X1
+ *                   -Duser.script=X2 -Duser.script.display=X2
+ *                   -Duser.variant=X3 -Duser.variant.display=X3
+ *          LocaleCmdOverrides
+ * @run main/othervm -Duser.language=XX -Duser.language.display=XX -Duser.language.format=XX
+ *                   -Duser.country=X1 -Duser.country.display=X1 -Duser.country.format=X1
+ *                   -Duser.script=X2 -Duser.script.display=X2 -Duser.script.format=X2
+ *                   -Duser.variant=X3 -Duser.variant.display=X3 -Duser.variant.format=X3
+ *          LocaleCmdOverrides
+ * @run main/othervm -Duser.language=XX -Duser.language.format=X1
+ *                   -Duser.country.format=X1
+ *                   -Duser.script.format=X2
+ *                   -Duser.variant.format=X3
+ *          LocaleCmdOverrides
+ */
+public class LocaleCmdOverrides {
+
+    // Language, country, script, variant
+
+    public static void main(String[] args) {
+        Map props = commandLineDefines();
+        System.out.printf("props: %s%n", props);
+        test("user.language", props);
+        test("user.country", props);
+        test("user.script", props);
+        test("user.variant", props);
+    }
+
+    /*
+     * Check each of the properties for a given basename.
+     */
+    static void test(String baseName, Map args) {
+        validateArg(baseName,"",  args);
+        validateArg(baseName,".display", args);
+        validateArg(baseName,".format", args);
+    }
+
+    // If an argument is -D defined, the corresponding property must be equal
+    static void validateArg(String name, String ext, Map args) {
+        String extName = name.concat(ext);
+        String arg = args.get(extName);
+        String prop = System.getProperty(extName);
+        if (arg == null && prop == null) {
+            System.out.printf("No values for %s%n", extName);
+        } else {
+            System.out.printf("validateArg %s: arg: %s, prop: %s%n", extName, arg, prop);
+        }
+
+        if (arg != null) {
+            if (!Objects.equals(arg, prop)) {
+                throw new RuntimeException(extName + ": -D value should match property: "
+                        + arg + " != " + prop);
+            }
+        } else if (prop != null) {
+            // no command line arg for extName and some value for prop
+            // Check that if a property is not overridden then it is not equal to the base
+            if (ext != null && !ext.isEmpty()) {
+                String value = System.getProperty(name);
+                if (Objects.equals(value, prop)) {
+                    throw new RuntimeException(extName + " property should not be equals to "
+                            + name + " property: " + prop);
+                }
+            }
+        }
+    }
+
+    /**
+     * Extract the -D arguments from the command line and return a map of key, value.
+     * @return a map of key, values defined by -D on the command line.
+     */
+    static HashMap commandLineDefines() {
+        HashMap props = new HashMap<>();
+        RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
+        List args = runtime.getInputArguments();
+        System.out.printf("args: %s%n", args);
+        for (String arg : args) {
+            if (arg.startsWith("-Duser.")) {
+                String[] kv = arg.substring(2).split("=");
+                switch (kv.length) {
+                    case 1:
+                        props.put(kv[0], "");
+                        break;
+                    case 2:
+                        props.put(kv[0], kv[1]);
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Illegal property syntax: " + arg);
+                }
+            }
+        }
+        return props;
+    }
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/java/util/Map/MapFactories.java
--- a/test/jdk/java/util/Map/MapFactories.java	Fri Mar 23 18:01:52 2018 +0000
+++ b/test/jdk/java/util/Map/MapFactories.java	Fri Mar 23 18:44:47 2018 +0000
@@ -376,6 +376,16 @@
         Map.ofEntries((Map.Entry[])null);
     }
 
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void containsValueNullShouldThrowNPE(Map act, Map exp) {
+        act.containsValue(null);
+    }
+
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void containsKeyNullShouldThrowNPE(Map act, Map exp) {
+        act.containsKey(null);
+    }
+
     @Test(dataProvider="all")
     public void serialEquality(Map act, Map exp) {
         // assume that act.equals(exp) tested elsewhere
diff -r eb72d194235c -r 514c68575523 test/jdk/javax/imageio/plugins/bmp/DIB_size-56_ARGB_16bits.bmp
Binary file test/jdk/javax/imageio/plugins/bmp/DIB_size-56_ARGB_16bits.bmp has changed
diff -r eb72d194235c -r 514c68575523 test/jdk/javax/imageio/plugins/bmp/DIB_size-56_RGB_16bits.bmp
Binary file test/jdk/javax/imageio/plugins/bmp/DIB_size-56_RGB_16bits.bmp has changed
diff -r eb72d194235c -r 514c68575523 test/jdk/javax/imageio/plugins/bmp/DIB_size-56_XRGB_32bits.bmp
Binary file test/jdk/javax/imageio/plugins/bmp/DIB_size-56_XRGB_32bits.bmp has changed
diff -r eb72d194235c -r 514c68575523 test/jdk/javax/imageio/plugins/bmp/ReadBITMAPV3INFOHEADERTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/imageio/plugins/bmp/ReadBITMAPV3INFOHEADERTest.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018, 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     7031957
+ * @summary Test verifies whether BMPImageReader is capable of reading
+ *          images with DIB header type BITMAPV3INFOHEADER.
+ * @run     main ReadBITMAPV3INFOHEADERTest
+ */
+
+import javax.imageio.ImageIO;
+import java.io.File;
+import java.io.IOException;
+
+public class ReadBITMAPV3INFOHEADERTest {
+    public static void main(String[] args) throws IOException {
+        String dir = System.getProperty("test.src");
+        String sep = System.getProperty("file.separator");
+        /*
+         * Try reading BITMAPV3INFOHEADER type BMP images and check whether
+         * read fails. If read fails we throw Exception.
+         */
+        ImageIO.read(new File(dir + sep + "DIB_size-56_ARGB_16bits.bmp"));
+        ImageIO.read(new File(dir + sep + "DIB_size-56_RGB_16bits.bmp"));
+        ImageIO.read(new File(dir + sep + "DIB_size-56_XRGB_32bits.bmp"));
+    }
+}
+
diff -r eb72d194235c -r 514c68575523 test/jdk/javax/imageio/plugins/gif/GIFCharCellDimensionTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/imageio/plugins/gif/GIFCharCellDimensionTest.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2018, 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 6686236
+ * @summary Checks whether GIF native metadata format returns appropriate max
+ *          value that could be set for characterCellWidth and
+ *          characterCellHeight attributes of PlainTextExtension node. Besides,
+ *          the test also checks whether IIOInvalidTreeException is thrown when
+ *          incorrect value is set on these two attributes.
+ * @run main GIFCharCellDimensionTest
+ */
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.metadata.IIOInvalidTreeException;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataNode;
+import javax.imageio.metadata.IIOMetadataFormat;
+import java.util.Iterator;
+import java.awt.image.BufferedImage;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
+
+public class GIFCharCellDimensionTest {
+    // GIF image metadata and native metadata format.
+    private static IIOMetadata imageMetadata = null;
+    private static IIOMetadataFormat metadataFormat = null;
+    private static String formatName = null;
+
+    private static void initializeTest() {
+        // Initialize the test case by querying GIF image writer for default
+        // image metadata and native metadata format.
+        ImageWriter gifWriter = null;
+        Iterator iterGifWriter = null;
+        BufferedImage bufImage = null;
+        ImageTypeSpecifier imageType = null;
+
+        try {
+            iterGifWriter = ImageIO.getImageWritersBySuffix("GIF");
+            if (iterGifWriter.hasNext()) {
+                gifWriter = iterGifWriter.next();
+                bufImage = new BufferedImage(32, 32, TYPE_4BYTE_ABGR);
+
+                // Get GIF image metadata
+                imageMetadata = gifWriter.getDefaultImageMetadata(
+                        ImageTypeSpecifier.createFromRenderedImage(bufImage),
+                        gifWriter.getDefaultWriteParam());
+                if (imageMetadata == null) {
+                    reportException("Test Failed. Could not get image" +
+                            " metadata.");
+                }
+
+                // Get GIF native metadata format.
+                formatName = imageMetadata.getNativeMetadataFormatName();
+                metadataFormat = imageMetadata.getMetadataFormat(formatName);
+                if (metadataFormat == null) {
+                    reportException("Test Failed. Could not get native" +
+                            " metadata format.");
+                }
+            } else {
+                reportException("Test Failed. No GIF image writer found.");
+            }
+        } finally {
+            gifWriter.dispose();
+        }
+    }
+
+    private static IIOMetadataNode createPlainTextExtensionNode(String value) {
+        // Create a PlainTextExtensionNode with required values
+        IIOMetadataNode rootNode = null;
+
+        if (imageMetadata != null && formatName != null) {
+            IIOMetadataNode plainTextNode = null;
+
+            rootNode = new IIOMetadataNode(formatName);
+            plainTextNode = new IIOMetadataNode("PlainTextExtension");
+            plainTextNode.setAttribute("textGridLeft", "0");
+            plainTextNode.setAttribute("textGridTop", "0");
+            plainTextNode.setAttribute("textGridWidth", "32");
+            plainTextNode.setAttribute("textGridHeight", "32");
+            // Set required values for cell width and cell height
+            plainTextNode.setAttribute("characterCellWidth", value);
+            plainTextNode.setAttribute("characterCellHeight", value);
+            plainTextNode.setAttribute("textForegroundColor", "0");
+            plainTextNode.setAttribute("textBackgroundColor", "1");
+            rootNode.appendChild(plainTextNode);
+        } else {
+            reportException("Test Failed. Un-initialized image metadata.");
+        }
+
+        return rootNode;
+    }
+
+    private static void testCharacterCellDimensions() {
+        if (imageMetadata != null && metadataFormat != null) {
+            // Get max permissible value that could be set on characterCellWidth
+            // and characterCellHeight attributes of plain text node.
+            String cellWidth = metadataFormat.getAttributeMaxValue(
+                    "PlainTextExtension",
+                    "characterCellWidth");
+            String cellHeight = metadataFormat.getAttributeMaxValue(
+                    "PlainTextExtension",
+                    "characterCellHeight");
+
+            // Test fails if the max permissible value is larger than 255
+            int maxCharCellWidth = Integer.parseInt(cellWidth);
+            int maxCharCellHeight = Integer.parseInt(cellHeight);
+            if (maxCharCellWidth > 255 || maxCharCellHeight > 255) {
+                reportException("Test Failed. Invalid max range for" +
+                        " character cell width or character cell height.");
+            }
+
+            try {
+                // Merge a plain text node with incorrect value set on
+                // characterCellWidth and characterCellHeight attributes.
+                IIOMetadataNode root = createPlainTextExtensionNode("256");
+                imageMetadata.setFromTree(formatName, root);
+            } catch (IIOInvalidTreeException exception) {
+                // No-op. Expected exception was thrown.
+            }
+        } else {
+            reportException("Test Failed. Un-initialized image metadata or" +
+                    " metadata format.");
+        }
+    }
+
+    private static void reportException(String message) {
+        // Report an exception with the required message.
+        throw new RuntimeException(message);
+    }
+
+    public static void main(String[] args) {
+        // Initialize the test
+        initializeTest();
+
+        // Test plain text extension node.
+        testCharacterCellDimensions();
+    }
+}
\ No newline at end of file
diff -r eb72d194235c -r 514c68575523 test/jdk/javax/swing/JEditorPane/8195095/ImageViewTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/swing/JEditorPane/8195095/ImageViewTest.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2018, 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
+ * @key headful
+ * @bug 8195095
+ * @summary Tests if Images are scaled correctly in JEditorPane.
+ * @run main ImageViewTest
+ */
+import java.awt.Robot;
+import java.awt.Point;
+import java.awt.Color;
+import java.awt.Insets;
+
+import javax.swing.JEditorPane;
+import javax.swing.SwingUtilities;
+import javax.swing.JFrame;
+import javax.swing.WindowConstants;
+
+public class ImageViewTest {
+
+    private static final int WIDTH = 200;
+    private static final int HEIGHT = 200;
+    private static JFrame f;
+
+    private static JEditorPane editorPane1;
+    private static JEditorPane editorPane2;
+    private static JEditorPane editorPane3;
+    private static JEditorPane editorPane4;
+
+    private static void test(Robot r, JEditorPane editorPane)  throws Exception {
+
+        SwingUtilities.invokeAndWait(() -> {
+            f = new JFrame();
+            editorPane.setEditable(false);
+            f.add(editorPane);
+            f.setSize(220,240);
+            f.setLocationRelativeTo(null);
+
+            f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+            f.setVisible(true);
+        });
+
+        r.waitForIdle();
+        r.delay(500);
+
+        SwingUtilities.invokeAndWait(() -> {
+            Insets insets = editorPane.getInsets();
+            Point loc = editorPane.getLocationOnScreen();
+
+            final Color blue = Color.BLUE;
+            final int offset = 10;
+
+            Color center = r.getPixelColor(loc.x + insets.left + WIDTH / 2,
+                                            loc.y + insets.top + HEIGHT / 2);
+            Color left = r.getPixelColor(loc.x + insets.left + offset,
+                                            loc.y + insets.top + HEIGHT / 2);
+            Color right = r.getPixelColor(loc.x + insets.left + WIDTH - offset,
+                                            loc.y + insets.top + HEIGHT / 2);
+            Color bottom = r.getPixelColor(loc.x + insets.left + WIDTH / 2,
+                                            loc.y + insets.top + HEIGHT - offset);
+            Color top = r.getPixelColor(loc.x + insets.left + WIDTH / 2,
+                                            loc.y + insets.top + offset);
+
+            f.dispose();
+
+            System.out.println("center color: " + center);
+            System.out.println("left color: " + left);
+            System.out.println("right color: " + right);
+            System.out.println("bottom color: " + bottom);
+            System.out.println("top color: " + top);
+            System.out.println();
+
+            if (!(blue.equals(center) && blue.equals(left) && blue.equals(right) &&
+                    blue.equals(top) && blue.equals(bottom))) {
+                throw new RuntimeException("Test failed: Image not scaled correctly");
+            }
+        });
+
+        r.waitForIdle();
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        final String ABSOLUTE_FILE_PATH = ImageViewTest.class.getResource("circle.png").getPath();
+
+        System.out.println(ABSOLUTE_FILE_PATH);
+
+        Robot r = new Robot();
+
+        SwingUtilities.invokeAndWait(() -> {
+            editorPane1 = new JEditorPane("text/html",
+                    "(dlm);
+                list.setSelectionMode(
+                        ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+                dlm.addElement("1");
+                dlm.addElement("2");
+
+                // Set the selection interval from 0-2 (3 elements instead
+                // of 2). The getSelectedValue should return the first
+                // selected element
+                list.setSelectionInterval(0, 2);
+                checkSelectedIndex(list, "1");
+
+                //here the smallest selection index is bigger than number of
+                // elements in list. This should return null.
+                list.setSelectionInterval(4, 5);
+                checkSelectedIndex(list,null);
+            }
+        });
+    }
+
+    static void checkSelectedIndex(JList list, Object value)
+            throws RuntimeException {
+        Object selectedObject = list.getSelectedValue();
+        if (!Objects.equals(value, selectedObject)) {
+            System.out.println("Expected: " + value);
+            System.out.println("Actual: " + selectedObject);
+            throw new RuntimeException("Wrong selection");
+        }
+    }
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/javax/swing/JList/GetSelectedValuesListTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/swing/JList/GetSelectedValuesListTest.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2018, 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
+ * @key headful
+ * @bug 7108280
+ * @summary Verifies that getSelectedValuesList works fine without crash when
+ *          the setSelectionInterval was called with indices outside the
+ *          range of data present in DataModel
+ * @run main GetSelectedValuesListTest
+ */
+
+import javax.swing.SwingUtilities;
+import javax.swing.DefaultListModel;
+import javax.swing.JList;
+import javax.swing.ListSelectionModel;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+
+public class GetSelectedValuesListTest {
+    public static void main(String[] args) throws Exception {
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                // Create a JList with 2 elements
+                DefaultListModel dlm = new DefaultListModel();
+                JList list = new JList(dlm);
+                list.setSelectionMode(
+                        ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+                dlm.addElement("1");
+                dlm.addElement("2");
+
+                // Set the selection interval from 0-2 (3 elements instead
+                // of 2). The getSelectedValuesList should return the list of
+                // objects present in the list in the given interval
+                list.setSelectionInterval(0, 2);
+                checkSelection(list, List.of("1", "2"));
+
+                //here the selection interval is set greater than number of
+                // elements in list. This should return empty list
+                list.setSelectionInterval(4, 10);
+                checkSelection(list, Collections.emptyList());
+
+                // This will set the selection interval from 0 to 2 index.
+                // The getSelectedValuesList should return the list of
+                // objects present in the list in the given interval
+                list.getSelectionModel().setSelectionInterval(0, 2);
+                checkSelection(list, List.of("1", "2"));
+            }
+        });
+    }
+
+    static void checkSelection(JList list, List selectionList)
+            throws RuntimeException
+    {
+        List listSelection = list.getSelectedValuesList();
+        if (!listSelection.equals(selectionList)) {
+            System.out.println("Expected: " + selectionList);
+            System.out.println("Actual: " + listSelection);
+            throw new RuntimeException("Wrong selection from " +
+                    "getSelectedValuesList");
+        }
+
+        Object[] arraySelection = list.getSelectedValues();
+        if (!Arrays.equals(arraySelection, selectionList.toArray())) {
+            System.out.println("Expected: " + selectionList);
+            System.out.println("Actual: " + Arrays.asList(arraySelection));
+            throw new RuntimeException("Wrong selection from " +
+                    "getSelectedValues");
+        }
+    }
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/SwingSet/src/TableDemoTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/SwingSet/src/TableDemoTest.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2018, 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 static com.sun.swingset3.demos.table.TableDemo.COLUMN1_NAME;
+import static com.sun.swingset3.demos.table.TableDemo.COLUMN2_NAME;
+import static com.sun.swingset3.demos.table.TableDemo.COLUMN3_NAME;
+import static com.sun.swingset3.demos.table.TableDemo.COLUMN4_NAME;
+import static com.sun.swingset3.demos.table.TableDemo.DEMO_TITLE;
+import static com.sun.swingset3.demos.table.TableDemo.ROW_HEIGHT;
+import static org.jemmy2ext.JemmyExt.EXACT_STRING_COMPARATOR;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JTable;
+
+import org.jtregext.GuiTestListener;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.JCheckBoxOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JTableHeaderOperator;
+import org.netbeans.jemmy.operators.JTableOperator;
+import org.netbeans.jemmy.operators.JTextFieldOperator;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+
+import com.sun.swingset3.demos.table.OscarCandidate;
+import com.sun.swingset3.demos.table.OscarTableModel;
+import com.sun.swingset3.demos.table.TableDemo;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 TableDemo page by checking different properties
+ * of the JTable like number of row, number of columns and actions like
+ * selection of cell, sorting based on column, filtering based on text and
+ * moving of the column
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Extensions/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @modules java.desktop
+ *          java.logging
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.table.TableDemo
+ * @run testng TableDemoTest
+ */
+@Listeners(GuiTestListener.class)
+public class TableDemoTest {
+
+    private final static int MAX_ROW_COUNT = 524;
+    private final static int MAX_COL_COUNT = 4;
+
+    private final static String FILTER_TEXT = "Sunrise";
+    private final static String FILTER_RESET_TEXT = "";
+
+    private final static int [] SELECT_ROW_INDICES ={10, 11, 18};
+
+    private final static int MOVE_COL_START_INDEX = 1;
+    private final static int MOVE_COL_END_INDEX = 2;
+    private final static String MOVE_COL_VAL_TEXT1 = "Sunrise";
+    private final static String MOVE_COL_VAL_TEXT2 = "Most Unique Artistic Picture";
+    private final static int MOVE_COL_VAL_ROW = 0;
+
+    private final static int SORT_COL = 1;
+    private final static int[] SORT_VAL_ROWS =new int[] {0, 250, 523};
+    private final static String[][] ASC_PRE_SORT_ROW_VAL = new String[][] {
+        {"1928", "Best Actor", "The Way of All Flesh", "[Emil Jannings]"},
+        {"1933", "Best Director", "Cavalcade", "[Frank Lloyd]"},
+        {"1936", "Best Engineering Effects", "My Man Godfrey", "[Eric Hatch, Morris Ryskind]"}};
+    private final static String[][] ASC_POST_SORT_ROW_VAL = new String[][] {
+        {"1928", "Best Actor", "The Way of All Flesh", "[Emil Jannings]"},
+        {"1936", "Best Director", "My Man Godfrey", "[Gregory La Cava]"},
+        {"1928", "Most Unique Artistic Picture", "The Crowd", "[]"}};
+    private final static String[][] DESC_POST_SORT_ROW_VAL = new String[][] {
+        {"1928", "Most Unique Artistic Picture", "Sunrise", "[]"},
+        {"1934", "Best Engineering Effects", "Viva Villa!", "[Ben Hecht]"},
+        {"1936", "Best Actor", "San Francisco", "[Spencer Tracy]"}};
+
+    /**
+     * Tests the different properties of JTable like number of rows, number
+     * of columns and actions like selection of cell, sorting based on column,
+     * filtering based on text and moving of the column.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void test() throws Exception {
+
+        new ClassReference(TableDemo.class.getCanonicalName()).startApplication();
+
+        JFrameOperator frameOperator = new JFrameOperator(DEMO_TITLE);
+        frameOperator.setComparator(EXACT_STRING_COMPARATOR);
+        frameOperator.setVerification(true);
+        JTableOperator tableOperator = new JTableOperator(frameOperator);
+        JTableHeaderOperator tableHeaderOperator = new JTableHeaderOperator(frameOperator);
+
+        checkTableBasicProperties(tableOperator);
+        checkCellSelection(tableOperator);
+        checkSortTable(tableOperator, tableHeaderOperator);
+        checkMoveColumn(tableOperator, tableHeaderOperator);
+        checkFilterTable(frameOperator, tableOperator);
+    }
+
+    /**
+     * Verifies the table basic properties number of columns, rows and row height
+     *
+     * @param tableOperator
+     */
+    private void checkTableBasicProperties(JTableOperator tableOperator) {
+        tableOperator.waitStateOnQueue(comp
+                -> MAX_COL_COUNT == ((JTable)comp).getColumnCount());
+        waitRowCount(tableOperator, MAX_ROW_COUNT);
+        tableOperator.waitStateOnQueue(comp
+                -> ROW_HEIGHT == ((JTable)comp).getRowHeight());
+    }
+
+    /**
+     * Selects one table cell and verifies the selected cell's row number and column number
+     *
+     * @param tableOperator
+     */
+    private void checkCellSelection(JTableOperator tableOperator) {
+        int noOfColumns = tableOperator.getColumnCount();
+        for (int i = 0; i < SELECT_ROW_INDICES.length; i++) {
+            int rowIndex = SELECT_ROW_INDICES[i];
+            for (int j = 0; j < noOfColumns; j++) {
+                int colIndex = j;
+                tableOperator.clickOnCell(rowIndex, colIndex);
+                tableOperator.waitStateOnQueue(comp
+                        -> rowIndex == ((JTable)comp).getSelectedRow() &&
+                        colIndex == ((JTable)comp).getSelectedColumn());
+            }
+        }
+    }
+
+    /**
+     * Filter table based on specific text and winners check box, and verifies row count
+     *
+     * @param frameOperator
+     * @param tableOperator
+     */
+    private void checkFilterTable(JFrameOperator frameOperator,
+            JTableOperator tableOperator) {
+
+        int [] filterRowCount = getFilteredCount(tableOperator, FILTER_TEXT);
+        JTextFieldOperator filterField = new JTextFieldOperator(frameOperator);
+        JCheckBoxOperator winnersCheckbox = new JCheckBoxOperator(frameOperator);
+
+        // Filtering based on FILTER_TEXT
+        filterField.setText(FILTER_TEXT);
+        waitRowCount(tableOperator, filterRowCount[0]);
+
+        // Filtering based on WinnersCheckbox
+        winnersCheckbox.setSelected(true);
+        waitRowCount(tableOperator, filterRowCount[1]);
+
+        // Resets the winners check box
+        winnersCheckbox.setSelected(false);
+        waitRowCount(tableOperator, filterRowCount[0]);
+
+        // Resets the filter text field
+        filterField.setText(FILTER_RESET_TEXT);
+        waitRowCount(tableOperator, MAX_ROW_COUNT);
+
+    }
+
+    private int[] getFilteredCount(JTableOperator tableOperator, String filterText){
+        OscarTableModel tableModel = (OscarTableModel)tableOperator.getModel();
+        int noOfRows = tableModel.getRowCount();
+        int filteredRowCount = 0;
+        int filteredWinnersRowCount = 0;
+        for (int i = 0; i < noOfRows; i++) {
+            OscarCandidate candidate = tableModel.getCandidate(i);
+            if(isMovieOrPersonsContainsText(candidate, filterText)){
+                filteredRowCount++;
+                if(candidate.isWinner()) {
+                    filteredWinnersRowCount++;
+                }
+            }
+        }
+        return new int[] {filteredRowCount, filteredWinnersRowCount};
+    }
+
+    private boolean isMovieOrPersonsContainsText(
+            OscarCandidate candidate, String filterText){
+        String movie = candidate.getMovieTitle();
+        if(movie != null && movie.contains(filterText)) {
+            return true;
+        } else {
+            List persons = candidate.getPersons();
+            for (String person : persons) {
+                if(person != null && person.contains(filterText)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Moves to swap the columns, move again to reset back, verify column name
+     * and cell values in both the scenarios.
+     *
+     * @param tableOperator
+     * @param tableHeaderOperator
+     */
+    private void checkMoveColumn(JTableOperator tableOperator,
+            JTableHeaderOperator tableHeaderOperator) {
+
+        String[] columnNames = {COLUMN1_NAME, COLUMN3_NAME, COLUMN2_NAME, COLUMN4_NAME};
+        // Moving the column from 'start index' to 'end index'
+        moveColumn(tableOperator, tableHeaderOperator, columnNames,
+                MOVE_COL_START_INDEX, MOVE_COL_END_INDEX);
+
+        // Resets the columns to original position(from 'end index' to 'start index')
+        columnNames[1] = COLUMN2_NAME;
+        columnNames[2] = COLUMN3_NAME;
+        moveColumn(tableOperator, tableHeaderOperator, columnNames,
+                MOVE_COL_END_INDEX, MOVE_COL_START_INDEX);
+    }
+
+    /**
+     * Moves to swap the columns, verify column name and cell values.
+     *
+     * @param tableOperator
+     * @param tableHeaderOperator
+     * @param columnNames
+     * @param moveCol
+     * @param moveToCol
+     */
+    private void moveColumn(JTableOperator tableOperator, JTableHeaderOperator tableHeaderOperator,
+            String[] columnNames, int moveCol, int moveToCol){
+
+        tableHeaderOperator.moveColumn(moveCol, moveToCol);
+        checkColumnNames(tableOperator, columnNames);
+        tableOperator.waitCell(MOVE_COL_VAL_TEXT1, MOVE_COL_VAL_ROW, moveCol);
+        tableOperator.waitCell(MOVE_COL_VAL_TEXT2, MOVE_COL_VAL_ROW, moveToCol);
+    }
+
+    private void checkColumnNames(JTableOperator tableOperator, String[] columnNames) {
+        for (int i = 0; i < tableOperator.getColumnCount(); i++) {
+            int columnIndex = i;
+            tableOperator.waitStateOnQueue(comp -> columnNames[columnIndex].equals(
+                    ((JTable)comp).getColumnModel().getColumn(columnIndex).getHeaderValue()));
+        }
+    }
+
+    /**
+     * Sorts the table based on one particular column in ascending and descending order,
+     * and verifies cell values
+     *
+     * @param tableOperator
+     * @param tableHeaderOperator
+     */
+    private void checkSortTable(JTableOperator tableOperator,
+            JTableHeaderOperator tableHeaderOperator) {
+
+        // Verifying the row values before sort
+        checkTableRows(tableOperator, ASC_PRE_SORT_ROW_VAL);
+
+        // Getting all award category values before stating the sort
+        // to prepare the expected result
+        ArrayList awardCats = new ArrayList<>();
+        for (int i = 0; i < tableOperator.getRowCount(); i++) {
+            awardCats.add((String) tableOperator.getValueAt(i, SORT_COL));
+        }
+        // Sorting awardCats(expected result) in ascending order
+        awardCats.sort((s1, s2) -> s1.compareTo(s2));
+
+        // Sorting table based on column 'Award Category' in ascending order
+        sortTable(tableOperator, tableHeaderOperator, awardCats,
+                ASC_POST_SORT_ROW_VAL);
+
+        // Sorting awardCats(expected result) in descending order
+        awardCats.sort((s1, s2) -> s2.compareTo(s1));
+        // Sorting table based on column 'Award Category' in descending order
+        sortTable(tableOperator, tableHeaderOperator, awardCats,
+                DESC_POST_SORT_ROW_VAL);
+
+    }
+
+    private void checkColumnSorted(JTableOperator tableOperator,
+            ArrayList awardCatExp){
+        ArrayList awardCatActual = new ArrayList<>();
+        for (int i = 0; i < tableOperator.getRowCount(); i++) {
+            awardCatActual.add((String) tableOperator.getValueAt(i, SORT_COL));
+        }
+        tableOperator.waitStateOnQueue(comp -> awardCatExp.equals(awardCatActual));
+    }
+
+    private void checkTableRows(JTableOperator tableOperator, String[][] rowValues) {
+        for (int i = 0; i < SORT_VAL_ROWS.length; i++) {
+            tableOperator.waitCell(rowValues[i][0], SORT_VAL_ROWS[i], 0);
+            tableOperator.waitCell(rowValues[i][1], SORT_VAL_ROWS[i], 1);
+            tableOperator.waitCell(rowValues[i][2], SORT_VAL_ROWS[i], 2);
+            tableOperator.waitCell(rowValues[i][3], SORT_VAL_ROWS[i], 3);
+        }
+    }
+
+    /**
+     * Sorts the table based on one particular column and verifies cell values
+     *
+     * @param tableOperator
+     * @param tableHeaderOperator
+     * @param awardCatExp
+     * @param rowValues
+     */
+    private void sortTable(JTableOperator tableOperator, JTableHeaderOperator tableHeaderOperator,
+            ArrayList awardCatExp, String[][] rowValues) {
+
+        tableHeaderOperator.selectColumn(SORT_COL);
+        checkColumnSorted(tableOperator, awardCatExp);
+        // Verifying the row values after sort
+        checkTableRows(tableOperator, rowValues);
+    }
+
+    /**
+     * Waits the number of rows on table equal to the count specified
+     *
+     * @param tableOperator
+     * @param count
+     */
+    private void waitRowCount(JTableOperator tableOperator, int count) {
+        tableOperator.waitStateOnQueue(comp
+                -> count == ((JTable)comp).getRowCount());
+    }
+
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/HyperlinkCellRenderer.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/HyperlinkCellRenderer.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2018, 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.sun.swingset3.demos.table;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import javax.swing.Action;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+import javax.swing.table.TableCellRenderer;
+
+import com.sun.swingset3.demos.JHyperlink;
+
+/**
+ * Table renderer which renders cell value as hyperlink with optional rollover underline.
+ *
+ * @author aim
+ */
+public class HyperlinkCellRenderer extends JHyperlink implements TableCellRenderer {
+    private JTable table;
+    private final ArrayList columnModelIndeces = new ArrayList();
+
+    private Color rowColors[];
+    private Color foreground;
+    private Color visitedForeground;
+    private Border focusBorder;
+    private Border noFocusBorder;
+
+    private boolean underlineOnRollover = true;
+
+    private transient int hitColumnIndex = -1;
+    private transient int hitRowIndex = -1;
+
+    private HashMap visitedCache;
+
+    public HyperlinkCellRenderer(Action action, boolean underlineOnRollover) {
+        setAction(action);
+        setHorizontalAlignment(JHyperlink.LEFT);
+        rowColors = new Color[1];
+        rowColors[0] = UIManager.getColor("Table.background");
+        this.underlineOnRollover = underlineOnRollover;
+        applyDefaults();
+    }
+
+    public void setRowColors(Color[] colors) {
+        this.rowColors = colors;
+    }
+
+    public void updateUI() {
+        super.updateUI();
+        applyDefaults();
+    }
+
+    protected void applyDefaults() {
+        setOpaque(true);
+        setBorderPainted(false);
+        foreground = UIManager.getColor("Hyperlink.foreground");
+        visitedForeground = UIManager.getColor("Hyperlink.visitedForeground");
+
+        // Make sure border used on non-focussed cells is same size as focussed border
+        focusBorder = UIManager.getBorder("Table.focusCellHighlightBorder");
+        if (focusBorder != null) {
+            Insets insets = focusBorder.getBorderInsets(this);
+            noFocusBorder = new EmptyBorder(insets.top, insets.left, insets.bottom, insets.right);
+        } else {
+            focusBorder = noFocusBorder = new EmptyBorder(1, 1, 1, 1);
+        }
+    }
+
+    public Component getTableCellRendererComponent(JTable table, Object value,
+            boolean isSelected, boolean hasFocus, int row, int column) {
+        if (this.table == null) {
+            this.table = table;
+            HyperlinkMouseListener hyperlinkListener = new HyperlinkMouseListener();
+            table.addMouseMotionListener(hyperlinkListener);
+            table.addMouseListener(hyperlinkListener);
+        }
+        int columnModelIndex = table.getColumnModel().getColumn(column).getModelIndex();
+        if (!columnModelIndeces.contains(columnModelIndex)) {
+            columnModelIndeces.add(columnModelIndex);
+        }
+
+        if (value instanceof Link) {
+            Link link = (Link) value;
+            setText(link.getDisplayText());
+            setToolTipText(link.getDescription());
+        } else {
+            setText(value != null ? value.toString() : "");
+        }
+        setVisited(isCellLinkVisited(value, row, column));
+        setDrawUnderline(!underlineOnRollover ||
+                (row == hitRowIndex && column == hitColumnIndex));
+
+        if (!isSelected) {
+            setBackground(rowColors[row % rowColors.length]);
+            //setForeground(isCellLinkVisited(value, row, column)?
+            //  visitedForeground : foreground);
+            setForeground(foreground);
+            setVisitedForeground(visitedForeground);
+        } else {
+            setBackground(table.getSelectionBackground());
+            setForeground(table.getSelectionForeground());
+            setVisitedForeground(table.getSelectionForeground());
+        }
+        //setBorder(hasFocus? focusBorder : noFocusBorder);
+        //System.out.println("border insets="+getBorder().getBorderInsets(this));
+
+        return this;
+    }
+
+    protected void setCellLinkVisited(Object value, int row, int column) {
+        if (!isCellLinkVisited(value, row, column)) {
+            if (value instanceof Link) {
+                ((Link) value).setVisited(true);
+            } else {
+                if (visitedCache == null) {
+                    visitedCache = new HashMap();
+                }
+                int position[] = new int[2];
+                position[0] = table.convertRowIndexToModel(row);
+                position[1] = table.convertColumnIndexToModel(column);
+                visitedCache.put(value, position);
+            }
+        }
+    }
+
+    protected boolean isCellLinkVisited(Object value, int row, int column) {
+        if (value instanceof Link) {
+            return ((Link) value).isVisited();
+        }
+        if (visitedCache != null) {
+            int position[] = visitedCache.get(value);
+            if (position != null) {
+                return position[0] == table.convertRowIndexToModel(row) &&
+                        position[1] == table.convertColumnIndexToModel(column);
+            }
+        }
+        return false;
+    }
+
+    public int getActiveHyperlinkRow() {
+        return hitRowIndex;
+    }
+
+    public int getActiveHyperlinkColumn() {
+        return hitColumnIndex;
+    }
+
+    // overridden because the AbstractButton's version forces the source of the event
+    // to be the AbstractButton and we want a little more freedom to configure the
+    // event
+    @Override
+    protected void fireActionPerformed(ActionEvent event) {
+        // Guaranteed to return a non-null array
+        Object[] listeners = listenerList.getListenerList();
+
+        // Process the listeners last to first, notifying
+        // those that are interested in this event
+        for (int i = listeners.length - 2; i >= 0; i -= 2) {
+            if (listeners[i] == ActionListener.class) {
+                ((ActionListener) listeners[i + 1]).actionPerformed(event);
+            }
+        }
+    }
+
+    public void invalidate() {
+    }
+
+    public void validate() {
+    }
+
+    public void revalidate() {
+    }
+
+    public void repaint(long tm, int x, int y, int width, int height) {
+    }
+
+    public void repaint(Rectangle r) {
+    }
+
+    public void repaint() {
+    }
+
+    private class HyperlinkMouseListener extends MouseAdapter {
+        private transient Rectangle cellRect;
+        private final transient Rectangle iconRect = new Rectangle();
+        private final transient Rectangle textRect = new Rectangle();
+        private transient Cursor tableCursor;
+
+        @Override
+        public void mouseMoved(MouseEvent event) {
+            // This should only be called if underlineOnRollover is true
+            JTable table = (JTable) event.getSource();
+
+            // Locate the table cell under the event location
+            int oldHitColumnIndex = hitColumnIndex;
+            int oldHitRowIndex = hitRowIndex;
+
+            checkIfPointInsideHyperlink(event.getPoint());
+
+            if (hitRowIndex != oldHitRowIndex ||
+                    hitColumnIndex != oldHitColumnIndex) {
+                if (hitRowIndex != -1) {
+                    if (tableCursor == null) {
+                        tableCursor = table.getCursor();
+                    }
+                    table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+                } else {
+                    table.setCursor(tableCursor);
+                }
+
+                // repaint the cells affected by rollover
+                Rectangle repaintRect;
+                if (hitRowIndex != -1 && hitColumnIndex != -1) {
+                    // we need to repaint new cell with rollover underline
+                    // cellRect already contains rect of hit cell
+                    if (oldHitRowIndex != -1 && oldHitColumnIndex != -1) {
+                        // we also need to repaint previously underlined hyperlink cell
+                        // to remove the underline
+                        repaintRect = cellRect.union(
+                                table.getCellRect(oldHitRowIndex, oldHitColumnIndex, false));
+                    } else {
+                        // we don't have a previously underlined hyperlink, so just repaint new one'
+                        repaintRect = table.getCellRect(hitRowIndex, hitColumnIndex, false);
+                    }
+                } else {
+                    // we just need to repaint previously underlined hyperlink cell
+                    //to remove the underline
+                    repaintRect = table.getCellRect(oldHitRowIndex, oldHitColumnIndex, false);
+                }
+                table.repaint(repaintRect);
+            }
+
+        }
+
+        @Override
+        public void mouseClicked(MouseEvent event) {
+            if (checkIfPointInsideHyperlink(event.getPoint())) {
+
+                ActionEvent actionEvent = new ActionEvent(new Integer(hitRowIndex),
+                        ActionEvent.ACTION_PERFORMED,
+                        "hyperlink");
+
+                HyperlinkCellRenderer.this.fireActionPerformed(actionEvent);
+
+                setCellLinkVisited(table.getValueAt(hitRowIndex, hitColumnIndex),
+                        hitRowIndex, hitColumnIndex);
+
+            }
+        }
+
+        protected boolean checkIfPointInsideHyperlink(Point p) {
+            hitColumnIndex = table.columnAtPoint(p);
+            hitRowIndex = table.rowAtPoint(p);
+
+            if (hitColumnIndex != -1 && hitRowIndex != -1 &&
+                    columnModelIndeces.contains(table.getColumnModel().
+                            getColumn(hitColumnIndex).getModelIndex())) {
+                // We know point is within a hyperlink column, however we do further hit testing
+                // to see if point is within the text bounds on the hyperlink
+                TableCellRenderer renderer = table.getCellRenderer(hitRowIndex, hitColumnIndex);
+                JHyperlink hyperlink = (JHyperlink) table.prepareRenderer(renderer, hitRowIndex, hitColumnIndex);
+
+                // Convert the event to the renderer's coordinate system
+                cellRect = table.getCellRect(hitRowIndex, hitColumnIndex, false);
+                hyperlink.setSize(cellRect.width, cellRect.height);
+                p.translate(-cellRect.x, -cellRect.y);
+                cellRect.x = cellRect.y = 0;
+                iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
+                textRect.x = textRect.y = textRect.width = textRect.height = 0;
+                SwingUtilities.layoutCompoundLabel(
+                        hyperlink.getFontMetrics(hyperlink.getFont()),
+                        hyperlink.getText(), hyperlink.getIcon(),
+                        hyperlink.getVerticalAlignment(),
+                        hyperlink.getHorizontalAlignment(),
+                        hyperlink.getVerticalTextPosition(),
+                        hyperlink.getHorizontalTextPosition(),
+                        cellRect, iconRect, textRect, hyperlink.getIconTextGap());
+
+                if (textRect.contains(p)) {
+                    // point is within hyperlink text bounds
+                    return true;
+                }
+            }
+            // point is not within a hyperlink's text bounds
+            hitRowIndex = -1;
+            hitColumnIndex = -1;
+            return false;
+        }
+    }
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/IMDBLink.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/IMDBLink.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2018, 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.sun.swingset3.demos.table;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+
+/**
+ * Class used to support converting a movie title string into an IMDB URI
+ * corresponding to that movie's IMDB entry.   Since IMDB encodes entries with
+ * an alpha-numeric key (rather than title), we have to use Yahoo search on the
+ * title and then screenscrape the search results to find the IMDB key.
+ *
+ * @author aim
+ */
+public class IMDBLink {
+
+    private IMDBLink() {
+    }
+
+    /**
+     * @param movieTitle the title of the movie
+     * @param year       the year the movie was nominated for the oscar
+     * @return String containing URI for movie's IMDB entry or null if URI could not be found
+     */
+    public static String getMovieURIString(String movieTitle, int year) throws IOException {
+        ArrayList matches = new ArrayList();
+        URL url;
+        BufferedReader reader;
+
+        // btw, google rejects the request with a 403 return code!
+        // URL url = new URL("http://www.google.com/search?q=Dazed+and+confused");
+        // Thank you, yahoo, for granting our search request :-)
+        try {
+            String urlKey = URLEncoder.encode(movieTitle, "UTF-8");
+            url = new URL("http://search.yahoo.com/search?ei=utf-8&fr=sfp&p=imdb+" +
+                    urlKey + "&iscqry=");
+        } catch (Exception ex) {
+            System.err.println(ex);
+
+            return null;
+        }
+
+        URLConnection conn = url.openConnection();
+        conn.connect();
+
+        // Get the response from Yahoo search query
+        reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+
+        // Parse response a find each imdb/titleString result
+        String line;
+        String imdbString = ".imdb.com";
+        String titleStrings[] = {"/title", "/Title"};
+
+        while ((line = reader.readLine()) != null) {
+            for (String titleString : titleStrings) {
+                String scrapeKey = imdbString + titleString;
+                int index = line.indexOf(scrapeKey);
+                if (index != -1) {
+                    // The IMDB key looks something like "tt0032138"
+                    // so we look for the 9 characters after the scrape key
+                    // to construct the full IMDB URI.
+                    // e.g. http://www.imdb.com/title/tt0032138
+                    int len = scrapeKey.length();
+                    String imdbURL = "http://www" +
+                            line.substring(index, index + len) +
+                            line.substring(index + len, index + len + 10);
+
+                    if (!matches.contains(imdbURL)) {
+                        matches.add(imdbURL);
+                    }
+                }
+            }
+        }
+        reader.close();
+
+        // Since imdb contains entries for multiple movies of the same titleString,
+        // use the year to find the right entry
+        if (matches.size() > 1) {
+            for (String matchURL : matches) {
+                if (verifyYear(matchURL, year)) {
+                    return matchURL;
+                }
+            }
+        }
+        return matches.isEmpty()? null : matches.get(0);
+    }
+
+
+    private static boolean verifyYear(String imdbURL, int movieYear) throws IOException {
+        boolean yearMatches = false;
+
+        URLConnection conn = new URL(imdbURL).openConnection();
+        conn.connect();
+
+        // Get the response
+        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+
+        String line;
+        while ((line = reader.readLine()) != null) {
+            int index = line.indexOf("");
+            if (index != -1) {
+                // looking for "movie title (YEAR)"
+                try {
+                    int year = Integer.parseInt(line.substring(index - 5, index - 1));
+                    // Movie may have been made the year prior to oscar award
+                    yearMatches = year == movieYear || year == movieYear - 1;
+
+                } catch (NumberFormatException ex) {
+                    // ignore title lines that have other formatting
+                }
+                break; // only interested in analyzing the one line
+            }
+        }
+        reader.close();
+
+        return yearMatches;
+    }
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/Link.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/Link.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018, 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.sun.swingset3.demos.table;
+
+import java.net.URI;
+
+/**
+ * Class representing the state of a hyperlink
+ * This class may be used in conjunction with HyperlinkCellRenderer,
+ * but it is not required.
+ *
+ * @author aim
+ */
+public class Link {
+    protected String displayText;
+    private URI uri;
+    private String description;
+    private boolean visited;
+
+    /**
+     * Creates a new instance of Link
+     */
+    public Link(String text) {
+        setDisplayText(text);
+    }
+
+    public Link(String text, URI uri) {
+        this(text);
+        setUri(uri);
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public void setDisplayText(String text) {
+        this.displayText = text;
+    }
+
+    public URI getUri() {
+        return uri;
+    }
+
+    public void setUri(URI uri) {
+        this.uri = uri;
+    }
+
+    public String getDescription() {
+        return description != null ? description :
+                uri != null ? uri.getPath() : null;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public boolean isVisited() {
+        return visited;
+    }
+
+    public void setVisited(boolean visited) {
+        this.visited = visited;
+    }
+
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/OscarCandidate.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/OscarCandidate.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2018, 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.sun.swingset3.demos.table;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author aim
+ */
+public class OscarCandidate {
+
+    private String category;
+    private Integer year;
+    private boolean winner = false;
+    private String movie;
+    private URI imdbURI;
+    private final ArrayList persons = new ArrayList();
+
+    /**
+     * Creates a new instance of OscarCandidate
+     */
+    public OscarCandidate(String category) {
+        this.category = category;
+    }
+
+    public String getCategory() {
+        return category;
+    }
+
+    public void setCategory(String category) {
+        this.category = category;
+    }
+
+    public Integer getYear() {
+        return year;
+    }
+
+    public void setYear(Integer year) {
+        this.year = year;
+    }
+
+    public boolean isWinner() {
+        return winner;
+    }
+
+    public void setWinner(boolean winner) {
+        this.winner = winner;
+    }
+
+    public String getMovieTitle() {
+        return movie;
+    }
+
+    public void setMovieTitle(String movie) {
+        this.movie = movie;
+    }
+
+    public URI getIMDBMovieURI() {
+        return imdbURI;
+    }
+
+    public void setIMDBMovieURI(URI uri) {
+        this.imdbURI = uri;
+    }
+
+    public List getPersons() {
+        return persons;
+    }
+
+
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/OscarCellRenderers.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/OscarCellRenderers.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2018, 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.sun.swingset3.demos.table;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Font;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.UIManager;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableModel;
+
+/**
+ *
+ * @author aim
+ */
+public class OscarCellRenderers {
+
+    //Render table rows with alternating colors
+    public static class RowRenderer extends DefaultTableCellRenderer {
+        private Color rowColors[];
+
+        public RowRenderer() {
+            // initialize default colors from look-and-feel
+            rowColors = new Color[1];
+            rowColors[0] = UIManager.getColor("Table.background");
+        }
+
+        public RowRenderer(Color colors[]) {
+            super();
+            setRowColors(colors);
+        }
+
+        public void setRowColors(Color colors[]) {
+            rowColors = colors;
+        }
+
+        public Component getTableCellRendererComponent(JTable table, Object value,
+                boolean isSelected, boolean hasFocus, int row, int column) {
+            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+            setText(value != null ? value.toString() : "unknown");
+            if (!isSelected) {
+                setBackground(rowColors[row % rowColors.length]);
+            }
+            return this;
+        }
+
+        public boolean isOpaque() {
+            return true;
+        }
+    }
+    //
+
+    //Render "year" table column with font representing style of decade
+    // currently only used on OS X because fonts are Mac centric.
+
+    public static class YearRenderer extends RowRenderer {
+        private HashMap eraFonts;
+
+        public YearRenderer() {
+            setHorizontalAlignment(JLabel.CENTER);
+
+            if (System.getProperty("os.name").equals("Mac OS X")) {
+                eraFonts = new HashMap();
+                eraFonts.put("192"/*1920's*/, new Font("Jazz LET", Font.PLAIN, 12));
+                eraFonts.put("193"/*1930's*/, new Font("Mona Lisa Solid ITC TT", Font.BOLD, 18));
+                eraFonts.put("194"/*1940's*/, new Font("American Typewriter", Font.BOLD, 12));
+                eraFonts.put("195"/*1950's*/, new Font("Britannic Bold", Font.PLAIN, 12));
+                eraFonts.put("196"/*1960's*/, new Font("Cooper Black", Font.PLAIN, 14));
+                eraFonts.put("197"/*1970's*/, new Font("Syncro LET", Font.PLAIN, 14));
+                eraFonts.put("198"/*1980's*/, new Font("Mistral", Font.PLAIN, 18));
+                eraFonts.put("199"/*1990's*/, new Font("Papyrus", Font.BOLD, 14));
+                eraFonts.put("200"/*2000's*/, new Font("Calisto MT", Font.PLAIN, 14));
+            }
+        }
+
+        public YearRenderer(Color colors[]) {
+            this();
+            setRowColors(colors);
+        }
+
+        public Component getTableCellRendererComponent(JTable table, Object value,
+                boolean isSelected, boolean hasFocus, int row, int column) {
+
+            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+
+            String year = table.getValueAt(row,
+                    table.convertColumnIndexToView(OscarTableModel.YEAR_COLUMN)).toString();
+            if (eraFonts != null && year != null && year.length() == 4) {
+                String era = year.substring(0, 3);
+                Font eraFont = eraFonts.get(era);
+                setFont(eraFont);
+            }
+            return this;
+        }
+    }
+    //
+
+    //Render "nominee" table column with special icon for winners
+
+    public static class NomineeRenderer extends RowRenderer {
+        private final ImageIcon winnerIcon;
+        private final ImageIcon nomineeIcon; // nice way of saying "loser" :)
+
+        public NomineeRenderer() {
+            winnerIcon = new ImageIcon(
+                    getClass().getResource("resources/images/goldstar.png"));
+            nomineeIcon = new ImageIcon(
+                    getClass().getResource("resources/images/nominee.png"));
+            setHorizontalTextPosition(JLabel.TRAILING);
+        }
+
+        public NomineeRenderer(Color colors[]) {
+            this();
+            setRowColors(colors);
+        }
+
+        public Component getTableCellRendererComponent(JTable table, Object value,
+                boolean isSelected, boolean hasFocus, int row, int column) {
+
+            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+
+            TableModel model = table.getModel();
+            boolean winner = ((Boolean) model.getValueAt(table.convertRowIndexToModel(row),
+                    OscarTableModel.WINNER_COLUMN)).booleanValue();
+
+            List persons = (List) value;
+            String text = persons != null && !persons.isEmpty() ? persons.get(0) : "name unknown";
+            if (persons != null && persons.size() > 1) {
+                int personCount = persons.size();
+                setText(text + " + more...");
+                StringBuffer winners = new StringBuffer("");
+                for (int i = 0; i < personCount; i++) {
+                    String person = persons.get(i);
+                    winners.append(" " + person + (i < personCount - 1 ? ", " : ""));
+                }
+                setToolTipText((winner ? "Winners:" : "Nominees:") + winners);
+            } else {
+                setText(text);
+                setToolTipText(winner ? "Winner!" : "Nominee");
+            }
+
+            setIcon(winner ? winnerIcon : nomineeIcon);
+
+            return this;
+        }
+    }
+    //
+
+    public static class MovieRenderer extends HyperlinkCellRenderer {
+        public MovieRenderer(Action action, boolean underlineOnRollover, Color rowColors[]) {
+            super(action, underlineOnRollover);
+            setRowColors(rowColors);
+        }
+
+        public Component getTableCellRendererComponent(JTable table, Object value,
+                boolean isSelected, boolean hasFocus, int row, int column) {
+            super.getTableCellRendererComponent(table, value, isSelected,
+                    hasFocus, row, column);
+            if (value != null) {
+                setToolTipText("http://www.imdb.com/" + "\"" + value + "\"");
+            }
+            return this;
+        }
+    }
+
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/OscarDataParser.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/OscarDataParser.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2018, 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.sun.swingset3.demos.table;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.logging.Level;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public abstract class OscarDataParser extends DefaultHandler {
+    private static final String[] CATEGORIES_IN = {
+            "actor", "actress", "bestPicture",
+            "actorSupporting", "actressSupporting", "artDirection",
+            "assistantDirector", "director", "cinematography",
+            "costumeDesign", "danceDirection", "docFeature",
+            "docShort", "filmEditing", "foreignFilm",
+            "makeup", "musicScore", "musicSong",
+            "screenplayAdapted", "screenplayOriginal", "shortAnimation",
+            "shortLiveAction", "sound", "soundEditing",
+            "specialEffects", "visualEffects", "writing",
+            "engEffects", "uniqueArtisticPicture"
+    };
+
+    private static final String[] CATEGORIES_OUT = {
+            "Best Actor", "Best Actress", "Best Picture",
+            "Best Supporting Actor", "Best Supporting Actress", "Best Art Direction",
+            "Best Assistant Director", "Best Director", "Best Cinematography",
+            "Best Costume Design", "Best Dance Direction", "Best Feature Documentary",
+            "Best Short Documentary", "Best Film Editing", "Best Foreign Film",
+            "Best Makeup", "Best Musical Score", "Best Song",
+            "Best Adapted Screenplay", "Best Original Screenplay", "Best Animation Short",
+            "Best Live Action Short", "Best Sound", "Best Sound Editing",
+            "Best Special Effects", "Best Visual Effects", "Best Engineering Effects",
+            "Best Writing", "Most Unique Artistic Picture"
+    };
+
+
+    private String tempVal;
+
+    //to maintain context
+    private OscarCandidate tempOscarCandidate;
+
+    private int count = 0;
+
+    public int getCount() {
+        return count;
+    }
+
+    public void parseDocument(URL oscarURL) {
+        //get a factory
+        SAXParserFactory spf = SAXParserFactory.newInstance();
+
+        try {
+            //get a new instance of parser
+            SAXParser sp = spf.newSAXParser();
+
+            //parse the file and also register this class for call backs
+            InputStream is = new BufferedInputStream(oscarURL.openStream());
+            sp.parse(is, this);
+            System.out.println("done parsing count="+count);
+            is.close();
+
+        } catch (SAXException se) {
+            se.printStackTrace();
+        } catch (ParserConfigurationException pce) {
+            pce.printStackTrace();
+        } catch (IOException ie) {
+            ie.printStackTrace();
+        }
+    }
+
+    //Event Handlers
+    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+        //reset
+        tempVal = "";
+        for (int i = 0; i < CATEGORIES_IN.length; i++) {
+            if (qName.equalsIgnoreCase(CATEGORIES_IN[i])) {
+                tempOscarCandidate = new OscarCandidate(CATEGORIES_OUT[i]);
+                tempOscarCandidate.setYear(Integer.parseInt(attributes.getValue("year")));
+                if (CATEGORIES_IN[i].equals("screenplayOriginal") &&
+                     tempOscarCandidate.getYear() == 2007) {
+                }
+                return;
+            }
+        }
+    }
+
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        tempVal = new String(ch, start, length);
+    }
+
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        if (qName.equalsIgnoreCase("won")) {
+            tempOscarCandidate.setWinner(true);
+        } else if (qName.equalsIgnoreCase("lost")) {
+            tempOscarCandidate.setWinner(false);
+        } else if (qName.equalsIgnoreCase("movie")) {
+            tempOscarCandidate.setMovieTitle(tempVal);
+        } else if (qName.equalsIgnoreCase("person")) {
+            tempOscarCandidate.getPersons().add(tempVal);
+        } else {
+            // find category
+            for (String category : CATEGORIES_IN) {
+                if (qName.equalsIgnoreCase(category)) {
+                    //add it to the list
+                    count++;
+                    addCandidate(tempOscarCandidate);
+                    break;
+                }
+            }
+        }
+    }
+
+    @Override
+    public void error(SAXParseException ex) throws SAXException {
+        TableDemo.logger.log(Level.SEVERE, "error parsing oscar data ", ex);
+    }
+
+    @Override
+    public void fatalError(SAXParseException ex) throws SAXException {
+        TableDemo.logger.log(Level.SEVERE, "fatal error parsing oscar data ", ex);
+    }
+
+    @Override
+    public void warning(SAXParseException ex) {
+        TableDemo.logger.log(Level.WARNING, "warning occurred while parsing oscar data ", ex);
+    }
+
+    @Override
+    public void endDocument() throws SAXException {
+        TableDemo.logger.log(Level.FINER, "parsed to end of oscar data.");
+    }
+
+    protected abstract void addCandidate(OscarCandidate candidate);
+}
+
diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/OscarTableModel.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/OscarTableModel.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2018, 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.sun.swingset3.demos.table;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+/**
+ * Data model for oscar candidate data: a list of OscarCandidate beans.
+ *
+ * @author aim
+ */
+
+public class OscarTableModel extends AbstractTableModel {
+    public static final int CATEGORY_COLUMN = 0;
+    public static final int YEAR_COLUMN = 1;
+    public static final int WINNER_COLUMN = 2;
+    public static final int MOVIE_COLUMN = 3;
+    public static final int PERSONS_COLUMN = 4;
+    public static final int COLUMN_COUNT = 5;
+
+    private final List candidates = new ArrayList();
+
+    public void add(List newCandidates) {
+        int first = candidates.size();
+        int last = first + newCandidates.size() - 1;
+        candidates.addAll(newCandidates);
+        fireTableRowsInserted(first, last);
+    }
+
+    public void add(OscarCandidate candidate) {
+        int index = candidates.size();
+        candidates.add(candidate);
+        fireTableRowsInserted(index, index);
+    }
+
+    public int getRowCount() {
+        return candidates.size();
+    }
+
+    public int getColumnCount() {
+        return COLUMN_COUNT;
+    }
+
+    @Override
+    public Class getColumnClass(int column) {
+        return getValueAt(0, column).getClass();
+    }
+
+    public OscarCandidate getCandidate(int row) {
+        return candidates.get(row);
+    }
+
+    public Object getValueAt(int row, int column) {
+        OscarCandidate oscarCandidate = candidates.get(row);
+        switch (column) {
+            case CATEGORY_COLUMN:
+                return oscarCandidate.getCategory();
+            case YEAR_COLUMN:
+                return oscarCandidate.getYear();
+            case MOVIE_COLUMN:
+                return oscarCandidate.getMovieTitle();
+            case WINNER_COLUMN:
+                return oscarCandidate.isWinner() ? Boolean.TRUE : Boolean.FALSE;
+            case PERSONS_COLUMN:
+                return oscarCandidate.getPersons();
+        }
+        return null;
+    }
+
+}
diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/TableDemo.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/TableDemo.java	Fri Mar 23 18:44:47 2018 +0000
@@ -0,0 +1,623 @@
+/*
+ * Copyright (c) 2018, 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.sun.swingset3.demos.table;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+import javax.swing.AbstractAction;
+import javax.swing.Box;
+import javax.swing.JCheckBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.RowFilter;
+import javax.swing.UIManager;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableColumnModel;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableRowSorter;
+import javax.swing.text.Document;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.DemoUtilities;
+
+/**
+ *
+ * @author aim
+ */
+@DemoProperties(
+        value = "JTable Demo",
+        category = "Data",
+        description = "Demonstrates use of Swing's data grid component, JTable, including asynchronous loading and sorting/filtering.",
+        sourceFiles = {
+                "com/sun/swingset3/demos/table/TableDemo.java",
+                "com/sun/swingset3/demos/table/HyperlinkCellRenderer.java",
+                "com/sun/swingset3/demos/table/IMDBLink.java",
+                "com/sun/swingset3/demos/table/Link.java",
+                "com/sun/swingset3/demos/table/OscarCandidate.java",
+                "com/sun/swingset3/demos/table/OscarCellRenderers.java",
+                "com/sun/swingset3/demos/table/OscarDataParser.java",
+                "com/sun/swingset3/demos/table/OscarTableModel.java",
+                "com/sun/swingset3/demos/DemoUtilities.java",
+                "com/sun/swingset3/demos/JHyperlink.java",
+                "com/sun/swingset3/demos/table/resources/bestpicture",
+                //"com/sun/swingset3/demos/table/resources/oscars.xml", file too large!!
+                "com/sun/swingset3/demos/table/resources/TableDemo.properties",
+                "com/sun/swingset3/demos/table/resources/images/goldstar.png",
+                "com/sun/swingset3/demos/table/resources/images/nominee.png",
+                "com/sun/swingset3/demos/table/resources/images/TableDemo.gif"
+                }
+)
+public class TableDemo extends JPanel {
+    static final Logger logger = Logger.getLogger(TableDemo.class.getName());
+    public static final String DEMO_TITLE = TableDemo.class.getAnnotation(DemoProperties.class).value();
+    public static final int ROW_HEIGHT = 26;
+    public static final String COLUMN1_NAME = "Year";
+    public static final String COLUMN2_NAME = "Award Category";
+    public static final String COLUMN3_NAME = "Movie Title";
+    public static final String COLUMN4_NAME = "Nominees";
+
+    private OscarTableModel oscarModel;
+
+    private JPanel controlPanel;
+    private JTable oscarTable;
+    private JCheckBox winnersCheckbox;
+    private JTextField filterField;
+    private Box statusBarLeft;
+    private JLabel actionStatus;
+    private JLabel tableStatus;
+
+    private Color[] rowColors;
+    private String statusLabelString;
+    private String searchLabelString;
+
+    private boolean showOnlyWinners = false;
+    private String filterString = null;
+
+    private TableRowSorter sorter;
+    private RowFilter winnerFilter;
+    private RowFilter searchFilter;
+
+    // Resource bundle for internationalized and accessible text
+    private ResourceBundle bundle = null;
+
+    public TableDemo() {
+        initModel();
+        initComponents();
+        initSortingFiltering();
+    }
+
+    protected void initModel() {
+        oscarModel = new OscarTableModel();
+    }
+
+    protected void initComponents() {
+        setLayout(new BorderLayout());
+
+        controlPanel = createControlPanel();
+        add(controlPanel, BorderLayout.NORTH);
+
+        //Create JTable
+        oscarTable = new JTable(oscarModel);
+        //
+
+        //Set JTable display properties
+        oscarTable.setColumnModel(createColumnModel());
+        oscarTable.setAutoCreateRowSorter(true);
+        oscarTable.setRowHeight(ROW_HEIGHT);
+        oscarTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
+        oscarTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        oscarTable.setIntercellSpacing(new Dimension(0, 0));
+        //
+
+        //Initialize preferred size for table's viewable area
+        Dimension viewSize = new Dimension();
+        viewSize.width = oscarTable.getColumnModel().getTotalColumnWidth();
+        viewSize.height = 10 * oscarTable.getRowHeight();
+        oscarTable.setPreferredScrollableViewportSize(viewSize);
+        //
+
+        //Customize height and alignment of table header
+        JTableHeader header = oscarTable.getTableHeader();
+        header.setPreferredSize(new Dimension(30, 26));
+        TableCellRenderer headerRenderer = header.getDefaultRenderer();
+        if (headerRenderer instanceof JLabel) {
+            ((JLabel) headerRenderer).setHorizontalAlignment(JLabel.CENTER);
+        }
+        //
+
+        JScrollPane scrollpane = new JScrollPane(oscarTable);
+        add(scrollpane, BorderLayout.CENTER);
+
+        add(createStatusBar(), BorderLayout.SOUTH);
+
+    }
+
+    protected JPanel createControlPanel() {
+        JPanel controlPanel = new JPanel();
+        GridBagLayout gridbag = new GridBagLayout();
+        GridBagConstraints c = new GridBagConstraints();
+        controlPanel.setLayout(gridbag);
+
+        c.gridx = 0;
+        c.gridy = 1;
+        c.gridheight = 1;
+        c.insets = new Insets(20, 10, 0, 10);
+        c.anchor = GridBagConstraints.SOUTHWEST;
+        JLabel searchLabel = new JLabel(getString("TableDemo.searchLabel",
+                "Search Titles and Recipients"));
+        controlPanel.add(searchLabel, c);
+
+        c.gridx = 0;
+        c.gridy = 2;
+        c.weightx = 1.0;
+        c.insets.top = 0;
+        c.insets.bottom = 12;
+        c.anchor = GridBagConstraints.SOUTHWEST;
+        //c.fill = GridBagConstraints.HORIZONTAL;
+        filterField = new JTextField(24);
+        filterField.getDocument().addDocumentListener(new SearchFilterListener());
+        controlPanel.add(filterField, c);
+
+        c.gridx = 1;
+        c.gridy = 2;
+        c.gridwidth = GridBagConstraints.REMAINDER;
+        //c.insets.right = 24;
+        //c.insets.left = 12;
+        c.weightx = 0.0;
+        c.anchor = GridBagConstraints.EAST;
+        c.fill = GridBagConstraints.NONE;
+        winnersCheckbox = new JCheckBox(getString("TableDemo.winnersLabel",
+                "Show Only Winners"));
+        winnersCheckbox.addChangeListener(new ShowWinnersListener());
+        controlPanel.add(winnersCheckbox, c);
+
+        return controlPanel;
+    }
+
+    protected Container createStatusBar() {
+        statusLabelString = getString("TableDemo.rowCountLabel",
+                "Showing ");
+        searchLabelString = getString("TableDemo.searchCountLabel",
+                "Search found ");
+
+        Box statusBar = Box.createHorizontalBox();
+
+        // Left status area
+        statusBar.add(Box.createRigidArea(new Dimension(10, 22)));
+        statusBarLeft = Box.createHorizontalBox();
+        statusBar.add(statusBarLeft);
+        actionStatus = new JLabel(getString("TableDemo.noDataStatusLabel",
+                "No data loaded"));
+        actionStatus.setHorizontalAlignment(JLabel.LEADING);
+        statusBarLeft.add(actionStatus);
+
+        // Middle (should stretch)
+        statusBar.add(Box.createHorizontalGlue());
+        statusBar.add(Box.createHorizontalGlue());
+        statusBar.add(Box.createVerticalGlue());
+
+        // Right status area
+        tableStatus = new JLabel(statusLabelString + "0");
+        statusBar.add(tableStatus);
+        statusBar.add(Box.createHorizontalStrut(12));
+
+        //Track number of rows currently displayed
+        oscarModel.addTableModelListener(new TableModelListener() {
+            public void tableChanged(TableModelEvent e) {
+                // Get rowCount from *table*, not model, as the view row count
+                // may be different from the model row count due to filtering
+                tableStatus.setText((hasFilterString() ? searchLabelString : statusLabelString) +
+                        oscarTable.getRowCount());
+            }
+        });
+        //
+
+        return statusBar;
+    }
+
+    private Color[] getTableRowColors() {
+        if (rowColors == null) {
+            rowColors = new Color[2];
+            rowColors[0] = UIManager.getColor("Table.background");
+            rowColors[1] = new Color((int) (rowColors[0].getRed() * .9),
+                    (int) (rowColors[0].getGreen() * .9),
+                    (int) (rowColors[0].getBlue() * .9));
+        }
+        return rowColors;
+    }
+
+    // returns appropriate string from resource bundle
+    protected String getString(String key, String fallback) {
+        String value = fallback;
+        if (bundle == null) {
+            String bundleName = getClass().getPackage().getName() + ".resources." + getClass().getSimpleName();
+            bundle = ResourceBundle.getBundle(bundleName);
+        }
+        try {
+            value = bundle != null ? bundle.getString(key) : key;
+
+        } catch (MissingResourceException ex) {
+            logger.log(Level.WARNING, "couldn't find resource value for: " + key, ex);
+        }
+        return value;
+    }
+
+    public void start() {
+        if (oscarModel.getRowCount() == 0) {
+            loadData("resources/oscars.xml");
+        }
+    }
+
+    //Initialize table columns
+    protected TableColumnModel createColumnModel() {
+        DefaultTableColumnModel columnModel = new DefaultTableColumnModel();
+
+        TableCellRenderer cellRenderer = new OscarCellRenderers.RowRenderer(getTableRowColors());
+
+        TableColumn column = new TableColumn();
+        column.setModelIndex(OscarTableModel.YEAR_COLUMN);
+        column.setHeaderValue(COLUMN1_NAME);
+        column.setPreferredWidth(26);
+        column.setCellRenderer(new OscarCellRenderers.YearRenderer(getTableRowColors()));
+        columnModel.addColumn(column);
+
+        column = new TableColumn();
+        column.setModelIndex(OscarTableModel.CATEGORY_COLUMN);
+        column.setHeaderValue(COLUMN2_NAME);
+        column.setPreferredWidth(100);
+        column.setCellRenderer(cellRenderer);
+        columnModel.addColumn(column);
+
+        column = new TableColumn();
+        column.setModelIndex(OscarTableModel.MOVIE_COLUMN);
+        column.setHeaderValue(COLUMN3_NAME);
+        column.setPreferredWidth(180);
+        column.setCellRenderer(cellRenderer);
+        columnModel.addColumn(column);
+
+        column = new TableColumn();
+        column.setModelIndex(OscarTableModel.PERSONS_COLUMN);
+        column.setHeaderValue(COLUMN4_NAME);
+        column.setPreferredWidth(120);
+        column.setCellRenderer(new OscarCellRenderers.NomineeRenderer(getTableRowColors()));
+        columnModel.addColumn(column);
+
+        return columnModel;
+    }
+    //
+
+    protected void initSortingFiltering() {
+        //Setup filtering for winners
+        sorter = new TableRowSorter(oscarModel);
+        oscarTable.setRowSorter(sorter);
+        winnerFilter = new RowFilter() {
+            public boolean include(Entry entry) {
+                OscarTableModel oscarModel = entry.getModel();
+                OscarCandidate candidate = oscarModel.getCandidate(entry.getIdentifier().intValue());
+                if (candidate.isWinner()) {
+                    // Returning true indicates this row should be shown.
+                    return true;
+                }
+                // loser
+                return false;
+            }
+        };
+        //
+
+        //Setup search filter
+        searchFilter = new RowFilter() {
+            public boolean include(Entry entry) {
+                OscarTableModel oscarModel = entry.getModel();
+                OscarCandidate candidate = oscarModel.getCandidate(entry.getIdentifier().intValue());
+                boolean matches = false;
+                Pattern p = Pattern.compile(filterString + ".*", Pattern.CASE_INSENSITIVE);
+
+                String movie = candidate.getMovieTitle();
+                if (movie != null) {
+                    if (movie.startsWith("The ")) {
+                        movie = movie.replace("The ", "");
+                    } else if (movie.startsWith("A ")) {
+                        movie = movie.replace("A ", "");
+                    }
+                    // Returning true indicates this row should be shown.
+                    matches = p.matcher(movie).matches();
+                }
+                List persons = candidate.getPersons();
+                for (String person : persons) {
+                    if (p.matcher(person).matches()) {
+                        matches = true;
+                    }
+                }
+                return matches;
+            }
+        };
+        //
+    }
+
+    public void setShowOnlyWinners(boolean showOnlyWinners) {
+        boolean oldShowOnlyWinners = this.showOnlyWinners;
+        this.showOnlyWinners = showOnlyWinners;
+        configureFilters();
+        tableStatus.setText(statusLabelString + oscarTable.getRowCount());
+        firePropertyChange("showOnlyWinners", oldShowOnlyWinners, showOnlyWinners);
+    }
+
+    public boolean getShowOnlyWinners() {
+        return showOnlyWinners;
+    }
+
+    public void setFilterString(String filterString) {
+        String oldFilterString = this.filterString;
+        this.filterString = filterString;
+        configureFilters();
+        firePropertyChange("filterString", oldFilterString, filterString);
+    }
+
+    protected boolean hasFilterString() {
+        return filterString != null && !filterString.equals("");
+    }
+
+    protected void configureFilters() {
+        if (showOnlyWinners && hasFilterString()) {
+            List> filters =
+                    new ArrayList>(2);
+            filters.add(winnerFilter);
+            filters.add(searchFilter);
+            RowFilter comboFilter = RowFilter.andFilter(filters);
+            sorter.setRowFilter(comboFilter);
+        } else if (showOnlyWinners) {
+            sorter.setRowFilter(winnerFilter);
+        } else if (hasFilterString()) {
+            sorter.setRowFilter(searchFilter);
+        } else {
+            sorter.setRowFilter(null);
+        }
+        tableStatus.setText((hasFilterString() ? searchLabelString : statusLabelString)
+                + oscarTable.getRowCount());
+
+    }
+
+    private class ShowWinnersListener implements ChangeListener {
+        public void stateChanged(ChangeEvent event) {
+            setShowOnlyWinners(winnersCheckbox.isSelected());
+        }
+    }
+
+    //Setup search filter
+    protected class SearchFilterListener implements DocumentListener {
+        protected void changeFilter(DocumentEvent event) {
+            Document document = event.getDocument();
+            try {
+                setFilterString(document.getText(0, document.getLength()));
+
+            } catch (Exception ex) {
+                ex.printStackTrace();
+                System.err.println(ex);
+            }
+        }
+
+        public void changedUpdate(DocumentEvent e) {
+            changeFilter(e);
+        }
+
+        public void insertUpdate(DocumentEvent e) {
+            changeFilter(e);
+        }
+
+        public void removeUpdate(DocumentEvent e) {
+            changeFilter(e);
+        }
+    }
+    //
+
+    //Use SwingWorker to asynchronously load the data
+
+    public void loadData(String dataPath) {
+        // create SwingWorker which will load the data on a separate thread
+        OscarDataLoader loader = new OscarDataLoader(
+                TableDemo.class.getResource(dataPath), oscarModel);
+
+        actionStatus.setText(getString("TableDemo.loadingStatusLabel",
+                "Loading data: "));
+
+        // display progress bar while data loads
+        final JProgressBar progressBar = new JProgressBar();
+        statusBarLeft.add(progressBar);
+        loader.addPropertyChangeListener(new PropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                if (event.getPropertyName().equals("progress")) {
+                    int progress = ((Integer) event.getNewValue()).intValue();
+                    progressBar.setValue(progress);
+
+                    if (progress == 100) {
+                        statusBarLeft.remove(progressBar);
+                        actionStatus.setText("");
+                        revalidate();
+                    }
+                }
+            }
+        });
+        loader.execute();
+
+    }
+    //
+
+    protected void showMessage(String title, String message) {
+        JOptionPane.showMessageDialog(this, message, title, JOptionPane.INFORMATION_MESSAGE);
+    }
+
+    //Use SwingWorker to asynchronously load the data
+    private class OscarDataLoader extends javax.swing.SwingWorker, OscarCandidate> {
+        private final URL oscarData;
+        private final OscarTableModel oscarModel;
+        private final List candidates = new ArrayList();
+        private JLabel credits;
+
+        private OscarDataLoader(URL oscarURL, OscarTableModel oscarTableModel) {
+            this.oscarData = oscarURL;
+            this.oscarModel = oscarTableModel;
+        }
+
+        @Override
+        public List doInBackground() {
+            OscarDataParser parser = new OscarDataParser() {
+                @Override
+                protected void addCandidate(OscarCandidate candidate) {
+                    candidates.add(candidate);
+                    if (candidates.size() % 3 == 0) {
+                        try { // slow it down so we can see progress :-)
+                            Thread.sleep(1);
+                        } catch (Exception ex) {
+                        }
+                    }
+                    publish(candidate);
+                    setProgress(100 * candidates.size() / 524);
+                }
+            };
+            parser.parseDocument(oscarData);
+            return candidates;
+        }
+
+        // for OS X older Java 6
+        /*
+        protected void process(List... moreCandidates) {
+            for(List newCandidates: moreCandidates) {
+                oscarModel.add(newCandidates);
+            }
+        }*/
+
+        //@Override
+
+        protected void process(List moreCandidates) {
+            if (credits == null) {
+                showCredits();
+            }
+            oscarModel.add(moreCandidates);
+        }
+
+        // For older Java 6 on OS X
+        protected void process(OscarCandidate... moreCandidates) {
+            for (OscarCandidate candidate : moreCandidates) {
+                oscarModel.add(candidate);
+            }
+        }
+
+        private void showCredits() {
+            credits = new JLabel(getString("TableDemo.credits",
+                    "

Academy Award data
courtesy of Howard Katz

")); + credits.setFont(UIManager.getFont("Table.font").deriveFont(24f)); + credits.setHorizontalAlignment(JLabel.CENTER); + credits.setBorder(new CompoundBorder(new TitledBorder(""), + new EmptyBorder(20,20,20,20))); + } + @Override + protected void done() { + setProgress(100); + } + + } + //
+ + private class IMDBLinkAction extends AbstractAction { + + public void actionPerformed(ActionEvent event) { + int row = ((Integer) event.getSource()).intValue(); + OscarCandidate candidate = oscarModel.getCandidate(oscarTable.convertRowIndexToModel(row)); + + try { + URI imdbURI = candidate.getIMDBMovieURI(); + if (imdbURI == null) { + String imdbString = IMDBLink.getMovieURIString(candidate.getMovieTitle(), + candidate.getYear()); + if (imdbString != null) { + imdbURI = new URI(imdbString); + candidate.setIMDBMovieURI(imdbURI); + } + } + if (imdbURI != null) { + DemoUtilities.browse(imdbURI); + } else { + showMessage("IMDB Link", + getString("TableDemo.imdbLinkNotFound", + "Unable to locate IMDB URL for") + "\n" + + candidate.getMovieTitle()); + } + + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + public static void main(String args[]) { + + javax.swing.SwingUtilities.invokeLater(new Runnable() { + public void run() { + JFrame frame = new JFrame("JTable Demo"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + TableDemo demo = new TableDemo(); + frame.add(demo); + frame.setSize(700, 400); + frame.setVisible(true); + demo.start(); + } + }); + } +} diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/TableDemo.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/TableDemo.properties Fri Mar 23 18:44:47 2018 +0000 @@ -0,0 +1,22 @@ +# Table Demo Properties + +TableDemo.accessible_description=Advanced Table Demo +TableDemo.name=Advanced Table Demo +TableDemo.title=Academy Awards Results +TableDemo.credits=

Academy Award data
courtesy of Howard Katz

+ +TableDemo.searchLabel=Search Titles and Recipients +TableDemo.winnersLabel=Show Only Winners + +TableDemo.noDataStatusLabel=No data loaded +TableDemo.loadingStatusLabel=Loading data: +TableDemo.rowCountLabel=Showing +TableDemo.searchCountLabel=Search found + +TableDemo.yearColumnTitle=Year +TableDemo.categoryColumnTitle=Award Category +TableDemo.movieTitleColumnTitle=Movie Title +TableDemo.nomineesColumnTitle=Nominee(s) + +TableDemo.imdbLinkNotFound=Unable to locate IMDB URL for + diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/bestpicture --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/bestpicture Fri Mar 23 18:44:47 2018 +0000 @@ -0,0 +1,397 @@ + +1927/28 (1st) +OUTSTANDING PICTURE +* +Paramount Famous Lasky -- Wings + +1928/29 (2nd) +OUTSTANDING PICTURE +* +Metro-Goldwyn-Mayer -- The Broadway Melody +[NOTE: THIS IS NOT AN OFFICIAL NOMINATION. There were no announcements of nominations, no certificates of nomination or honorable mention, and only the winners (*) were revealed during the awards banquet on April 3, 1930.] + +1929/30 (3rd) +OUTSTANDING PRODUCTION +* +All Quiet on the Western Front -- Universal + +1930/31 (4th) +OUTSTANDING PRODUCTION +* +Cimarron -- RKO Radio + +1931/32 (5th) +OUTSTANDING PRODUCTION +* +Grand Hotel -- Metro-Goldwyn-Mayer + +1932/33 (6th) +OUTSTANDING PRODUCTION +* +Cavalcade -- Fox + +1934 (7th) +OUTSTANDING PRODUCTION +* +It Happened One Night -- Columbia + +1935 (8th) +OUTSTANDING PRODUCTION +* +Mutiny on the Bounty -- Metro-Goldwyn-Mayer + +1936 (9th) +OUTSTANDING PRODUCTION +* +The Great Ziegfeld -- Metro-Goldwyn-Mayer + +1937 (10th) +OUTSTANDING PRODUCTION +* +The Life of Emile Zola -- Warner Bros. + +1938 (11th) +OUTSTANDING PRODUCTION +* +You Can't Take It with You -- Columbia + +1939 (12th) +OUTSTANDING PRODUCTION +* +Gone with the Wind -- Selznick International Pictures + +1940 (13th) +OUTSTANDING PRODUCTION +* +Rebecca -- Selznick International Pictures + +1941 (14th) +OUTSTANDING MOTION PICTURE +* +How Green Was My Valley -- 20th Century-Fox + +1942 (15th) +OUTSTANDING MOTION PICTURE +* +Mrs. Miniver -- Metro-Goldwyn-Mayer + +1943 (16th) +OUTSTANDING MOTION PICTURE +* +Casablanca -- Warner Bros. + +1944 (17th) +BEST MOTION PICTURE +* +Going My Way -- Paramount + +1945 (18th) +BEST MOTION PICTURE +* +The Lost Weekend -- Paramount + +1946 (19th) +BEST MOTION PICTURE +* +The Best Years of Our Lives -- Samuel Goldwyn Productions + +1947 (20th) +BEST MOTION PICTURE +* +Gentleman's Agreement -- 20th Century-Fox + +1948 (21st) +BEST MOTION PICTURE +* +Hamlet -- J. Arthur Rank-Two Cities Films + +1949 (22nd) +BEST MOTION PICTURE +* +All the King's Men -- Robert Rossen Productions + +1950 (23rd) +BEST MOTION PICTURE +* +All about Eve -- 20th Century-Fox + +1951 (24th) +BEST MOTION PICTURE +* +An American in Paris -- Arthur Freed, Producer + +1952 (25th) +BEST MOTION PICTURE +* +The Greatest Show on Earth -- Cecil B. DeMille, Producer + +1953 (26th) +BEST MOTION PICTURE +* +From Here to Eternity -- Buddy Adler, Producer + +1954 (27th) +BEST MOTION PICTURE +* +On the Waterfront -- Sam Spiegel, Producer + +1955 (28th) +BEST MOTION PICTURE +* +Marty -- Harold Hecht, Producer + +1956 (29th) +BEST MOTION PICTURE +* +Around the World in 80 Days -- Michael Todd, Producer + +1957 (30th) +BEST MOTION PICTURE +* +The Bridge on the River Kwai -- Sam Spiegel, Producer + +1958 (31st) +BEST MOTION PICTURE +* +Gigi -- Arthur Freed, Producer + +1959 (32nd) +BEST MOTION PICTURE +* +Ben-Hur -- Sam Zimbalist, Producer + +1960 (33rd) +BEST MOTION PICTURE +* +The Apartment -- Billy Wilder, Producer + +1961 (34th) +BEST MOTION PICTURE +* +West Side Story -- Robert Wise, Producer + +1962 (35th) +BEST PICTURE +* +Lawrence of Arabia -- Sam Spiegel, Producer + +1963 (36th) +BEST PICTURE +* +Tom Jones -- Tony Richardson, Producer + +1964 (37th) +BEST PICTURE +* +My Fair Lady -- Jack L. Warner, Producer + +1965 (38th) +BEST PICTURE +* +The Sound of Music -- Robert Wise, Producer + +1966 (39th) +BEST PICTURE +* +A Man for All Seasons -- Fred Zinnemann, Producer + +1967 (40th) +BEST PICTURE +* +In the Heat of the Night -- Walter Mirisch, Producer + +1968 (41st) +BEST PICTURE +* +Oliver! -- John Woolf, Producer + +1969 (42nd) +BEST PICTURE +* +Midnight Cowboy -- Jerome Hellman, Producer + +1970 (43rd) +BEST PICTURE +* +Patton -- Frank McCarthy, Producer + +1971 (44th) +BEST PICTURE +* +The French Connection -- Philip D'Antoni, Producer + +1972 (45th) +BEST PICTURE +* +The Godfather -- Albert S. Ruddy, Producer + +1973 (46th) +BEST PICTURE +* +The Sting -- Tony Bill, Michael Phillips and Julia Phillips, Producers + +1974 (47th) +BEST PICTURE +* +The Godfather Part II -- Francis Ford Coppola, Producer; Gray Frederickson and Fred Roos, Co-Producers + +1975 (48th) +BEST PICTURE +* +One Flew over the Cuckoo's Nest -- Saul Zaentz and Michael Douglas, Producers + +1976 (49th) +BEST PICTURE +* +Rocky -- Irwin Winkler and Robert Chartoff, Producers + +1977 (50th) +BEST PICTURE +* +Annie Hall -- Charles H. Joffe, Producer + +1978 (51st) +BEST PICTURE +* +The Deer Hunter -- Barry Spikings, Michael Deeley, Michael Cimino and John Peverall, Producers + +1979 (52nd) +BEST PICTURE +* +Kramer vs. Kramer -- Stanley R. Jaffe, Producer + +1980 (53rd) +BEST PICTURE +* +Ordinary People -- Ronald L. Schwary, Producer + +1981 (54th) +BEST PICTURE +* +Chariots of Fire -- David Puttnam, Producer + +1982 (55th) +BEST PICTURE +* +Gandhi -- Richard Attenborough, Producer + +1983 (56th) +BEST PICTURE +* +Terms of Endearment -- James L. Brooks, Producer + +1984 (57th) +BEST PICTURE +* +Amadeus -- Saul Zaentz, Producer + +1985 (58th) +BEST PICTURE +* +Out of Africa -- Sydney Pollack, Producer + +1986 (59th) +BEST PICTURE +* +Platoon -- Arnold Kopelson, Producer + +1987 (60th) +BEST PICTURE +* +The Last Emperor -- Jeremy Thomas, Producer + +1988 (61st) +BEST PICTURE +* +Rain Man -- Mark Johnson, Producer + +1989 (62nd) +BEST PICTURE +* +Driving Miss Daisy -- Richard D. Zanuck and Lili Fini Zanuck, Producers + +1990 (63rd) +BEST PICTURE +* +Dances With Wolves -- Jim Wilson and Kevin Costner, Producers + +1991 (64th) +BEST PICTURE +* +The Silence of the Lambs -- Edward Saxon, Kenneth Utt and Ron Bozman, Producers + +1992 (65th) +BEST PICTURE +* +Unforgiven -- Clint Eastwood, Producer + +1993 (66th) +BEST PICTURE +* +Schindler's List -- Steven Spielberg, Gerald R. Molen and Branko Lustig, Producers + +1994 (67th) +BEST PICTURE +* +Forrest Gump -- Wendy Finerman, Steve Tisch and Steve Starkey, Producers + +1995 (68th) +BEST PICTURE +* +Braveheart -- Mel Gibson, Alan Ladd, Jr. and Bruce Davey, Producers + +1996 (69th) +BEST PICTURE +* +The English Patient -- Saul Zaentz, Producer + +1997 (70th) +BEST PICTURE +* +Titanic -- James Cameron and Jon Landau, Producers + +1998 (71st) +BEST PICTURE +* +Shakespeare in Love -- David Parfitt, Donna Gigliotti, Harvey Weinstein, Edward Zwick and Marc Norman, Producers + +1999 (72nd) +BEST PICTURE +* +American Beauty -- Bruce Cohen and Dan Jinks, Producers + +2000 (73rd) +BEST PICTURE +* +Gladiator -- Douglas Wick, David Franzoni and Branko Lustig, Producers + +2001 (74th) +BEST PICTURE +* +A Beautiful Mind -- Brian Grazer and Ron Howard, Producers + +2002 (75th) +BEST PICTURE +* +Chicago -- Martin Richards, Producer + +2003 (76th) +BEST PICTURE +* +The Lord of the Rings: The Return of the King -- Barrie M. Osborne, Peter Jackson and Fran Walsh, Producers + +2004 (77th) +BEST PICTURE +* +Million Dollar Baby -- Clint Eastwood, Albert S. Ruddy and Tom Rosenberg, Producers + +2005 (78th) +BEST PICTURE +* +Crash -- Paul Haggis and Cathy Schulman, Producers + +2006 (79th) +BEST PICTURE +* +The Departed -- Graham King, Producer +© Academy of Motion Picture Arts and Sciences \ No newline at end of file diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/images/TableDemo.gif Binary file test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/images/TableDemo.gif has changed diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/images/goldstar.png Binary file test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/images/goldstar.png has changed diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/images/nominee.png Binary file test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/images/nominee.png has changed diff -r eb72d194235c -r 514c68575523 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/oscars.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/table/resources/oscars.xml Fri Mar 23 18:44:47 2018 +0000 @@ -0,0 +1,1 @@ +

This data has been marked up in XML and placed into the public domain by Howard Katz,

Fatdog Software Inc., 2006. It may be freely copied and distributed worldwide.

The Last Command The Way of All Flesh Emil Jannings The Noose The Patent Leather Kid Richard Barthelmess The Circus Charles Chaplin 7th Heaven Street Angel Sunrise Janet Gaynor A Ship Comes in Louise Dresser Sadie Thompson Gloria Swanson The Dove The Tempest William Cameron Menzies 7th Heaven Harry Oliver Sunrise Rochus Gliese Wings Paramount Famous Lasky 7th Heaven Fox The Racket The Caddo Company Sunrise Charles Rosher Karl Struss The Devil Dancer The Magic Flame Sadie Thompson George Barnes Two Arabian Knights Lewis Milestone Speedy Ted Wilde 7th Heaven Frank Borzage The Crowd King Vidor Sorrell and Son Herbert Brenon Wings Roy Pomeroy Ralph Hammeras Nugent Slaughter Sunrise Fox Chang Paramount Famous Lasky The Crowd Metro-Goldwyn-Mayer 7th Heaven Benjamin Glazer Glorious Betsy Anthony Coldeway The Jazz Singer Alfred Cohn Underworld Ben Hecht The Last Command Lajos Biro Joseph Farnham George Marion Jr. The Private Life of Helen of Troy Gerald Duffy In Old Arizona Warner Baxter Thunderbolt George Bancroft Alibi Chester Morris The Valiant Paul Muni The Patriot Lewis Stone Coquette Mary Pickford Madame X Ruth Chatterton The Barker Betty Compson The Letter Jeanne Eagels The Divine Lady Corinne Griffith The Broadway Melody Bessie Love The Bridge of San Luis Rey Cedric Gibbons Alibi The Awakening William Cameron Menzies Dynamite Mitchell Leisen The Patriot Hans Dreier Street Angel Harry Oliver The Broadway Melody Metro-Goldwyn-Mayer Alibi Art Cinema Hollywood Revue Metro-Goldwyn-Mayer In Old Arizona Fox The Patriot Paramount Famous Lasky White Shadows in the South Seas Clyde De Vinna The Divine Lady John Seitz Four Devils Street Angel Ernest Palmer In Old Arizona Arthur Edeson Our Dancing Daughters George Barnes The Divine Lady Frank Lloyd The Broadway Melody Harry Beaumont Drag Frank Lloyd In Old Arizona Irving Cummings Madame X Lionel Barrymore The Patriot Ernst Lubitsch Weary River Frank Lloyd The Patriot Hans Kraly The Cop Elliott Clawson In Old Arizona Tom Barry The Last of Mrs. Cheyney Hans Kraly The Leatherneck Elliott Clawson Our Dancing Daughters Josephine Lovett Sal of Singapore Elliott Clawson Skyscraper Elliott Clawson The Valiant Tom Barry A Woman of Affairs Bess Meredyth Wonder of Women Bess Meredyth Disraeli George Arliss The Green Goddess George Arliss The Big House Wallace Beery The Big Pond Maurice Chevalier The Love Parade Maurice Chevalier Bulldog Drummond Ronald Colman Condemned Ronald Colman The Rogue Song Lawrence Tibbett The Divorcee Norma Shearer The Devil's Holiday Nancy Carroll Sarah and Son Ruth Chatterton Anna Christie Greta Garbo Romance Greta Garbo Their Own Desire Norma Shearer The Trespasser Gloria Swanson King of Jazz Herman Rosse Bulldog Drummond William Cameron Menzies The Love Parade Hans Dreier Sally Jack Okey The Vagabond King Hans Dreier All Quiet on the Western Front Universal The Big House Cosmopolitan Disraeli Warner Bros. The Divorcee Metro-Goldwyn-Mayer The Love Parade Paramount Famous Lasky With Byrd at the South Pole Joseph T. Rucker Willard Van Der Veer All Quiet on the Western Front Arthur Edeson Anna Christie William Daniels Hell's Angels Gaetano Gaudio) Harry Perry The Love Parade Victor Milner All Quiet on the Western Front Lewis Milestone Anna Christie Clarence Brown The Divorcee Robert Leonard Hallelujah King Vidor The Love Parade Ernst Lubitsch Romance Clarence Brown The Big House Metro-Goldwyn-Mayer Studio Sound Department Douglas Shearer The Case of Sergeant Grischa RKO Radio Studio Sound Department John Tribby The Love Parade Paramount Famous Lasky Studio Sound Department Franklin Hansen Raffles United Artists Studio Sound Department Oscar Lagerstrom Song of the Flame First National Studio Sound Department George Groves The Big House Frances Marion All Quiet on the Western Front George Abbott Maxwell Anderson Del Andrews Disraeli Julian Josephson The Divorcee John Meehan Street of Chance Howard Estabrook A Free Soul Lionel Barrymore Skippy Jackie Cooper Cimarron Richard Dix The Royal Family of Broadway Fredric March The Front Page Adolphe Menjou Min and Bill Marie Dressler Morocco Marlene Dietrich Cimarron Irene Dunne Holiday Ann Harding A Free Soul Norma Shearer Cimarron Max Ree Just Imagine Stephen Goosson Ralph Hammeras Morocco Hans Dreier Svengali Anton Grot Whoopee! Richard Day Cimarron RKO Radio East Lynne Fox The Front Page The Caddo Company Skippy Paramount Publix Trader Horn Metro-Goldwyn-Mayer Tabu Floyd Crosby Cimarron Edward Cronjager Morocco Lee Garmes The Right to Love Charles Lang Svengali Barney "Chick" McGill Skippy Norman Taurog Cimarron Wesley Ruggles A Free Soul Clarence Brown The Front Page Lewis Milestone Morocco Josef Von Sternberg Samuel Goldwyn - United Artists Studio Sound Department Metro-Goldwyn-Mayer Studio Sound Department Paramount Publix Studio Sound Department RKO Radio Studio Sound Department Cimarron Howard Estabrook The Criminal Code Seton I. Miller Fred Niblo Jr. Holiday Horace Jackson Little Caesar Francis Faragoh Robert N. Lee Skippy Joseph L. Mankiewicz Sam Mintz The Dawn Patrol John Monk Saunders The Doorway to Hell Rowland Brown Laughter Harry d'Abbadie d'Arrast Douglas Doty Donald Ogden Stewart The Public Enemy John Bright Kubec Glasmon Smart Money Lucien Hubbard Joseph Jackson The Champ Wallace Beery Dr. Jekyll and Mr. Hyde Fredric March The Guardsman Alfred Lunt The Sin of Madelon Claudet Helen Hayes Emma Marie Dressler The Guardsman Lynn Fontanne Transatlantic Gordon Wiles Arrowsmith Richard Day A Nous La Liberte Lazare Meerson Grand Hotel Metro-Goldwyn-Mayer Arrowsmith Samuel Goldwyn Bad Girl Fox The Champ Metro-Goldwyn-Mayer Five Star Final First National One Hour with You Paramount Publix Shanghai Express Paramount Publix The Smiling Lieutenant Paramount Publix Shanghai Express Lee Garmes Arrowsmith Ray June Dr. Jekyll and Mr. Hyde Karl Struss Bad Girl Frank Borzage The Champ King Vidor Shanghai Express Josef Von Sternberg Flowers and Trees Walt Disney It's Got Me Again Leon Schlesinger Mickey's Orphans Walt Disney The Music Box Hal Roach The Loud Mouth Mack Sennett Scratch-As-Catch-Can RKO Radio Stout Hearts and Willing Hands RKO Radio Wrestling Swordfish Mack Sennett Screen Souvenirs Paramount Publix Swing High Metro-Goldwyn-Mayer Metro-Goldwyn-Mayer Studio Sound Department Paramount Publix Studio Sound Department RKO Radio Studio Sound Department Warner Bros.-First National Studio Sound Department Bad Girl Edwin Burke Arrowsmith Sidney Howard Dr. Jekyll and Mr. Hyde Percy Heath Samuel Hoffenstein The Champ Frances Marion Lady and Gent Grover Jones William Slavens McNutt The Star Witness Lucien Hubbard What Price Hollywood? Jane Murfin Adela Rogers St. Johns The Private Life of Henry VIII Charles Laughton Berkeley Square Leslie Howard I Am a Fugitive from a Chain Gang Paul Muni Morning Glory Katharine Hepburn Lady for a Day May Robson Cavalcade Diana Wynyard Cavalcade William S. Darling A Farewell to Arms Roland Anderson Hans Dreier When Ladies Meet Cedric Gibbons Charles Barton Scott Beal Charles Dorian Fred Fox Gordon Hollingshead Dewey Starkey William Tummel Al Alborn Sidney S. Brod Bunny Dull Percy Ikerd Arthur Jacobson Eddie Killey Joe McDonough W. J. Reiter Frank X. Shaw Benjamin Silvey John S. Waters Cavalcade Fox 42nd Street Warner Bros. A Farewell to Arms Paramount I Am a Fugitive from a Chain Gang Warner Bros. Lady for a Day Columbia Little Women RKO Radio The Private Life of Henry VIII London Films She Done Him Wrong Paramount Smilin' Through Metro-Goldwyn-Mayer State Fair Fox A Farewell to Arms Charles Bryant Lang Jr. Reunion in Vienna George J. Folsey The Sign of the Cross Karl Struss Cavalcade Frank Lloyd Lady for a Day Frank Capra Little Women George Cukor The Three Little Pigs Walt Disney Building a Building Walt Disney The Merry Old Soul Walter Lantz So This Is Harris Louis Brock Mister Mugg Warren Doane A Preferred List Louis Brock Krakatoa Joe Rock Menu Pete Smith The Sea Educational A Farewell to Arms Paramount Studio Sound Department Franklin B. Hansen 42nd Street Warner Bros. Studio Sound Department Nathan Levinson Gold Diggers of 1933 Warner Bros. Studio Sound Department Nathan Levinson I Am a Fugitive from a Chain Gang Warner Bros. Studio Sound Department Nathan Levinson Little Women Victor Heerman Sarah Y. Mason Lady for a Day Robert Riskin State Fair Paul Green Sonya Levien One Way Passage Robert Lord The Prizefighter and the Lady Frances Marion Rasputin and the Empress Charles MacArthur It Happened One Night Clark Gable The Affairs of Cellini Frank Morgan The Thin Man William Powell It Happened One Night Claudette Colbert Of Human Bondage Bette Davis One Night of Love Grace Moore The Barretts of Wimpole Street Norma Shearer The Merry Widow Cedric Gibbons Frederic Hope The Affairs of Cellini Richard Day The Gay Divorcee Carroll Clark Van Nest Polglase Viva Villa! John Waters Cleopatra Cullen Tate Imitation of Life Scott Beal It Happened One Night Columbia The Barretts of Wimpole Street Metro-Goldwyn-Mayer Cleopatra Paramount Flirtation Walk First National The Gay Divorcee RKO Radio Here Comes the Navy Warner Bros. The House of Rothschild 20th Century Imitation of Life Universal One Night of Love Columbia The Thin Man Metro-Goldwyn-Mayer Viva Villa! Metro-Goldwyn-Mayer The White Parade Jesse L. Lasky Cleopatra Victor Milner The Affairs of Cellini Charles Rosher Operator 13 George Folsey It Happened One Night Frank Capra One Night of Love Victor Schertzinger The Thin Man W. S. Van Dyke Eskimo Conrad Nervig Cleopatra Anne Bauchens One Night of Love Gene Milford One Night of Love Columbia Studio Music Department Louis Silvers Gus Kahn Victor Schertzinger The Gay Divorcee RKO Radio Studio Music Department Samuel Hoffenstein Max Steiner Kenneth Webb The Lost Patrol RKO Radio Studio Music Department Max Steiner Captain Blood Warner Bros.-First National Studio Music Department Erich Wolfgang Korngold Leo Forbstein Mutiny on the Bounty Metro-Goldwyn-Mayer Studio Music Department Nat W. Finston Herbert Stothart Peter Ibbetson Paramount Studio Music Department Irvin Talbot Ernst Toch The Continental The Gay Divorcee Con Conrad Herb Magidson Carioca Flying Down to Rio Edward Eliscu Gus Kahn Vincent Youmans Love in Bloom She Loves Me Not Ralph Rainger Leo Robin The Tortoise and the Hare Walt Disney Holiday Land Charles Mintz Jolly Little Elves Walter Lantz La Cucaracha Kenneth Macgowan Men in Black Jules White What, No Men! Warner Bros. City of Wax Horace Woodard Stacy Woodard Bosom Friends Skibo Productions Strikes and Spares Pete Smith One Night of Love Columbia Studio Sound Department John Livadary The Affairs of Cellini United Artists Studio Sound Department Thomas T. Moulton Cleopatra Paramount Studio Sound Department Franklin B. Hansen Flirtation Walk Warner Bros.-First National Studio Sound Department Nathan Levinson The Gay Divorcee RKO Radio Studio Sound Department Carl Dreher Imitation of Life Universal Studio Sound Department Theodore Soderberg Viva Villa! Metro-Goldwyn-Mayer Studio Sound Department Douglas Shearer The White Parade Fox Studio Sound Department E. H. Hansen It Happened One Night Robert Riskin The Thin Man Frances Goodrich Albert Hackett Viva Villa! Ben Hecht Manhattan Melodrama Arthur Caesar Hide-Out Mauri Grashin The Richest Girl in the World Norman Krasna The Informer Victor McLaglen Mutiny on the Bounty Clark Gable Mutiny on the Bounty Charles Laughton Black Fury Paul Muni Mutiny on the Bounty Franchot Tone Dangerous Bette Davis Escape Me Never Elisabeth Bergner Private Worlds Claudette Colbert Alice Adams Katharine Hepburn Becky Sharp Miriam Hopkins The Dark Angel Merle Oberon The Dark Angel Richard Day The Lives of a Bengal Lancer Roland Anderson Hans Dreier Top Hat Carroll Clark Van Nest Polglase The Lives of a Bengal Lancer Clem Beauchamp Paul Wing David Copperfield Joseph Newman Les Miserables Eric Stacey A Midsummer Night's Dream Sherry Shourds Mutiny on the Bounty Metro-Goldwyn-Mayer Alice Adams RKO Radio Broadway Melody of 1936 Metro-Goldwyn-Mayer Captain Blood Cosmopolitan David Copperfield Metro-Goldwyn-Mayer The Informer RKO Radio Les Miserables 20th Century The Lives of a Bengal Lancer Paramount A Midsummer Night's Dream Warner Bros. Naughty Marietta Metro-Goldwyn-Mayer Ruggles of Red Gap Paramount Top Hat RKO Radio A Midsummer Night's Dream Hal Mohr Barbary Coast Ray June The Crusades Victor Milner Les Miserables Gregg Toland Broadway Melody of 1936 Folies Bergere Dave Gould All the King's Horses Big Broadcast of 1936 LeRoy Prinz Broadway Hostess Go Into Your Dance Bobby Connolly Gold Diggers of 1935 Busby Berkeley King of Burlesque Sammy Lee Top Hat Hermes Pan She Benjamin Zemach The Informer John Ford Captain Blood Michael Curtiz The Lives of a Bengal Lancer Henry Hathaway Mutiny on the Bounty Frank Lloyd A Midsummer Night's Dream Ralph Dawson David Copperfield Robert J. Kern The Informer George Hively Les Miserables Barbara McLean The Lives of a Bengal Lancer Ellsworth Hoagland Mutiny on the Bounty Margaret Booth The Informer RKO Radio Studio Music Department Max Steiner Lullaby of Broadway Gold Diggers of 1935 Al Dubin Harry Warren Cheek to Cheek Top Hat Irving Berlin Lovely to Look at Roberta Dorothy Fields Jerome Kern Jimmy McHugh Three Orphan Kittens Walt Disney The Calico Dragon Harman-Ising Who Killed Cock Robin? Walt Disney How To Sleep Jack Chertok Oh, My Nerves Jules White Tit for Tat Hal Roach Wings Over Mt. Everest Gaumont British and Skibo Productions Audioscopiks Pete Smith Camera Thrills Universal Naughty Marietta Metro-Goldwyn-Mayer Studio Sound Department Douglas Shearer $1,000 a Minute Republic Studio Sound Department The Bride of Frankenstein Universal Studio Sound Department Gilbert Kurland Captain Blood Warner Bros.-First National Studio Sound Department Nathan Levinson The Dark Angel United Artists Studio Sound Department Thomas T. Moulton I Dream Too Much RKO Radio Studio Sound Department Carl Dreher The Lives of a Bengal Lancer Paramount Studio Sound Department Franklin B. Hansen Love Me Forever Columbia Studio Sound Department John Livadary Thanks a Million 20th Century-Fox Studio Sound Department E. H. Hansen The Scoundrel Ben Hecht Charles MacArthur Broadway Melody of 1936 Moss Hart G-Men Gregory Rogers The Gay Deception Stephen Avery Don Hartman The Informer Dudley Nichols Captain Blood Casey Robinson The Lives of a Bengal Lancer Achmed Abdullah John L. Balderston Grover Jones William Slavens McNutt Waldemar Young Mutiny on the Bounty Jules Furthman Talbot Jennings Carey Wilson The Story of Louis Pasteur Paul Muni Mr. Deeds Goes to Town Gary Cooper Dodsworth Walter Huston My Man Godfrey William Powell San Francisco Spencer Tracy Come and Get It Walter Brennan My Man Godfrey Mischa Auer Pigskin Parade Stuart Erwin Romeo and Juliet Basil Rathbone The General Died at Dawn Akim Tamiroff The Great Ziegfeld Luise Rainer Theodora Goes Wild Irene Dunne Valiant Is the Word for Carrie Gladys George My Man Godfrey Carole Lombard Romeo and Juliet Norma Shearer Anthony Adverse Gale Sondergaard The Gorgeous Hussy Beulah Bondi My Man Godfrey Alice Brady These Three Bonita Granville Dodsworth Maria Ouspenskaya Dodsworth Richard Day Anthony Adverse Anton Grot The Great Ziegfeld Cedric Gibbons Eddie Imazu Edwin B. Willis Lloyds of London William S. Darling The Magnificent Brute Albert S. D'Agostino Jack Otterson Romeo and Juliet Cedric Gibbons Frederic Hope Edwin B. Willis Winterset Perry Ferguson The Charge of the Light Brigade Jack Sullivan Anthony Adverse William Cannon The Garden of Allah Eric G. Stacey The Last of the Mohicans Clem Beauchamp San Francisco Joseph Newman The Great Ziegfeld Metro-Goldwyn-Mayer Anthony Adverse Warner Bros. Dodsworth Samuel Goldwyn Libeled Lady Metro-Goldwyn-Mayer Mr. Deeds Goes to Town Columbia Romeo and Juliet Metro-Goldwyn-Mayer San Francisco Metro-Goldwyn-Mayer The Story of Louis Pasteur Cosmopolitan A Tale of Two Cities Metro-Goldwyn-Mayer Three Smart Girls Universal Anthony Adverse Gaetano Gaudio The General Died at Dawn Victor Milner The Gorgeous Hussy George Folsey The Great Ziegfeld Seymour Felix Born to Dance Dave Gould Cain and Mabel Bobby Connolly Dancing Pirate Russell Lewis Gold Diggers of 1937 Busby Berkeley One in a Million Jack Haskell Swing Time Hermes Pan Mr. Deeds Goes to Town Frank Capra Dodsworth William Wyler The Great Ziegfeld Robert Z. Leonard My Man Godfrey Gregory La Cava San Francisco W. S. Van Dyke Anthony Adverse Ralph Dawson Come and Get It Edward Curtiss The Great Ziegfeld William S. Gray Lloyds of London Barbara McLean A Tale of Two Cities Conrad A. Nervig Theodora Goes Wild Otto Meyer Anthony Adverse Warner Bros. Studio Music Department Erich Wolfgang Korngold Leo Forbstein The Charge of the Light Brigade Max Steiner, Warner Bros. Studio Music Department Max Steiner Leo Forbstein The Garden of Allah Selznick International Pictures Music Department Max Steiner The General Died at Dawn Paramount Studio Music Department Werner Janssen Boris Morros Winterset RKO Radio Studio Music Department Nathaniel Shilkret The Way You Look Tonight Swing Time Dorothy Fields Jerome Kern A Melody from the Sky Trail of the Lonesome Pine Louis Alter Sidney Mitchell Did I Remember Suzy Harold Adamson Walter Donaldson I've Got You Under My Skin Born To Dance Cole Porter Pennies from Heaven Pennies from Heaven Johnny Burke Arthur Johnston When Did You Leave Heaven Sing, Baby, Sing Walter Bullock Richard A. Whiting The Country Cousin Walt Disney Old Mill Pond Harman-Ising Sinbad the Sailor Paramount Bored of Education Hal Roach Moscow Moods Paramount Wanted, a Master Pete Smith The Public Pays Metro-Goldwyn-Mayer Double Or Nothing Warner Bros. Dummy Ache RKO Radio Give Me Liberty Warner Bros. La Fiesta De Santa Barbara Lewis Lewyn Popular Science J-6-2 Paramount San Francisco Metro-Goldwyn-Mayer Studio Sound Department Douglas Shearer Banjo on My Knee 20th Century-Fox Studio Sound Department E. H. Hansen The Charge of the Light Brigade Warner Bros. Studio Sound Department Nathan Levinson Dodsworth United Artists Studio Sound Department Thomas T. Moulton General Spanky Hal Roach Studio Sound Department Elmer A. Raguse Mr. Deeds Goes to Town Columbia Studio Sound Department John Livadary The Texas Rangers Paramount Studio Sound Department Franklin B. Hansen That Girl from Paris Paramount Studio Sound Department J. O. Aalberg Three Smart Girls Universal Studio Sound Department Homer G. Tasker The Story of Louis Pasteur Pierre Collings Sheridan Gibney Fury Norman Krasna The Great Ziegfeld William Anthony McGuire San Francisco Robert Hopkins Three Smart Girls Adele Comandini The Story of Louis Pasteur Pierre Collings Sheridan Gibney After the Thin Man Frances Goodrich Albert Hackett Dodsworth Sidney Howard Mr. Deeds Goes to Town Robert Riskin My Man Godfrey Eric Hatch Morris Ryskind
\ No newline at end of file diff -r eb72d194235c -r 514c68575523 test/langtools/tools/javac/T8199910.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/T8199910.java Fri Mar 23 18:44:47 2018 +0000 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018, 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 8199910 + * @summary Compile variables of intersection type inferred by `var` with -g option + * @compile -g T8199910.java + */ +import java.util.List; + +class T8199910 { + T first(T... ts) { + return ts[0]; + } + + void m() { + var list1 = List.of("", 1); + var list2 = List.of(1, 2.0); + var a = first("", 1); + var b = first(1, 2.0); + } +} diff -r eb72d194235c -r 514c68575523 test/langtools/tools/javac/lvti/harness/LocalVariableInferenceTester.java --- a/test/langtools/tools/javac/lvti/harness/LocalVariableInferenceTester.java Fri Mar 23 18:01:52 2018 +0000 +++ b/test/langtools/tools/javac/lvti/harness/LocalVariableInferenceTester.java Fri Mar 23 18:44:47 2018 +0000 @@ -80,12 +80,16 @@ void compileAndCheck(JavaFileObject input) throws IOException { JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - JavacTask task = (JavacTask) c.getTask(null, fm, null, null, null, Arrays.asList(input)); + JavacTask task = (JavacTask) c.getTask(null, fm, null, Arrays.asList("-g"), null, Arrays.asList(input)); JavacTrees trees = JavacTrees.instance(task); Types types = Types.instance(((JavacTaskImpl)task).getContext()); Iterable roots = task.parse(); - task.analyze(); //force attribution Log log = Log.instance(((JavacTaskImpl)task).getContext()); + //force code generation (to shake out non-denotable issues) + boolean hasClasses = task.generate().iterator().hasNext(); + if (!hasClasses) { + throw new AssertionError("Errors occurred during compilation!"); + } errors += log.nerrors; new LocalVarTypeChecker(trees, types).scan(roots, null); System.err.println("Checks executed: " + checks);