# HG changeset patch # User duke # Date 1499281139 -7200 # Node ID d8b2864e0ec4377ebd5b3e3a9c9a5e2457e8f334 # Parent ff95a3cea444afbfca6101ba1129c816bf930fff# Parent 77273343c131ea6c4974a47cfcad36df032bd84a Merge diff -r 77273343c131 -r d8b2864e0ec4 jdk/.hgtags --- a/jdk/.hgtags Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/.hgtags Wed Jul 05 20:58:59 2017 +0200 @@ -333,3 +333,4 @@ 6e50b992bef4def597a5033e696e5b1d4fe5b294 jdk9-b88 0d0a63b325592607974612f9cfb48590975aa2d6 jdk9-b89 b433e4dfb830fea60e5187e4580791b62cc362d2 jdk9-b90 +97624df5026a2fb191793697dbd2c604c4d5c66e jdk9-b91 diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/CompileDemos.gmk --- a/jdk/make/CompileDemos.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/CompileDemos.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -23,6 +23,10 @@ # questions. # +################################################################################ +# Build demos for the JDK into $(SUPPORT_OUTPUTDIR)/demos/image. +################################################################################ + default: all include $(SPEC) @@ -31,428 +35,487 @@ include NativeCompilation.gmk include SetupJavaCompilers.gmk include TextFileProcessing.gmk +include ZipArchive.gmk # Prepare the find cache. $(eval $(call FillCacheFind, $(JDK_TOPDIR)/src)) # Append demo goals to this variable. -BUILD_DEMOS = +TARGETS = # The demo structure and contents should really be cleaned up. # Now every other demo has its own quirks where to put the # READMEs and other files. DEMO_SHARE_SRC := $(JDK_TOPDIR)/src/demo/share -DEMO_CLOSED_SHARE_SRC := $(JDK_TOPDIR)/src/closed/demo/share -DEMO_SOLARIS_SRC := $(JDK_TOPDIR)/src/demo/solaris -DEMO_OS_TYPE_SRC := $(JDK_TOPDIR)/src/demo/$(OPENJDK_TARGET_OS_TYPE) GLOBAL_VERSION_INFO_RESOURCE := $(JDK_TOPDIR)/src/java.base/windows/native/common/version.rc -################################################################################################## +DEMO_MANIFEST := $(SUPPORT_OUTPUTDIR)/demos/java-main-manifest.mf -# This rule will be depended on due to the MANIFEST line +# This rule will be depended on due to the MANIFEST line in SetupBuildDemo +# and SetupBuildJvmtiDemo. $(eval $(call SetupTextFileProcessing, BUILD_JAVA_MANIFEST, \ SOURCE_FILES := $(JDK_TOPDIR)/make/data/mainmanifest/manifest.mf, \ - OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/demo/java-main-manifest.mf, \ + OUTPUT_FILE := $(DEMO_MANIFEST), \ REPLACEMENTS := \ @@RELEASE@@ => $(RELEASE) ; \ @@COMPANY_NAME@@ => $(COMPANY_NAME) , \ )) -define SetupAppletDemo - $$(eval $$(call SetupJavaCompilation,BUILD_DEMO_APPLET_$1, \ +################################################################################ +# Build applet demos. + +# Setup make rules for building a demo applet. +# +# Parameter 1 is the name of the rule. This name is used as variable prefix, +# and the targets generated are listed in a variable by that name. It is also +# used to locate the name of the applet subdir, and to determine the name +# of the output directory. +# +# Remaining parameters are named arguments. These include: +# SRC_DIR Alternative source directory to use for the demos. +# DISABLE_SJAVAC Passed to SetupJavaCompilation + +SetupBuildAppletDemo = $(NamedParamsMacroTemplate) +define SetupBuildAppletDemoBody + ifeq ($$($1_SRC_DIR), ) + $1_SRC_DIR := $(DEMO_SHARE_SRC)/applets + endif + + $$(eval $$(call SetupJavaCompilation, BUILD_DEMO_APPLET_$1, \ SETUP := GENERATE_USINGJDKBYTECODE, \ - SRC := $(JDK_TOPDIR)/src/$3demo/share/applets/$1, \ - BIN := $(SUPPORT_OUTPUTDIR)/demo/image/applets/$1, \ + SRC := $$($1_SRC_DIR)/$1, \ + BIN := $(SUPPORT_OUTPUTDIR)/demos/image/applets/$1, \ COPY := .html .java .xyz .obj .au .gif, \ - DISABLE_SJAVAC := $2)) - BUILD_DEMOS += $$(BUILD_DEMO_APPLET_$1) + DISABLE_SJAVAC := $$($1_DISABLE_SJAVAC), \ + )) + + $1 := $$(BUILD_DEMO_APPLET_$1) + + TARGETS += $$($1) endef ifneq ($(OPENJDK_TARGET_OS), solaris) - $(eval $(call SetupAppletDemo,ArcTest)) - $(eval $(call SetupAppletDemo,BarChart)) - $(eval $(call SetupAppletDemo,Blink)) - $(eval $(call SetupAppletDemo,CardTest)) - $(eval $(call SetupAppletDemo,Clock)) - $(eval $(call SetupAppletDemo,DitherTest)) - $(eval $(call SetupAppletDemo,DrawTest)) - $(eval $(call SetupAppletDemo,Fractal)) - $(eval $(call SetupAppletDemo,GraphicsTest)) - $(eval $(call SetupAppletDemo,NervousText)) - $(eval $(call SetupAppletDemo,SimpleGraph)) - $(eval $(call SetupAppletDemo,SortDemo)) - $(eval $(call SetupAppletDemo,SpreadSheet)) - - ifndef OPENJDK - $(eval $(call SetupAppletDemo,Animator,,closed/)) - $(eval $(call SetupAppletDemo,GraphLayout,true,closed/)) - $(eval $(call SetupAppletDemo,JumpingBox,,closed/)) - $(eval $(call SetupAppletDemo,TicTacToe,,closed/)) - endif + $(eval $(call SetupBuildAppletDemo, ArcTest)) + $(eval $(call SetupBuildAppletDemo, BarChart)) + $(eval $(call SetupBuildAppletDemo, Blink)) + $(eval $(call SetupBuildAppletDemo, CardTest)) + $(eval $(call SetupBuildAppletDemo, Clock)) + $(eval $(call SetupBuildAppletDemo, DitherTest)) + $(eval $(call SetupBuildAppletDemo, DrawTest)) + $(eval $(call SetupBuildAppletDemo, Fractal)) + $(eval $(call SetupBuildAppletDemo, GraphicsTest)) + $(eval $(call SetupBuildAppletDemo, NervousText)) + $(eval $(call SetupBuildAppletDemo, SimpleGraph)) + $(eval $(call SetupBuildAppletDemo, SortDemo)) + $(eval $(call SetupBuildAppletDemo, SpreadSheet)) endif -################################################################################################## +################################################################################ +# Build normal demos. -PATTERNS_TO_COPY = .html .txt .properties .js .gif .jpg .theme .data .opt README .c .h .png .ttf .xyz .obj +COPY_TO_JAR := .html .txt .properties .js .gif .jpg .theme .data .opt .c .h \ + .png .ttf .xyz .obj README COPYRIGHT + +COPY_TO_IMAGE := *.html *.txt *.png *.xml README* -define SetupDemo - # Param 1 = Name of the demo - # Param 2 = Subdirectory of the demo below the demo directory. - # Param 3 = Additional javac flags. - # Param 4 = The main class for the jar. - # Param 5 = Additional source directory. - # Param 6 = Extra dir below $(JDK_TOPDIR)/src (closed) - # Param 7 = List of files to copy - # Param 8 = Base name of jar file. Defaults to $1 - # Param 9 = Exclude list - # Param 10 = Extra copy patterns - # Param 11 = Extra manifest attribute - # Param 12 = Suffix for compiler setup name +# Setup make rules for building a demo. +# +# Parameter 1 is the name of the rule. This name is used as variable prefix, +# and the targets generated are listed in a variable by that name. +# +# Remaining parameters are named arguments. These include: +# DEMO_SUBDIR The name of the subdir of the demo, below the demo top dir. +# EXTRA_SRC_DIR Additional source directory. +# SRC_SUB_DIR Optional subdir to locate source code in +# SRC_DIR Alternative source directory to use for the demos. +# EXCLUDE_FILES Exclude file list +# JAR_NAME Base name of jar file. Defaults to $1. +# MAIN_CLASS The main class for the jar. Defaults to $1. +# EXTRA_COPY_TO_JAR Additional files to copy to jar (as patterns) +# EXTRA_COPY_TO_IMAGE Additional files to copy to images (as wildcards) +# EXTRA_MANIFEST_ATTR Extra manifest attribute +# SKIP_COMPILATION Skip Java compilation iff true +# DISABLE_SJAVAC Passed to SetupJavaCompilation +SetupBuildDemo = $(NamedParamsMacroTemplate) +define SetupBuildDemoBody + ifeq ($$($1_SRC_DIR), ) + $1_SRC_DIR := $(DEMO_SHARE_SRC) + endif - $1_SRC_BASE := $(JDK_TOPDIR)/src/$6demo/share/$2/$1 - # In some demos the source is found in a subdir called src. - $1_MAIN_SRC := $$(wildcard $$($1_SRC_BASE)/src) - ifeq ($$($1_MAIN_SRC), ) + $1_SRC_BASE := $$($1_SRC_DIR)/$$($1_DEMO_SUBDIR)/$1 + + # In some demos the source is found in a subdir + ifneq ($$($1_SRC_SUB_DIR), ) + $1_MAIN_SRC := $$($1_SRC_BASE)/$$($1_SRC_SUB_DIR) + else + # for allmost all $1_MAIN_SRC := $$($1_SRC_BASE) endif - ifneq ($8, ) - $1_JARFILE := $8.jar - else - $1_JARFILE := $1.jar + # Default is to use demo name as jar file name. + ifeq ($$($1_JAR_NAME), ) + $1_JAR_NAME := $1 endif - ifeq ($(findstring $1,Laffy SwingSet3), ) - $$(eval $$(call SetupJavaCompilation,BUILD_DEMO_$1, \ - SETUP := GENERATE_USINGJDKBYTECODE, \ - ADD_JAVAC_FLAGS := $3, \ - SRC := $$($1_MAIN_SRC) $5, \ - BIN := $(SUPPORT_OUTPUTDIR)/demo/classes/$2/$1, \ - COPY := $(PATTERNS_TO_COPY) $(10), \ - JAR := $(SUPPORT_OUTPUTDIR)/demo/image/$2/$1/$$($1_JARFILE), \ - JARMAIN := $4, \ - MANIFEST := $(SUPPORT_OUTPUTDIR)/demo/java-main-manifest.mf, \ - EXTRA_MANIFEST_ATTR := $(11), \ - SRCZIP := $(SUPPORT_OUTPUTDIR)/demo/image/$2/$1/src.zip, \ - EXCLUDE_FILES := $9, \ - DISABLE_SJAVAC := $(12))) - - BUILD_DEMOS += $$(BUILD_DEMO_$1) \ - $(SUPPORT_OUTPUTDIR)/demo/image/$2/$1/$$($1_JARFILE) \ - $(SUPPORT_OUTPUTDIR)/demo/image/$2/$1/src.zip + # Default is to use demo name as jar main class. + ifeq ($$($1_MAIN_CLASS), ) + $1_MAIN_CLASS := $1 + else ifeq ($$($1_MAIN_CLASS), NONE) + $1_MAIN_CLASS := + $1_EXTRA_MANIFEST_ATTR += Main-Class: \n endif - # Copy files. - $1_COPY_TARGETS := $$(patsubst $$($1_SRC_BASE)/%, \ - $(SUPPORT_OUTPUTDIR)/demo/image/$2/$1/%, \ - $$(wildcard $$(addprefix $$($1_SRC_BASE)/, $7))) - ifneq ($7, ) - $(SUPPORT_OUTPUTDIR)/demo/image/$2/$1/%: $$($1_SRC_BASE)/% - $$(call install-file) - $(CHMOD) -f ug+w $$@ + ifneq ($$($1_SKIP_COMPILATION), true) + $$(eval $$(call SetupJavaCompilation, BUILD_DEMO_$1, \ + SETUP := GENERATE_USINGJDKBYTECODE, \ + SRC := $$($1_MAIN_SRC) $$($1_EXTRA_SRC_DIR), \ + BIN := $(SUPPORT_OUTPUTDIR)/demos/classes/$$($1_DEMO_SUBDIR)/$1, \ + COPY := $(COPY_TO_JAR) $$($1_EXTRA_COPY_TO_JAR), \ + JAR := $(SUPPORT_OUTPUTDIR)/demos/image/$$($1_DEMO_SUBDIR)/$1/$$($1_JAR_NAME).jar, \ + JARMAIN := $$($1_MAIN_CLASS), \ + MANIFEST := $(DEMO_MANIFEST), \ + EXTRA_MANIFEST_ATTR := $$($1_EXTRA_MANIFEST_ATTR), \ + SRCZIP := $(SUPPORT_OUTPUTDIR)/demos/image/$$($1_DEMO_SUBDIR)/$1/src.zip, \ + EXCLUDE_FILES := $$($1_EXCLUDE_FILES), \ + DISABLE_SJAVAC := $$($1_DISABLE_SJAVAC), \ + )) - BUILD_DEMOS += $$($1_COPY_TARGETS) + $1 += $$(BUILD_DEMO_$1) endif + # Copy files. Sort is needed to remove duplicates. + $1_COPY_FILES := $$(sort $$(wildcard $$(addprefix $$($1_SRC_BASE)/, \ + $(COPY_TO_IMAGE) $$($1_EXTRA_COPY_TO_IMAGE)))) + $$(eval $$(call SetupCopyFiles, COPY_DEMO_$1, \ + SRC := $$($1_SRC_BASE), \ + DEST := $(SUPPORT_OUTPUTDIR)/demos/image/$$($1_DEMO_SUBDIR)/$1, \ + FILES := $$($1_COPY_FILES), \ + )) + + $1 += $$(COPY_DEMO_$1) + + TARGETS += $$($1) endef -$(eval $(call SetupDemo,CodePointIM,jfc,,CodePointIM,,,*.html)) -$(SUPPORT_OUTPUTDIR)/demo/image/jfc/CodePointIM/_the.services: \ - $(SUPPORT_OUTPUTDIR)/demo/image/jfc/CodePointIM/CodePointIM.jar \ - $(DEMO_SHARE_SRC)/jfc/CodePointIM/java.awt.im.spi.InputMethodDescriptor - (cd $(SUPPORT_OUTPUTDIR)/demo/image/jfc/CodePointIM && \ - $(MKDIR) -p _the.tmp/META-INF/services && \ - $(CP) $(DEMO_SHARE_SRC)/jfc/CodePointIM/java.awt.im.spi.InputMethodDescriptor _the.tmp/META-INF/services && \ - cd ./_the.tmp && \ - $(JAR) uf $(SUPPORT_OUTPUTDIR)/demo/image/jfc/CodePointIM/CodePointIM.jar META-INF/services/java.awt.im.spi.InputMethodDescriptor && \ - cd ./META-INF/services && \ - $(JAR) uf $(SUPPORT_OUTPUTDIR)/demo/image/jfc/CodePointIM/CodePointIM.jar java.awt.im.spi.InputMethodDescriptor) - $(RM) -r $(SUPPORT_OUTPUTDIR)/demo/image/jfc/CodePointIM/_the.tmp - $(TOUCH) $@ +CODEPOINT_SERVICE := java.awt.im.spi.InputMethodDescriptor +CODEPOINT_METAINF_SERVICE_FILE := \ + $(SUPPORT_OUTPUTDIR)/demos/classes/jfc/CodePointIM/META-INF/services/$(CODEPOINT_SERVICE) -BUILD_DEMOS += $(SUPPORT_OUTPUTDIR)/demo/image/jfc/CodePointIM/_the.services +$(eval $(call SetupBuildDemo, CodePointIM, \ + DEMO_SUBDIR := jfc, \ + EXTRA_COPY_TO_JAR := $(CODEPOINT_SERVICE), \ +)) + +# We also need to copy the CODEPOINT_SERVICE file to the META-INF/services +# location, and make sure the jar depends on that file to get it included. +$(CODEPOINT_METAINF_SERVICE_FILE): $(DEMO_SHARE_SRC)/jfc/CodePointIM/$(CODEPOINT_SERVICE) + $(call install-file) + +$(BUILD_DEMO_CodePointIM_JAR): $(CODEPOINT_METAINF_SERVICE_FILE) ifneq ($(OPENJDK_TARGET_OS), solaris) - $(eval $(call SetupDemo,MoleculeViewer,applets,,XYZChemModel,,,example*.html *.java)) - $(eval $(call SetupDemo,WireFrame,applets,,ThreeD,,,example*.html *.java)) - $(eval $(call SetupDemo,SwingApplet,jfc,,SwingApplet,,,README* *.html)) -endif -$(eval $(call SetupDemo,FileChooserDemo,jfc,,FileChooserDemo,,,README*)) -$(eval $(call SetupDemo,Font2DTest,jfc,,Font2DTest,,,*.html *.txt)) -$(eval $(call SetupDemo,Metalworks,jfc,,Metalworks,,,README*)) -$(eval $(call SetupDemo,Notepad,jfc,,Notepad,,,README*)) -$(eval $(call SetupDemo,SampleTree,jfc,,SampleTree,,,README*)) -$(eval $(call SetupDemo,TableExample,jfc,,TableExample,,,README*)) -$(eval $(call SetupDemo,TransparentRuler,jfc,,transparentruler.Ruler,,,README*)) -$(eval $(call SetupDemo,jconsole-plugin,scripting,,,,,*.xml *.txt,,,,Main-Class: \n)) -$(eval $(call SetupDemo,FullThreadDump,management,,FullThreadDump,,,README*)) -$(eval $(call SetupDemo,JTop,management,,JTop,,,README*)) -$(eval $(call SetupDemo,MemoryMonitor,management,,MemoryMonitor,,,README*)) -$(eval $(call SetupDemo,VerboseGC,management,,VerboseGC,,,README*)) + $(eval $(call SetupBuildDemo, MoleculeViewer, \ + DEMO_SUBDIR := applets, \ + MAIN_CLASS := XYZChemModel, \ + EXTRA_COPY_TO_IMAGE := *.java, \ + )) -ifndef OPENJDK - $(eval $(call SetupDemo,Laffy,jfc,,,,closed/,*)) - $(eval $(call SetupDemo,SwingSet3,jfc,,,,closed/,*)) + $(eval $(call SetupBuildDemo, WireFrame, \ + DEMO_SUBDIR := applets, \ + MAIN_CLASS := ThreeD, \ + EXTRA_COPY_TO_IMAGE := *.java, \ + )) - $(eval $(call SetupDemo,Java2D,jfc,,java2d.Java2Demo,,closed/,*.html README*,Java2Demo)) - $(eval $(call SetupDemo,Stylepad,jfc,,Stylepad, \ - $(DEMO_SHARE_SRC)/jfc/Notepad,closed/,*.txt,,$(DEMO_SHARE_SRC)/jfc/Notepad/README.txt)) - $(eval $(call SetupDemo,SwingSet2,jfc,,SwingSet2,,closed/,README* *.html,,,.java COPYRIGHT, \ - SplashScreen-Image: resources/images/splash.png,true)) - - BUILD_DEMOS += $(patsubst $(DEMO_CLOSED_SHARE_SRC)/nbproject/%, \ - $(SUPPORT_OUTPUTDIR)/demo/image/nbproject/%, \ - $(call CacheFind, $(DEMO_CLOSED_SHARE_SRC)/nbproject)) - - $(SUPPORT_OUTPUTDIR)/demo/image/nbproject/%: $(DEMO_CLOSED_SHARE_SRC)/nbproject/% - $(call install-file) - $(CHMOD) -f ug+w $@ + $(eval $(call SetupBuildDemo, SwingApplet, \ + DEMO_SUBDIR := jfc, \ + )) endif -################################################################################################## +$(eval $(call SetupBuildDemo, FileChooserDemo, \ + DEMO_SUBDIR := jfc, \ +)) + +$(eval $(call SetupBuildDemo, Font2DTest, \ + DEMO_SUBDIR := jfc, \ +)) + +$(eval $(call SetupBuildDemo, Metalworks, \ + DEMO_SUBDIR := jfc, \ +)) + +$(eval $(call SetupBuildDemo, Notepad, \ + DEMO_SUBDIR := jfc, \ +)) -# In the old makefiles, j2dbench was not compiled. -#$(eval $(call SetupDemo,J2DBench, java2d, /src, , j2dbench/J2DBench)) +$(eval $(call SetupBuildDemo, SampleTree, \ + DEMO_SUBDIR := jfc, \ +)) + +$(eval $(call SetupBuildDemo, TableExample, \ + DEMO_SUBDIR := jfc, \ +)) + +$(eval $(call SetupBuildDemo, TransparentRuler, \ + DEMO_SUBDIR := jfc, \ + MAIN_CLASS := transparentruler.Ruler, \ +)) + +$(eval $(call SetupBuildDemo, jconsole-plugin, \ + DEMO_SUBDIR := scripting, \ + SRC_SUB_DIR := src, \ + MAIN_CLASS := NONE, \ +)) + +$(eval $(call SetupBuildDemo, FullThreadDump, \ + DEMO_SUBDIR := management, \ +)) -# JVMTI demos are a bit strange and share some files, but be careful the -# shared files are just the *.c and *.h files, not the README or sample -# makefiles. So we always exclude the README.txt and sample.makefile.txt -# from the extra sources. -define SetupJVMTIDemo - # Param 1 = Name of the demo - # Param 2 = add these directories to the includes, default is agent_util - # Param 3 = extra CFLAGS - # Param 4 = C or C++ (defaults to C) - # Param 5 = libs for unix - # Param 6 = libs for windows - # Param 7 = libs for solaris - # Param 8 = libs for linux - # Param 9 = extra directories with required sources - # Param 10 = DISABLED_WARNINGS_gcc - # Param 11 = DISABLED_WARNINGS_microsoft - # Param 12 = DISABLED_WARNINGS_clang - BUILD_DEMO_JVMTI_$1_EXTRA_SRC := \ - $$(wildcard $(DEMO_OS_TYPE_SRC)/jvmti/$1) \ - $$(wildcard $$(addprefix $(DEMO_SHARE_SRC)/jvmti/, $2)) \ - $9 - BUILD_DEMO_JVMTI_$1_EXTRA_SRC_EXCLUDE := \ - $$(wildcard $$(patsubst %, $(DEMO_SHARE_SRC)/jvmti/%/README.txt, $2)) \ - $$(wildcard $$(patsubst %, $(DEMO_SHARE_SRC)/jvmti/%/sample.makefile.txt, $2)) - BUILD_DEMO_JVMTI_$1_EXTRA_INC := $$(addprefix -I, $$(BUILD_DEMO_JVMTI_$1_EXTRA_SRC)) - ifeq (C++, $4) - BUILD_DEMO_JVMTI_$1_TOOLCHAIN := TOOLCHAIN_LINK_CXX - $1_EXTRA_CXX := $(LDFLAGS_CXX_JDK) $(LIBCXX) +$(eval $(call SetupBuildDemo, JTop, \ + DEMO_SUBDIR := management, \ +)) + +$(eval $(call SetupBuildDemo, MemoryMonitor, \ + DEMO_SUBDIR := management, \ +)) + +$(eval $(call SetupBuildDemo, VerboseGC, \ + DEMO_SUBDIR := management, \ +)) + +################################################################################ +# Build JVMTI demos. + +# Setup make rules for building a JVMTI demo. +# +# Parameter 1 is the name of the rule. This name is used as variable prefix, +# and the targets generated are listed in a variable by that name. +# +# Remaining parameters are named arguments. These include: +# EXTRA_SRC_SUBDIR Also include these subdirectories +# TOOLCHAIN Optionally specify toolchain to use +SetupBuildJvmtiDemo = $(NamedParamsMacroTemplate) +define SetupBuildJvmtiDemoBody + $1_SRC := \ + $(DEMO_SHARE_SRC)/jvmti/$1 \ + $$(wildcard $$(addprefix $(DEMO_SHARE_SRC)/jvmti/, \ + agent_util $$($1_EXTRA_SRC_SUBDIR))) + + ### Build the native lib + $1_CFLAGS_INCLUDE := $$(addprefix -I, $$($1_SRC)) + + $1_CXXFLAGS := $$($1_CFLAGS_INCLUDE) $(CXXFLAGS_JDKLIB) $(CXXFLAGS_DEBUG_SYMBOLS) + + ifeq ($$($1_TOOLCHAIN), TOOLCHAIN_LINK_CXX) + # For C++, we also need some special treatment. + $1_LDFLAGS := $(LDFLAGS_CXX_JDK) + $1_LIBS := $(LIBCXX) + + ifeq ($(OPENJDK_TARGET_CPU_ARCH), sparc) + $1_CXXFLAGS := $$(filter-out -xregs=no%appl, $$($1_CXXFLAGS)) + endif endif - $1_CXXFLAGS := $(CXXFLAGS_JDKLIB) -I$(DEMO_SHARE_SRC)/jvmti/$1 \ - $$(BUILD_DEMO_JVMTI_$1_EXTRA_INC) $3 \ - $(CXXFLAGS_DEBUG_SYMBOLS) - ifeq ($1-$(OPENJDK_TARGET_CPU_ARCH), waiters-sparc) - $1_FILTER := -xregs=no%appl - $1_CXXFLAGS := $$(filter-out $$($1_FILTER), $$($1_CXXFLAGS)) - endif - - # Workaround for CFLAGS_JDKLIB containing ',' on solaris. If this is added as 'CFLAGS' to the - # eval call below, the comma gets expanded too early. - BUILD_DEMO_JVMTI_$1_CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_DEBUG_SYMBOLS) \ - -I$(DEMO_SHARE_SRC)/jvmti/$1 $$(BUILD_DEMO_JVMTI_$1_EXTRA_INC) $3 - # Remove the -incremental:no setting to get .ilk-files like in the old build. - $$(eval $$(call SetupNativeCompilation,BUILD_DEMO_JVMTI_$1, \ - SRC := $(DEMO_SHARE_SRC)/jvmti/$1 $$(BUILD_DEMO_JVMTI_$1_EXTRA_SRC), \ - TOOLCHAIN := $$(BUILD_DEMO_JVMTI_$1_TOOLCHAIN), \ + $$(eval $$(call SetupNativeCompilation, BUILD_DEMO_JVMTI_NATIVE_$1, \ + SRC := $$($1_SRC), \ + TOOLCHAIN := $$($1_TOOLCHAIN), \ OPTIMIZATION := LOW, \ + CFLAGS := $$($1_CFLAGS_INCLUDE) $$(CFLAGS_JDKLIB) $$(CFLAGS_DEBUG_SYMBOLS), \ CXXFLAGS := $$($1_CXXFLAGS), \ - DISABLED_WARNINGS_gcc := $(10), \ - DISABLED_WARNINGS_clang := $(12), \ - DISABLED_WARNINGS_microsoft := $(11), \ - LDFLAGS := $(filter-out -incremental:no -opt:ref, $(LDFLAGS_JDKLIB)), \ + LDFLAGS := $(filter-out -incremental:no -opt:ref, $(LDFLAGS_JDKLIB)) \ + $$($1_LDFLAGS), \ LDFLAGS_macosx := $(call SET_EXECUTABLE_ORIGIN), \ - LIBS := $$($1_EXTRA_CXX), \ - LIBS_unix := $5, \ - LIBS_linux := $8, \ - LIBS_solaris := $7 -lc, \ - LIBS_windows := $6, \ + LIBS := $$($1_LIBS), \ + LIBS_solaris := -lc, \ VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ RC_FLAGS := $$(RC_FLAGS) \ -D "JDK_FNAME=$1.dll" \ -D "JDK_INTERNAL_NAME=$1" \ -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/demo/native/jvmti/$1, \ - OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/lib, \ - LIBRARY := $1)) + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native/jvmti/$1, \ + OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/lib, \ + LIBRARY := $1, \ + )) + + $1 += $$(BUILD_DEMO_JVMTI_NATIVE_$1) + + ### Build the jar, if we have java sources + ifneq ($$(wildcard $(DEMO_SHARE_SRC)/jvmti/$1/*.java), ) + $$(eval $$(call SetupJavaCompilation, BUILD_DEMO_JVMTI_JAVA_$1, \ + SETUP := GENERATE_USINGJDKBYTECODE, \ + SRC := $(DEMO_SHARE_SRC)/jvmti/$1, \ + BIN := $(SUPPORT_OUTPUTDIR)/demos/classes/jvmti/$1, \ + COPY := $(COPY_TO_JAR), \ + JAR := $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/$1.jar, \ + EXTRA_MANIFEST_ATTR := Main-Class: \n, \ + MANIFEST := $(DEMO_MANIFEST), \ + )) - $$(eval $$(call SetupZipArchive,BUILD_DEMO_JVMTI_SRC_$1, \ - SRC := $(DEMO_SHARE_SRC)/jvmti/$1 $$(BUILD_DEMO_JVMTI_$1_EXTRA_SRC), \ - EXCLUDE_FILES := $$(BUILD_DEMO_JVMTI_$1_EXTRA_SRC_EXCLUDE), \ - ZIP := $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/src.zip)) + $1 += $$(BUILD_DEMO_JVMTI_JAVA_$1_JAR) + endif + + ### Build the source zip + $1_EXCLUDE_FILES := \ + $$(wildcard $$(patsubst %, $(DEMO_SHARE_SRC)/jvmti/%/README.txt, \ + agent_util $$($1_EXTRA_SRC_SUBDIR))) \ + $$(wildcard $$(patsubst %, $(DEMO_SHARE_SRC)/jvmti/%/sample.makefile.txt, \ + agent_util $$($1_EXTRA_SRC_SUBDIR))) - $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/README.txt: $(DEMO_SHARE_SRC)/jvmti/$1/README.txt + $$(eval $$(call SetupZipArchive, BUILD_DEMO_JVMTI_SRC_$1, \ + SRC := $$($1_SRC), \ + EXCLUDE_FILES := $$($1_EXCLUDE_FILES), \ + ZIP := $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/src.zip, \ + )) + + $1 += $$(BUILD_DEMO_JVMTI_SRC_$1) + + # Copy files to image + $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/README.txt: $(DEMO_SHARE_SRC)/jvmti/$1/README.txt $$(call install-file) $(CHMOD) -f ug+w $$@ - ifneq (, $$(wildcard $(DEMO_SHARE_SRC)/jvmti/$1/*.java)) - $$(eval $$(call SetupJavaCompilation,BUILD_DEMO_JVMTI_$1_JAVA, \ - SETUP := GENERATE_USINGJDKBYTECODE, \ - SRC := $(DEMO_SHARE_SRC)/jvmti/$1, \ - BIN := $(SUPPORT_OUTPUTDIR)/demo/classes/jvmti/$1, \ - COPY := $(PATTERNS_TO_COPY), \ - JAR := $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/$1.jar, \ - EXTRA_MANIFEST_ATTR := Main-Class: \n, \ - MANIFEST := $(SUPPORT_OUTPUTDIR)/demo/java-main-manifest.mf)) + $1 += $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/README.txt + + ifeq ($(OPENJDK_TARGET_OS), windows) + # These lib and exp files normally end up in OBJECT_DIR but for demos they + # are supposed to be included in the distro. Since they are created as + # a side-effect of the library compilation, make does not know about them. + $1_SUPPORT_OUTPUTDIR := $(SUPPORT_OUTPUTDIR)/demos/native/jvmti/$1 + $1_IMAGE_OUTPUTDIR := $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/lib - BUILD_DEMOS += $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/$1.jar + $$($1_SUPPORT_OUTPUTDIR)/$1.lib: $$(BUILD_DEMO_JVMTI_NATIVE_$1) + + $$($1_SUPPORT_OUTPUTDIR)/$1.exp: $$(BUILD_DEMO_JVMTI_NATIVE_$1) + + $$($1_IMAGE_OUTPUTDIR)/$1.lib: $$($1_SUPPORT_OUTPUTDIR)/$1.lib + $$(call install-file) + + $$($1_IMAGE_OUTPUTDIR)/$1.exp: $$($1_SUPPORT_OUTPUTDIR)/$1.exp + $$(call install-file) + + $1 += $$($1_IMAGE_OUTPUTDIR)/$1.lib $$($1_IMAGE_OUTPUTDIR)/$1.exp endif - BUILD_DEMOS += $$(BUILD_DEMO_JVMTI_$1) \ - $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/src.zip \ - $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/README.txt - - ifeq ($(OPENJDK_TARGET_OS), windows) - # These files normally end up in OBJECT_DIR but for demos they - # are supposed to be included in the distro. - $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/lib/$1.lib: $$(BUILD_DEMO_JVMTI_$1) - $(CP) $(SUPPORT_OUTPUTDIR)/demo/native/jvmti/$1/$1.lib $$@ - - $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/lib/$1.exp: $$(BUILD_DEMO_JVMTI_$1) - $(CP) $(SUPPORT_OUTPUTDIR)/demo/native/jvmti/$1/$1.exp $$@ - - BUILD_DEMOS += $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/lib/$1.lib \ - $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/$1/lib/$1.exp - endif + TARGETS += $$($1) endef -$(eval $(call SetupJVMTIDemo,compiledMethodLoad, agent_util)) -$(eval $(call SetupJVMTIDemo,gctest, agent_util)) -$(eval $(call SetupJVMTIDemo,heapTracker, agent_util java_crw_demo)) -$(eval $(call SetupJVMTIDemo,heapViewer, agent_util)) -$(eval $(call SetupJVMTIDemo,minst, agent_util java_crw_demo)) -$(eval $(call SetupJVMTIDemo,mtrace, agent_util java_crw_demo)) -$(eval $(call SetupJVMTIDemo,waiters, agent_util, , C++)) -$(eval $(call SetupJVMTIDemo,versionCheck, agent_util)) +$(eval $(call SetupBuildJvmtiDemo, compiledMethodLoad)) +$(eval $(call SetupBuildJvmtiDemo, gctest)) +$(eval $(call SetupBuildJvmtiDemo, heapViewer)) +$(eval $(call SetupBuildJvmtiDemo, versionCheck)) + +$(eval $(call SetupBuildJvmtiDemo, heapTracker, \ + EXTRA_SRC_SUBDIR := java_crw_demo, \ +)) + +$(eval $(call SetupBuildJvmtiDemo, minst, \ + EXTRA_SRC_SUBDIR := java_crw_demo, \ +)) -################################################################################################## +$(eval $(call SetupBuildJvmtiDemo, mtrace, \ + EXTRA_SRC_SUBDIR := java_crw_demo, \ +)) -$(SUPPORT_OUTPUTDIR)/demo/image/management/index.html: $(DEMO_SHARE_SRC)/management/index.html - $(call install-file) - $(CHMOD) -f ug+w $@ +$(eval $(call SetupBuildJvmtiDemo, waiters, \ + TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ +)) -$(SUPPORT_OUTPUTDIR)/demo/image/jvmti/index.html: $(DEMO_SHARE_SRC)/jvmti/index.html - $(call install-file) - $(CHMOD) -f ug+w $@ +################################################################################ +# Build the Poller demo (on Solaris only). + +ifeq ($(OPENJDK_TARGET_OS), solaris) + DEMO_SOLARIS_SRC := $(JDK_TOPDIR)/src/demo/solaris -BUILD_DEMOS += $(SUPPORT_OUTPUTDIR)/demo/image/management/index.html \ - $(SUPPORT_OUTPUTDIR)/demo/image/jvmti/index.html + $(eval $(call SetupJavaCompilation, BUILD_DEMO_JAVA_Poller, \ + SETUP := GENERATE_USINGJDKBYTECODE, \ + SRC := $(DEMO_SOLARIS_SRC)/jni/Poller, \ + BIN := $(SUPPORT_OUTPUTDIR)/demos/classes/jni/Poller, \ + HEADERS := $(SUPPORT_OUTPUTDIR)/demos/classes/jni/Poller, \ + JAR := $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/Poller.jar, \ + MANIFEST := $(SUPPORT_OUTPUTDIR)/demos/java-main-manifest.mf, \ + SRCZIP := $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/src.zip, \ + COPY := README.txt Poller.c, \ + JARMAIN := Client, \ + )) -################################################################################################## + TARGETS += $(BUILD_DEMO_JAVA_Poller) -# The netbeans project files are copied into the demo directory. -ifeq ($(OPENJDK_TARGET_OS), solaris) - BUILD_DEMOS += $(patsubst $(DEMO_SHARE_SRC)/nbproject/%, \ - $(SUPPORT_OUTPUTDIR)/demo/image/nbproject/%, \ - $(filter-out $(DEMO_SHARE_SRC)/nbproject/jfc/SwingApplet%, \ - $(call CacheFind, $(DEMO_SHARE_SRC)/nbproject))) -else - BUILD_DEMOS += $(patsubst $(DEMO_SHARE_SRC)/nbproject/%, \ - $(SUPPORT_OUTPUTDIR)/demo/image/nbproject/%, \ - $(call CacheFind, $(DEMO_SHARE_SRC)/nbproject)) -endif + $(eval $(call SetupNativeCompilation, BUILD_DEMO_NATIVE_Poller, \ + SRC := $(DEMO_SOLARIS_SRC)/jni/Poller, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(SUPPORT_OUTPUTDIR)/demos/classes/jni/Poller, \ + LDFLAGS := $(LDFLAGS_JDKLIB), \ + LIBS_solaris := -lc, \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native/jni/Poller, \ + OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native, \ + LIBRARY := Poller, \ + )) -$(SUPPORT_OUTPUTDIR)/demo/image/nbproject/%: $(DEMO_SHARE_SRC)/nbproject/% + TARGETS += $(BUILD_DEMO_NATIVE_Poller) + + # We can only compile native code after java has been compiled (since we + # depend on generated .h files) + $(SUPPORT_OUTPUTDIR)/demos/native/jni/Poller/Poller.o: \ + $(BUILD_DEMO_JAVA_POLLER_COMPILE_TARGETS) + + # Copy to image + $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/README.txt: \ + $(DEMO_SOLARIS_SRC)/jni/Poller/README.txt $(call install-file) $(CHMOD) -f ug+w $@ -################################################################################################## + TARGETS += $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/README.txt -$(SUPPORT_OUTPUTDIR)/demo/image/README: $(DEMO_SHARE_SRC)/README + $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/lib/libPoller.so: \ + $(SUPPORT_OUTPUTDIR)/demos/native/libPoller.so $(call install-file) -BUILD_DEMOS += $(SUPPORT_OUTPUTDIR)/demo/image/README - -################################################################################################## + TARGETS += $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/lib/libPoller.so +endif -ifeq ($(OPENJDK_TARGET_OS), solaris) +################################################################################ +# Copy html and README files. - $(SUPPORT_OUTPUTDIR)/demo/classes/jni/Poller/%: $(DEMO_SOLARIS_SRC)/jni/Poller/% +$(SUPPORT_OUTPUTDIR)/demos/image/management/index.html: $(DEMO_SHARE_SRC)/management/index.html $(call install-file) $(CHMOD) -f ug+w $@ - $(SUPPORT_OUTPUTDIR)/demo/image/jni/Poller/README.txt: $(DEMO_SOLARIS_SRC)/jni/Poller/README.txt +$(SUPPORT_OUTPUTDIR)/demos/image/jvmti/index.html: $(DEMO_SHARE_SRC)/jvmti/index.html $(call install-file) $(CHMOD) -f ug+w $@ - $(SUPPORT_OUTPUTDIR)/demo/image/jni/Poller/Poller.jar: \ - $(SUPPORT_OUTPUTDIR)/demo/classes/jni/Poller/README.txt \ - $(SUPPORT_OUTPUTDIR)/demo/classes/jni/Poller/Poller.c - - $(eval $(call SetupJavaCompilation,BUILD_DEMO_POLLER_JAR, \ - SETUP := GENERATE_USINGJDKBYTECODE, \ - SRC := $(DEMO_SOLARIS_SRC)/jni/Poller, \ - BIN := $(SUPPORT_OUTPUTDIR)/demo/classes/jni/Poller, \ - HEADERS := $(SUPPORT_OUTPUTDIR)/demo/classes/jni/Poller, \ - JAR := $(SUPPORT_OUTPUTDIR)/demo/image/jni/Poller/Poller.jar, \ - MANIFEST := $(SUPPORT_OUTPUTDIR)/demo/java-main-manifest.mf, \ - SRCZIP := $(SUPPORT_OUTPUTDIR)/demo/image/jni/Poller/src.zip, \ - COPY := README.txt Poller.c, \ - JARMAIN := Client)) - - - - BUILD_DEMOS += $(SUPPORT_OUTPUTDIR)/demo/image/jni/Poller/Poller.jar \ - $(SUPPORT_OUTPUTDIR)/demo/image/jni/Poller/src.zip \ - $(SUPPORT_OUTPUTDIR)/demo/image/jni/Poller/README.txt - - $(eval $(call SetupNativeCompilation,BUILD_LIBPOLLER, \ - SRC := $(DEMO_SOLARIS_SRC)/jni/Poller, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(SUPPORT_OUTPUTDIR)/demo/classes/jni/Poller, \ - LDFLAGS := $(LDFLAGS_JDKLIB), \ - LIBS_solaris := -lc, \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/demo/native/jni/Poller, \ - OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/demo/native, \ - LIBRARY := Poller)) - - # - # We can only compile native code after jar has been build (since we depend on generated .h files) - # - $(SUPPORT_OUTPUTDIR)/demo/native/jni/Poller/Poller.o: $(SUPPORT_OUTPUTDIR)/demo/image/jni/Poller/Poller.jar - - $(SUPPORT_OUTPUTDIR)/demo/image/jni/Poller/lib/$(LIBRARY_PREFIX)Poller$(SHARED_LIBRARY_SUFFIX): \ - $(SUPPORT_OUTPUTDIR)/demo/native/$(LIBRARY_PREFIX)Poller$(SHARED_LIBRARY_SUFFIX) +$(SUPPORT_OUTPUTDIR)/demos/image/README: $(DEMO_SHARE_SRC)/README $(call install-file) - BUILD_DEMOS += $(SUPPORT_OUTPUTDIR)/demo/image/jni/Poller/lib/$(LIBRARY_PREFIX)Poller$(SHARED_LIBRARY_SUFFIX) +TARGETS += $(SUPPORT_OUTPUTDIR)/demos/image/management/index.html \ + $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/index.html \ + $(SUPPORT_OUTPUTDIR)/demos/image/README + +################################################################################ +# Copy netbeans project files. +$(SUPPORT_OUTPUTDIR)/demos/image/nbproject/%: $(DEMO_SHARE_SRC)/nbproject/% + $(call install-file) + $(CHMOD) -f ug+w $@ + +ifeq ($(OPENJDK_TARGET_OS), solaris) + TARGETS += $(patsubst $(DEMO_SHARE_SRC)/nbproject/%, \ + $(SUPPORT_OUTPUTDIR)/demos/image/nbproject/%, \ + $(filter-out $(DEMO_SHARE_SRC)/nbproject/jfc/SwingApplet%, \ + $(call CacheFind, $(DEMO_SHARE_SRC)/nbproject))) +else + TARGETS += $(patsubst $(DEMO_SHARE_SRC)/nbproject/%, \ + $(SUPPORT_OUTPUTDIR)/demos/image/nbproject/%, \ + $(call CacheFind, $(DEMO_SHARE_SRC)/nbproject)) endif -################################################################################################## - -ifndef OPENJDK - DB_ZIP_DIR := $(wildcard $(JDK_TOPDIR)/src/closed/db) - DB_DEMO_ZIPFILE := $(wildcard $(DB_ZIP_DIR)/*.zip) - - $(SUPPORT_OUTPUTDIR)/demo/image/_the.db.unzipped: $(DB_DEMO_ZIPFILE) - $(MKDIR) -p $(@D) - $(RM) -r $(SUPPORT_OUTPUTDIR)/demo/image/db $(SUPPORT_OUTPUTDIR)/demo/image/demo - $(CD) $(SUPPORT_OUTPUTDIR)/demo/image && $(UNZIP) -q -o $< - $(MV) $(SUPPORT_OUTPUTDIR)/demo/image/db-derby-*-bin/demo $(SUPPORT_OUTPUTDIR)/demo/image/db - $(CD) $(SUPPORT_OUTPUTDIR)/demo/image && $(RM) -r db-derby-*-bin - $(TOUCH) $@ +################################################################################ - # Copy this after the unzip above to avoid race with directory creation and mv command. - $(SUPPORT_OUTPUTDIR)/demo/image/db/README-JDK-DEMOS.html: \ - $(DB_ZIP_DIR)/README-JDK-DEMOS.html \ - | $(SUPPORT_OUTPUTDIR)/demo/image/_the.db.unzipped - $(MKDIR) -p $(@D) - $(CAT) $< | $(SED) "s/XXXX/$(shell cat $(DB_ZIP_DIR)/COPYRIGHTYEAR)/" > $@ +# Hook to include the corresponding custom file, if present. +$(eval $(call IncludeCustomExtension, jdk, CompileDemos.gmk)) - BUILD_DEMOS += $(SUPPORT_OUTPUTDIR)/demo/image/_the.db.unzipped $(SUPPORT_OUTPUTDIR)/demo/image/db/README-JDK-DEMOS.html -endif - -################################################################################################## - -all: $(BUILD_DEMOS) +all: $(TARGETS) .PHONY: all diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/gendata/GendataPolicyJars.gmk --- a/jdk/make/gendata/GendataPolicyJars.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/gendata/GendataPolicyJars.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -27,7 +27,7 @@ include $(SPEC) include MakeBase.gmk -include JavaCompilation.gmk +include JarArchive.gmk ################################################################################ @@ -57,7 +57,7 @@ endif # -# TODO fix so that SetupArchive does not write files into SRCS +# TODO fix so that SetupJarArchive does not write files into SRCS # then we don't need this extra copying # # NOTE: We currently do not place restrictions on our limited export @@ -76,13 +76,14 @@ US_EXPORT_POLICY_JAR_DEPS := \ $(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy -$(eval $(call SetupArchive,BUILD_US_EXPORT_POLICY_JAR, \ +$(eval $(call SetupJarArchive, BUILD_US_EXPORT_POLICY_JAR, \ DEPENDENCIES := $(US_EXPORT_POLICY_JAR_DEPS), \ SRCS := $(US_EXPORT_POLICY_JAR_TMP), \ SUFFIXES := .policy, \ JAR := $(US_EXPORT_POLICY_JAR_UNLIMITED), \ EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \ - SKIP_METAINF := true)) + SKIP_METAINF := true, \ +)) $(US_EXPORT_POLICY_JAR_LIMITED): \ $(US_EXPORT_POLICY_JAR_UNLIMITED) @@ -122,7 +123,7 @@ $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy.jar # -# TODO fix so that SetupArchive does not write files into SRCS +# TODO fix so that SetupJarArchive does not write files into SRCS # then we don't need this extra copying # LOCAL_POLICY_JAR_LIMITED_TMP := \ @@ -138,22 +139,24 @@ $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited/% $(install-file) -$(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR_LIMITED, \ +$(eval $(call SetupJarArchive, BUILD_LOCAL_POLICY_JAR_LIMITED, \ DEPENDENCIES := $(LOCAL_POLICY_JAR_LIMITED_TMP)/exempt_local.policy \ $(LOCAL_POLICY_JAR_LIMITED_TMP)/default_local.policy, \ SRCS := $(LOCAL_POLICY_JAR_LIMITED_TMP), \ SUFFIXES := .policy, \ JAR := $(LOCAL_POLICY_JAR_LIMITED), \ EXTRA_MANIFEST_ATTR := Crypto-Strength: limited, \ - SKIP_METAINF := true)) + SKIP_METAINF := true, \ +)) -$(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR_UNLIMITED, \ +$(eval $(call SetupJarArchive, BUILD_LOCAL_POLICY_JAR_UNLIMITED, \ DEPENDENCIES := $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/default_local.policy, \ SRCS := $(LOCAL_POLICY_JAR_UNLIMITED_TMP), \ SUFFIXES := .policy, \ JAR := $(LOCAL_POLICY_JAR_UNLIMITED), \ EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \ - SKIP_METAINF := true)) + SKIP_METAINF := true, \ +)) TARGETS += $(LOCAL_POLICY_JAR_LIMITED) $(LOCAL_POLICY_JAR_UNLIMITED) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-java.base.gmk --- a/jdk/make/launcher/Launcher-java.base.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-java.base.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -25,32 +25,51 @@ include LauncherCommon.gmk +JAVA_RC_FLAGS += -i $(JDK_TOPDIR)/src/java.base/windows/native/common +ifdef OPENJDK + JAVA_RC_FLAGS += -i "$(JDK_TOPDIR)/src/java.base/windows/native/launcher/icons" +else + JAVA_RC_FLAGS += -i "$(JDK_TOPDIR)/src/closed/java.base/windows/native/launcher/icons" +endif + ################################################################################ # On windows, the debuginfo files get the same name as for java.dll. Build # into another dir and copy selectively so debuginfo for java.dll isn't # overwritten. -$(eval $(call SetupLauncher,java, \ - -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES,,,user32.lib comctl32.lib, \ - $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jli_static.lib, $(JAVA_RC_FLAGS), \ - $(JAVA_VERSION_INFO_RESOURCE), $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/java_objs,true)) +$(eval $(call SetupBuildLauncher, java, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \ + LDFLAGS_solaris := -R$(OPENWIN_HOME)/lib$(OPENJDK_TARGET_CPU_ISADIR), \ + LIBS_windows := user32.lib comctl32.lib, \ + RC_FLAGS := $(JAVA_RC_FLAGS), \ + VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \ + OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/java_objs, \ + OPTIMIZATION := HIGH, \ + WINDOWS_STATIC_LINK := true, \ + NO_JAVA_MS := true, \ +)) $(SUPPORT_OUTPUTDIR)/modules_cmds/java.base/java$(EXE_SUFFIX): $(BUILD_LAUNCHER_java) $(MKDIR) -p $(@D) $(RM) $@ - $(CP) $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/java_objs$(OUTPUT_SUBDIR)/java$(EXE_SUFFIX) $@ + $(CP) $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/java_objs/java$(EXE_SUFFIX) $@ TARGETS += $(SUPPORT_OUTPUTDIR)/modules_cmds/java.base/java$(EXE_SUFFIX) ifeq ($(OPENJDK_TARGET_OS), windows) - $(eval $(call SetupLauncher,javaw, \ - -DJAVAW -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES,,,user32.lib comctl32.lib, \ - $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jli_static.lib, $(JAVA_RC_FLAGS), \ - $(JAVA_VERSION_INFO_RESOURCE),,true)) + $(eval $(call SetupBuildLauncher, javaw, \ + CFLAGS := -DJAVAW -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \ + LIBS_windows := user32.lib comctl32.lib, \ + RC_FLAGS := $(JAVA_RC_FLAGS), \ + VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \ + WINDOWS_STATIC_LINK := true, \ + NO_JAVA_MS := true, \ + )) endif -$(eval $(call SetupLauncher,keytool, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.security.tools.keytool.Main"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, keytool, \ + MAIN_CLASS := sun.security.tools.keytool.Main, \ +)) ################################################################################ diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-java.corba.gmk --- a/jdk/make/launcher/Launcher-java.corba.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-java.corba.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,23 +25,26 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,idlj, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.corba.se.idl.toJavaPortable.Compile"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, idlj, \ + MAIN_CLASS := com.sun.tools.corba.se.idl.toJavaPortable.Compile, \ +)) -$(eval $(call SetupLauncher,orbd, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) \ - "-J-Dcom.sun.CORBA.activation.DbDir=./orb.db"$(COMMA) \ - "-J-Dcom.sun.CORBA.activation.Port=1049"$(COMMA) \ - "-J-Dcom.sun.CORBA.POA.ORBServerId=1"$(COMMA) \ - "com.sun.corba.se.impl.activation.ORBD"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, orbd, \ + MAIN_CLASS := com.sun.corba.se.impl.activation.ORBD, \ + JAVA_ARGS := \ + -Dcom.sun.CORBA.activation.DbDir=./orb.db \ + -Dcom.sun.CORBA.activation.Port=1049 \ + -Dcom.sun.CORBA.POA.ORBServerId=1, \ +)) -$(eval $(call SetupLauncher,servertool, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.corba.se.impl.activation.ServerTool"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, servertool, \ + MAIN_CLASS := com.sun.corba.se.impl.activation.ServerTool, \ +)) -$(eval $(call SetupLauncher,tnameserv, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) \ - "-J-Dcom.sun.CORBA.activation.DbDir=./orb.db"$(COMMA) \ - "-J-Djava.util.logging.LoggingPermission=contol"$(COMMA) \ - "-J-Dcom.sun.CORBA.POA.ORBServerId=1"$(COMMA) \ - "com.sun.corba.se.impl.naming.cosnaming.TransientNameServer"$(COMMA) }')) - +$(eval $(call SetupBuildLauncher, tnameserv, \ + MAIN_CLASS := com.sun.corba.se.impl.naming.cosnaming.TransientNameServer, \ + JAVA_ARGS := \ + -Dcom.sun.CORBA.activation.DbDir=./orb.db \ + -Djava.util.logging.LoggingPermission=contol \ + -Dcom.sun.CORBA.POA.ORBServerId=1, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-java.desktop.gmk --- a/jdk/make/launcher/Launcher-java.desktop.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-java.desktop.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -29,8 +29,8 @@ $(eval $(call IncludeCustomExtension, jdk, launcher/Launcher-java.desktop.gmk)) ifndef BUILD_HEADLESS_ONLY - $(eval $(call SetupLauncher,appletviewer, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.applet.Main"$(COMMA) }',, \ - $(XLIBS))) + $(eval $(call SetupBuildLauncher, appletviewer, \ + MAIN_CLASS := sun.applet.Main, \ + LIBS_unix := $(X_LIBS), \ + )) endif - diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-java.rmi.gmk --- a/jdk/make/launcher/Launcher-java.rmi.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-java.rmi.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,39 +25,10 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,rmid, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.rmi.server.Activation"$(COMMA) }')) - -$(eval $(call SetupLauncher,rmiregistry, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.rmi.registry.RegistryImpl"$(COMMA) }')) - -########################################################################################## +$(eval $(call SetupBuildLauncher, rmid, \ + MAIN_CLASS := sun.rmi.server.Activation, \ +)) -# -# The java-rmi.cgi script in bin/ only gets delivered in certain situations -# -JAVA_RMI_CGI := $(SUPPORT_OUTPUTDIR)/modules_cmds/$(MODULE)/java-rmi.cgi -ifeq ($(OPENJDK_TARGET_OS), linux) - TARGETS += $(JAVA_RMI_CGI) -endif -ifeq ($(OPENJDK_TARGET_OS), solaris) - TARGETS += $(JAVA_RMI_CGI) -endif - -# TODO: -# On windows java-rmi.cgi shouldn't be bundled since Java 1.2, but has been built all -# this time anyway. Since jdk6, it has been built from the wrong source and resulted -# in a (almost) copy of the standard java launcher named "java-rmi.exe" ending up in -# the final images bin dir. This weird behavior is mimicked here in the converted -# makefiles for now. Should probably just be deleted. -# http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6512052 -ifeq ($(OPENJDK_TARGET_OS), windows) - $(eval $(call SetupLauncher,java-rmi, , \ - $(call SET_SHARED_LIBRARY_MAPFILE,$(JDK_TOPDIR)/make/java/main/java/mapfile-$(OPENJDK_TARGET_CPU)),,,,,,,,,RMI)) -else - $(JAVA_RMI_CGI): $(JDK_TOPDIR)/src/java.rmi/unix/bin/java-rmi.cgi.sh - $(call install-file) - $(CHMOD) a+x $@ -endif - -########################################################################################## +$(eval $(call SetupBuildLauncher, rmiregistry, \ + MAIN_CLASS := sun.rmi.registry.RegistryImpl, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-java.scripting.gmk --- a/jdk/make/launcher/Launcher-java.scripting.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-java.scripting.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,6 +25,6 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,jrunscript, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.script.shell.Main"$(COMMA) }')) - +$(eval $(call SetupBuildLauncher, jrunscript, \ + MAIN_CLASS := com.sun.tools.script.shell.Main, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-java.security.jgss.gmk --- a/jdk/make/launcher/Launcher-java.security.jgss.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-java.security.jgss.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -26,13 +26,15 @@ include LauncherCommon.gmk ifeq ($(OPENJDK_TARGET_OS), windows) - $(eval $(call SetupLauncher,kinit, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.security.krb5.internal.tools.Kinit"$(COMMA) }')) + $(eval $(call SetupBuildLauncher, kinit, \ + MAIN_CLASS := sun.security.krb5.internal.tools.Kinit, \ + )) - $(eval $(call SetupLauncher,klist, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.security.krb5.internal.tools.Klist"$(COMMA) }')) + $(eval $(call SetupBuildLauncher, klist, \ + MAIN_CLASS := sun.security.krb5.internal.tools.Klist, \ + )) - $(eval $(call SetupLauncher,ktab, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.security.krb5.internal.tools.Ktab"$(COMMA) }')) + $(eval $(call SetupBuildLauncher, ktab, \ + MAIN_CLASS := sun.security.krb5.internal.tools.Ktab, \ + )) endif - diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.compiler.gmk --- a/jdk/make/launcher/Launcher-jdk.compiler.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.compiler.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,26 +25,30 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,javac, \ - -DEXPAND_CLASSPATH_WILDCARDS \ - -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javac.Main"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, javac, \ + MAIN_CLASS := com.sun.tools.javac.Main, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ +)) -$(eval $(call SetupLauncher,javah, \ - -DEXPAND_CLASSPATH_WILDCARDS \ - -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javah.Main"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, javah, \ + MAIN_CLASS := com.sun.tools.javah.Main, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ +)) -$(eval $(call SetupLauncher,serialver, \ - -DEXPAND_CLASSPATH_WILDCARDS \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.tools.serialver.SerialVer"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, serialver, \ + MAIN_CLASS := sun.tools.serialver.SerialVer, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ +)) ifeq ($(ENABLE_SJAVAC), yes) # Build sjavac directly to the exploded image so that it does not get included # into any real images - $(eval $(call SetupLauncher,sjavac, \ - -DEXPAND_CLASSPATH_WILDCARDS \ - -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.sjavac.Main"$(COMMA) }',,,,,,, \ - $(JDK_OUTPUTDIR)/bin)) + $(eval $(call SetupBuildLauncher, sjavac, \ + MAIN_CLASS := com.sun.tools.sjavac.Main, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ + OUTPUT_DIR := $(JDK_OUTPUTDIR)/bin, \ + )) endif diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.dev.gmk --- a/jdk/make/launcher/Launcher-jdk.dev.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.dev.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,5 +25,6 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,jimage,\ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "jdk.tools.jimage.Main"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, jimage,\ + MAIN_CLASS := jdk.tools.jimage.Main, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.hotspot.agent.gmk --- a/jdk/make/launcher/Launcher-jdk.hotspot.agent.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.hotspot.agent.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,12 +25,13 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,jsadebugd, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.jvm.hotspot.jdi.SADebugServer"$(COMMA) }' \ - ,,,,,,,,,Info-privileged.plist)) +$(eval $(call SetupBuildLauncher, jsadebugd, \ + MAIN_CLASS := sun.jvm.hotspot.jdi.SADebugServer, \ + MACOSX_SIGNED := true, \ +)) -$(eval $(call SetupLauncher,jhsdb, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.jvm.hotspot.SALauncher"$(COMMA) }' \ - ,,,,,,,,,Info-privileged.plist)) - +$(eval $(call SetupBuildLauncher, jhsdb, \ + MAIN_CLASS := sun.jvm.hotspot.SALauncher, \ + MACOSX_SIGNED := true, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.jartool.gmk --- a/jdk/make/launcher/Launcher-jdk.jartool.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.jartool.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -25,8 +25,10 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,jar, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.tools.jar.Main"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, jar, \ + MAIN_CLASS := sun.tools.jar.Main, \ +)) -$(eval $(call SetupLauncher,jarsigner, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.security.tools.jarsigner.Main"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, jarsigner, \ + MAIN_CLASS := sun.security.tools.jarsigner.Main, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.javadoc.gmk --- a/jdk/make/launcher/Launcher-jdk.javadoc.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.javadoc.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,8 +25,8 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,javadoc, \ - -DEXPAND_CLASSPATH_WILDCARDS \ - -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javadoc.Main"$(COMMA) }')) - +$(eval $(call SetupBuildLauncher, javadoc, \ + MAIN_CLASS := com.sun.tools.javadoc.Main, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.jcmd.gmk --- a/jdk/make/launcher/Launcher-jdk.jcmd.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.jcmd.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,36 +25,41 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,jinfo, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) \ - "-J-Dsun.jvm.hotspot.debugger.useProcDebugger"$(COMMA) \ - "-J-Dsun.jvm.hotspot.debugger.useWindbgDebugger"$(COMMA) \ - "sun.tools.jinfo.JInfo"$(COMMA) }' \ - -DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }' \ - ,,,,,,,,,Info-privileged.plist)) +$(eval $(call SetupBuildLauncher, jinfo, \ + MAIN_CLASS := sun.tools.jinfo.JInfo, \ + JAVA_ARGS := \ + -Dsun.jvm.hotspot.debugger.useProcDebugger \ + -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \ + APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ + MACOSX_SIGNED := true, \ +)) -$(eval $(call SetupLauncher,jmap, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) \ - "-J-Dsun.jvm.hotspot.debugger.useProcDebugger"$(COMMA) \ - "-J-Dsun.jvm.hotspot.debugger.useWindbgDebugger"$(COMMA) \ - "sun.tools.jmap.JMap"$(COMMA) }' \ - -DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }' \ - ,,,,,,,,,Info-privileged.plist)) +$(eval $(call SetupBuildLauncher, jmap, \ + MAIN_CLASS := sun.tools.jmap.JMap, \ + JAVA_ARGS := \ + -Dsun.jvm.hotspot.debugger.useProcDebugger \ + -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \ + APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ + MACOSX_SIGNED := true, \ +)) -$(eval $(call SetupLauncher,jps, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.tools.jps.Jps"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, jps, \ + MAIN_CLASS := sun.tools.jps.Jps, \ +)) -$(eval $(call SetupLauncher,jstack, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) \ - "-J-Dsun.jvm.hotspot.debugger.useProcDebugger"$(COMMA) \ - "-J-Dsun.jvm.hotspot.debugger.useWindbgDebugger"$(COMMA) \ - "sun.tools.jstack.JStack"$(COMMA) }' \ - -DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }' \ - ,,,,,,,,,Info-privileged.plist)) +$(eval $(call SetupBuildLauncher, jstack, \ + MAIN_CLASS := sun.tools.jstack.JStack, \ + JAVA_ARGS := \ + -Dsun.jvm.hotspot.debugger.useProcDebugger \ + -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \ + APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ + MACOSX_SIGNED := true, \ +)) -$(eval $(call SetupLauncher,jstat, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.tools.jstat.Jstat"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, jstat, \ + MAIN_CLASS := sun.tools.jstat.Jstat, \ +)) -$(eval $(call SetupLauncher,jcmd, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.tools.jcmd.JCmd"$(COMMA) }')) - +$(eval $(call SetupBuildLauncher, jcmd, \ + MAIN_CLASS := sun.tools.jcmd.JCmd, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.jconsole.gmk --- a/jdk/make/launcher/Launcher-jdk.jconsole.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.jconsole.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -25,9 +25,10 @@ include LauncherCommon.gmk -BUILD_LAUNCHER_jconsole_CFLAGS_windows := -DJAVAW -BUILD_LAUNCHER_jconsole_LIBS_windows := user32.lib - -$(eval $(call SetupLauncher,jconsole, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "-J-Djconsole.showOutputViewer"$(COMMA) "sun.tools.jconsole.JConsole"$(COMMA) }' \ - -DAPP_CLASSPATH='{ "/lib/jconsole.jar"$(COMMA) "/lib/tools.jar"$(COMMA) "/classes" }')) +$(eval $(call SetupBuildLauncher, jconsole, \ + MAIN_CLASS := sun.tools.jconsole.JConsole, \ + JAVA_ARGS := -Djconsole.showOutputViewer, \ + APP_CLASSPATH := /lib/jconsole.jar /lib/tools.jar /classes, \ + CFLAGS_windows := -DJAVAW, \ + LIBS_windows := user32.lib, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.jdeps.gmk --- a/jdk/make/launcher/Launcher-jdk.jdeps.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.jdeps.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -25,12 +25,14 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,javap, \ - -DEXPAND_CLASSPATH_WILDCARDS \ - -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javap.Main"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, javap, \ + MAIN_CLASS := com.sun.tools.javap.Main, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ +)) -$(eval $(call SetupLauncher,jdeps, \ - -DEXPAND_CLASSPATH_WILDCARDS \ - -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.jdeps.Main"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, jdeps, \ + MAIN_CLASS := com.sun.tools.jdeps.Main, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.jdi.gmk --- a/jdk/make/launcher/Launcher-jdk.jdi.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.jdi.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,7 +25,7 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,jdb, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.example.debug.tty.TTY"$(COMMA) }' \ - -DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }')) - +$(eval $(call SetupBuildLauncher, jdb, \ + MAIN_CLASS := com.sun.tools.example.debug.tty.TTY, \ + APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.jshell.gmk --- a/jdk/make/launcher/Launcher-jdk.jshell.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.jshell.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -25,7 +25,8 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,jshell, \ - -DEXPAND_CLASSPATH_WILDCARDS \ - -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "jdk.internal.jshell.tool.JShellTool"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, jshell, \ + MAIN_CLASS := jdk.internal.jshell.tool.JShellTool, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.jvmstat.gmk --- a/jdk/make/launcher/Launcher-jdk.jvmstat.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.jvmstat.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,6 +25,6 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,jstatd, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.tools.jstatd.Jstatd"$(COMMA) }')) - +$(eval $(call SetupBuildLauncher, jstatd, \ + MAIN_CLASS := sun.tools.jstatd.Jstatd, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.pack200.gmk --- a/jdk/make/launcher/Launcher-jdk.pack200.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.pack200.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -25,8 +25,9 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,pack200, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.java.util.jar.pack.Driver"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, pack200, \ + MAIN_CLASS := com.sun.java.util.jar.pack.Driver, \ +)) ################################################################################ # The order of the object files on the link command line affects the size of the resulting @@ -92,7 +93,7 @@ $(call SET_SHARED_LIBRARY_ORIGIN), \ LIBS := $(UNPACKEXE_LIBS) $(LIBCXX), \ LIBS_solaris := -lc, \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/unpackexe$(OUTPUT_SUBDIR), \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/unpackexe, \ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/$(MODULE), \ PROGRAM := unpack200, \ VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.policytool.gmk --- a/jdk/make/launcher/Launcher-jdk.policytool.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.policytool.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -26,7 +26,8 @@ include LauncherCommon.gmk ifndef BUILD_HEADLESS_ONLY - $(eval $(call SetupLauncher,policytool, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.security.tools.policytool.PolicyTool"$(COMMA) }',, \ - $(XLIBS))) + $(eval $(call SetupBuildLauncher, policytool, \ + MAIN_CLASS := sun.security.tools.policytool.PolicyTool, \ + LIBS_unix := $(X_LIBS), \ + )) endif diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.rmic.gmk --- a/jdk/make/launcher/Launcher-jdk.rmic.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.rmic.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,7 +25,7 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,rmic, \ - -DEXPAND_CLASSPATH_WILDCARDS \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.rmi.rmic.Main"$(COMMA) }')) - +$(eval $(call SetupBuildLauncher, rmic, \ + MAIN_CLASS := sun.rmi.rmic.Main, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk --- a/jdk/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,7 +25,7 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,jjs, \ - -DENABLE_ARG_FILES \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "jdk.nashorn.tools.jjs.Main"$(COMMA) }')) - +$(eval $(call SetupBuildLauncher, jjs, \ + MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \ + CFLAGS := -DENABLE_ARG_FILES, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.xml.bind.gmk --- a/jdk/make/launcher/Launcher-jdk.xml.bind.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.xml.bind.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,9 +25,10 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,schemagen, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.internal.jxc.SchemaGenerator"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, schemagen, \ + MAIN_CLASS := com.sun.tools.internal.jxc.SchemaGenerator, \ +)) -$(eval $(call SetupLauncher,xjc, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.internal.xjc.Driver"$(COMMA) }')) - +$(eval $(call SetupBuildLauncher, xjc, \ + MAIN_CLASS := com.sun.tools.internal.xjc.Driver, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/Launcher-jdk.xml.ws.gmk --- a/jdk/make/launcher/Launcher-jdk.xml.ws.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/Launcher-jdk.xml.ws.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,9 +25,10 @@ include LauncherCommon.gmk -$(eval $(call SetupLauncher,wsgen, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.internal.ws.WsGen"$(COMMA) }')) +$(eval $(call SetupBuildLauncher, wsgen, \ + MAIN_CLASS := com.sun.tools.internal.ws.WsGen, \ +)) -$(eval $(call SetupLauncher,wsimport, \ - -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.internal.ws.WsImport"$(COMMA) }')) - +$(eval $(call SetupBuildLauncher, wsimport, \ + MAIN_CLASS := com.sun.tools.internal.ws.WsImport, \ +)) diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/launcher/LauncherCommon.gmk --- a/jdk/make/launcher/LauncherCommon.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/launcher/LauncherCommon.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -28,28 +28,17 @@ # Prepare the find cache. $(eval $(call FillCacheFind, $(JDK_TOPDIR)/src/java.base/share/native/launcher)) -# When building a legacy overlay image (on solaris 64 bit), the launchers -# need to be built with a different rpath and a different output dir. -ifeq ($(OVERLAY_IMAGES), true) - ORIGIN_ROOT := /../.. - OUTPUT_SUBDIR := $(OPENJDK_TARGET_CPU_ISADIR) -else - ORIGIN_ROOT := /.. -endif - ifeq ($(OPENJDK_TARGET_OS), macosx) ORIGIN_ARG := $(call SET_EXECUTABLE_ORIGIN) else - ORIGIN_ARG := $(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/jli) -endif + ORIGIN_ARG := $(call SET_EXECUTABLE_ORIGIN,/../lib$(OPENJDK_TARGET_CPU_LIBDIR)/jli) -# -# Applications expect to be able to link against libjawt without invoking -# System.loadLibrary("jawt") first. This was the behaviour described in the -# devloper documentation of JAWT and what worked with OpenJDK6. -# -ifneq ($(findstring $(OPENJDK_TARGET_OS), linux solaris), ) - ORIGIN_ARG += $(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/lib$(OPENJDK_TARGET_CPU_LIBDIR)) + # Applications expect to be able to link against libjawt without invoking + # System.loadLibrary("jawt") first. This was the behaviour described in the + # devloper documentation of JAWT and what worked with OpenJDK6. + ifneq ($(findstring $(OPENJDK_TARGET_OS), linux solaris), ) + ORIGIN_ARG += $(call SET_EXECUTABLE_ORIGIN,/../lib$(OPENJDK_TARGET_CPU_LIBDIR)) + endif endif LAUNCHER_SRC := $(JDK_TOPDIR)/src/java.base/share/native/launcher @@ -61,51 +50,78 @@ GLOBAL_VERSION_INFO_RESOURCE := $(JDK_TOPDIR)/src/java.base/windows/native/common/version.rc JAVA_VERSION_INFO_RESOURCE := $(JDK_TOPDIR)/src/java.base/windows/native/launcher/java.rc MACOSX_PLIST_DIR := $(JDK_TOPDIR)/src/java.base/macosx/native/launcher -# Until the shuffle is permanent, we can't add this in configure -CFLAGS_JDKEXE := $(filter-out %javavm/export, $(CFLAGS_JDKEXE)) -CFLAGS_JDKEXE += -I$(JDK_TOPDIR)/src/java.base/share/native/include \ - -I$(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include -CXXFLAGS_JDKEXE := $(filter-out %javavm/export, $(CXXFLAGS_JDKEXE)) -CXXFLAGS_JDKEXE += -I$(JDK_TOPDIR)/src/java.base/share/native/include \ - -I$(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include JAVA_MANIFEST := $(JDK_TOPDIR)/src/java.base/windows/native/launcher/java.manifest -define SetupLauncher - # TODO: Fix mapfile on solaris. Won't work with ld as linker. - # Parameter 1 is the name of the launcher (java, javac, jar...) - # Parameter 2 is extra CFLAGS - # Parameter 3 is extra LDFLAGS - # Parameter 4 is extra LIBS_unix - # Parameter 5 is extra LIBS_windows - # Parameter 6 is optional Windows JLI library (full path) - # Parameter 7 is optional Windows resource (RC) flags - # Parameter 8 is optional Windows version resource file (.rc) - # Parameter 9 is different output dir - # Parameter 10 if set, link statically with c runtime on windows. - # Parameter 11 if set, override plist file on macosx. - $(call LogSetupMacroEntry,SetupLauncher($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11)) - $(if $(13),$(error Internal makefile error: Too many arguments to SetupLauncher, please update CompileLaunchers.gmk)) +################################################################################ +# Build standard launcher. - $1_WINDOWS_JLI_LIB := $(SUPPORT_OUTPUTDIR)/native/java.base/libjli/jli.lib - ifneq ($6, ) - $1_WINDOWS_JLI_LIB := $6 - endif - $1_VERSION_INFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE) - ifneq ($8, ) - $1_VERSION_INFO_RESOURCE := $8 +# Setup make rules for building a standard launcher. +# +# Parameter 1 is the name of the rule. This name is used as variable prefix, +# and the targets generated are listed in a variable by that name. It is also +# used as the name of the executable. +# +# Remaining parameters are named arguments. These include: +# MAIN_CLASS The Java main class to launch +# JAVA_ARGS Processed into a -DJAVA_ARGS C flag +# APP_CLASSPATH Processed into a -DAPP_CLASSPATH C flag +# CFLAGS Additional CFLAGS +# CFLAGS_windows Additional CFLAGS_windows +# LIBS_unix Additional LIBS_unix +# LIBS_windows Additional LIBS_windows +# LDFLAGS_solaris Additional LDFLAGS_solaris +# RC_FLAGS Additional RC_FLAGS +# MACOSX_SIGNED On macosx, sign this binary +# WINDOWS_STATIC_LINK On windows, link statically with C runtime and libjli. +# OPTIMIZATION Override default optimization level (LOW) +# OUTPUT_DIR Override default output directory +# VERSION_INFO_RESOURCE Override default Windows resource file +# NO_JAVA_MS Do not add -ms8m to JAVA_ARGS. +SetupBuildLauncher = $(NamedParamsMacroTemplate) +define SetupBuildLauncherBody + # Setup default values (unless overridden) + ifeq ($$($1_VERSION_INFO_RESOURCE), ) + $1_VERSION_INFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE) endif - $1_LDFLAGS := $3 + ifeq ($$($1_OUTPUT_DIR), ) + $1_OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/$(MODULE) + endif + + ifeq ($$($1_OPTIMIZATION), ) + $1_OPTIMIZATION := LOW + endif + + ifneq ($$($1_NO_JAVA_MS), true) + # The norm is to append -ms8m, unless otherwise instructed. + $1_JAVA_ARGS += -ms8m + endif + + ifneq ($$($1_JAVA_ARGS), ) + $1_JAVA_ARGS_STR := '{ $$(strip $$(foreach a, \ + $$(addprefix -J, $$($1_JAVA_ARGS)) $$($1_MAIN_CLASS), "$$a"$(COMMA) )) }' + $1_CFLAGS += -DJAVA_ARGS=$$($1_JAVA_ARGS_STR) + endif + + ifneq ($$($1_APP_CLASSPATH), ) + $1_APP_CLASSPATH_STR := '{ $$(strip $$(foreach a, \ + $$($1_APP_CLASSPATH), "$$a"$(COMMA) )) }' + # Remove the trailing comma + $1_APP_CLASSPATH_STR := $$(strip $$(subst $$(COMMA) }', }', \ + $$($1_APP_CLASSPATH_STR))) + $1_CFLAGS += -DAPP_CLASSPATH=$$($1_APP_CLASSPATH_STR) + endif + $1_LIBS := ifeq ($(OPENJDK_TARGET_OS), macosx) - $1_PLIST_FILE := Info-cmdline.plist - ifneq ($(11), ) - $1_PLIST_FILE := $(11) - ifneq ($$(findstring privileged, $$($1_PLIST_FILE)), ) + ifeq ($$($1_MACOSX_SIGNED), true) + $1_PLIST_FILE := Info-privileged.plist $1_CODESIGN := true - endif + else + $1_PLIST_FILE := Info-cmdline.plist endif + $1_CFLAGS += -DPACKAGE_PATH='"$(PACKAGE_PATH)"' $1_LDFLAGS += -Wl,-all_load $(SUPPORT_OUTPUTDIR)/native/java.base/libjli_static.a \ -sectcreate __TEXT __info_plist $(MACOSX_PLIST_DIR)/$$($1_PLIST_FILE) $1_LIBS += -framework Cocoa -framework Security \ @@ -121,22 +137,12 @@ $1_LIBS += -lz endif - $1_OUTPUT_DIR_ARG := $9 - ifeq (, $$($1_OUTPUT_DIR_ARG)) - $1_OUTPUT_DIR_ARG := $(SUPPORT_OUTPUTDIR)/modules_cmds/$(MODULE) - endif - - # TODO: maybe it's better to move this if-statement out of this function - ifeq ($1, java) - $1_OPTIMIZATION_ARG := HIGH - $1_LDFLAGS_solaris := -R$(OPENWIN_HOME)/lib$(OPENJDK_TARGET_CPU_ISADIR) + ifeq ($$($1_WINDOWS_STATIC_LINK), true) + $1_CFLAGS += $(filter-out -MD, $(CFLAGS_JDKEXE)) + $1_WINDOWS_JLI_LIB := $(SUPPORT_OUTPUTDIR)/native/java.base/jli_static.lib else - $1_OPTIMIZATION_ARG := LOW - endif - - $1_CFLAGS := $(CFLAGS_JDKEXE) - ifeq ($(10), true) - $1_CFLAGS := $(filter-out -MD, $(CFLAGS_JDKEXE)) + $1_CFLAGS += $(CFLAGS_JDKEXE) + $1_WINDOWS_JLI_LIB := $(SUPPORT_OUTPUTDIR)/native/java.base/libjli/jli.lib endif # The linker on older SuSE distros (e.g. on SLES 10) complains with: @@ -156,22 +162,23 @@ endif endif - $(call SetupNativeCompilation,BUILD_LAUNCHER_$1, \ + $$(eval $$(call SetupNativeCompilation, BUILD_LAUNCHER_$1, \ SRC := $(LAUNCHER_SRC), \ INCLUDE_FILES := main.c, \ - OPTIMIZATION := $$($1_OPTIMIZATION_ARG), \ + OPTIMIZATION := $$($1_OPTIMIZATION), \ CFLAGS := $$($1_CFLAGS) \ $(LAUNCHER_CFLAGS) \ -DFULL_VERSION='"$(FULL_VERSION)"' \ -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \ -DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"' \ -DLAUNCHER_NAME='"$(LAUNCHER_NAME)"' \ - -DPROGNAME='"$1"' $(DPACKAGEPATH) \ - $2, \ + -DPROGNAME='"$1"' \ + $$($1_CFLAGS), \ CFLAGS_linux := -fPIC, \ CFLAGS_solaris := -KPIC -DHAVE_GETHRTIME, \ + CFLAGS_windows := $$($1_CFLAGS_windows), \ LDFLAGS := $(LDFLAGS_JDKEXE) \ - $(ORIGIN_ARG) \ + $$(ORIGIN_ARG) \ $$($1_LDFLAGS), \ LDFLAGS_linux := \ $(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)$(SHARED_LIBRARY_SUFFIX)) \ @@ -182,27 +189,29 @@ -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)/jli, \ MAPFILE := $$($1_MAPFILE), \ LIBS := $(JDKEXE_LIBS) $$($1_LIBS), \ - LIBS_unix := $4, \ + LIBS_unix := $$($1_LIBS_unix), \ LIBS_linux := -lpthread -ljli $(LIBDL) -lc, \ LIBS_solaris := -ljli -lthread $(LIBDL) -lc, \ LIBS_windows := $$($1_WINDOWS_JLI_LIB) \ - $(SUPPORT_OUTPUTDIR)/native/java.base/libjava/java.lib advapi32.lib $5, \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/$1_objs$(OUTPUT_SUBDIR), \ - OUTPUT_DIR := $$($1_OUTPUT_DIR_ARG)$(OUTPUT_SUBDIR), \ + $(SUPPORT_OUTPUTDIR)/native/java.base/libjava/java.lib advapi32.lib \ + $$($1_LIBS_windows), \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/$1_objs, \ + OUTPUT_DIR := $$($1_OUTPUT_DIR), \ PROGRAM := $1, \ DEBUG_SYMBOLS := true, \ VERSIONINFO_RESOURCE := $$($1_VERSION_INFO_RESOURCE), \ - RC_FLAGS := $(RC_FLAGS) \ + RC_FLAGS := $$(RC_FLAGS) \ -D "JDK_FNAME=$1$(EXE_SUFFIX)" \ -D "JDK_INTERNAL_NAME=$1" \ -D "JDK_FTYPE=0x1L" \ - $7, \ + $$($1_RC_FLAGS), \ MANIFEST := $(JAVA_MANIFEST), \ MANIFEST_VERSION := $(JDK_VERSION_FOR_MANIFEST), \ CODESIGN := $$($1_CODESIGN), \ - ) + )) - TARGETS += $$(BUILD_LAUNCHER_$1) + $1 += $$(BUILD_LAUNCHER_$1) + TARGETS += $$($1) ifneq (,$(filter $(OPENJDK_TARGET_OS), macosx aix)) $$(BUILD_LAUNCHER_$1): $(SUPPORT_OUTPUTDIR)/native/java.base/libjli_static.a @@ -213,18 +222,3 @@ $$($1_WINDOWS_JLI_LIB) endif endef - -########################################################################################## - -XLIBS := $(X_LIBS) -lX11 -ifeq ($(OPENJDK_TARGET_OS), macosx) - DPACKAGEPATH := -DPACKAGE_PATH='"$(PACKAGE_PATH)"' - XLIBS := -endif - -JAVA_RC_FLAGS += -i $(JDK_TOPDIR)/src/java.base/windows/native/common -ifdef OPENJDK - JAVA_RC_FLAGS += -i "$(JDK_TOPDIR)/src/java.base/windows/native/launcher/icons" -else - JAVA_RC_FLAGS += -i "$(JDK_TOPDIR)/src/closed/java.base/windows/native/launcher/icons" -endif diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/lib/Awt2dLibraries.gmk --- a/jdk/make/lib/Awt2dLibraries.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/lib/Awt2dLibraries.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -890,9 +890,9 @@ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libsplashscreen/mapfile-vers, \ LDFLAGS := $(LIBSPLASHSCREEN_LDFLAGS) $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ - LIBS := $(LIBSPLASHSCREEN_LIBS) $(LIBZ) \ + LIBS := $(JDKLIB_LIBS) $(LIBSPLASHSCREEN_LIBS) $(LIBZ) \ $(GIFLIB_LIBS) $(LIBJPEG_LIBS) $(PNG_LIBS), \ - LIBS_solaris := -lc, \ + LIBS_aix := -liconv, \ VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ RC_FLAGS := $(RC_FLAGS) \ -D "JDK_FNAME=splashscreen.dll" \ diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/lib/CoreLibraries.gmk --- a/jdk/make/lib/CoreLibraries.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/lib/CoreLibraries.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -139,6 +139,12 @@ endif endif +ifeq ($(OPENJDK_TARGET_OS), linux) + ifeq ($(OPENJDK_TARGET_CPU), x86_64) + BUILD_LIBJAVA_Bits.c_CFLAGS := $(C_O_FLAG_NORM) + endif +endif + $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \ LIBRARY := java, \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/lib/Lib-java.instrument.gmk --- a/jdk/make/lib/Lib-java.instrument.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/lib/Lib-java.instrument.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -68,10 +68,11 @@ LDFLAGS_macosx := -Xlinker -all_load $(SUPPORT_OUTPUTDIR)/native/java.base/libjli_static.a, \ LDFLAGS_aix := -L$(SUPPORT_OUTPUTDIR)/native/java.base, \ LDFLAGS_windows := -export:Agent_OnAttach, \ + LIBS := $(JDKLIB_LIBS), \ LIBS_unix := -ljava $(LIBZ), \ LIBS_linux := -ljli $(LIBDL), \ - LIBS_solaris := -ljli $(LIBDL) -lc, \ - LIBS_aix := -ljli_static $(LIBDL),\ + LIBS_solaris := -ljli $(LIBDL), \ + LIBS_aix := -liconv -ljli_static $(LIBDL), \ LIBS_macosx := -liconv -framework Cocoa -framework Security \ -framework ApplicationServices, \ LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib \ diff -r 77273343c131 -r d8b2864e0ec4 jdk/make/lib/Lib-jdk.jdwp.agent.gmk --- a/jdk/make/lib/Lib-jdk.jdwp.agent.gmk Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/make/lib/Lib-jdk.jdwp.agent.gmk Wed Jul 05 20:58:59 2017 +0200 @@ -84,10 +84,11 @@ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjdwp/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS := $(JDKLIB_LIBS), \ LIBS_linux := $(LIBDL), \ - LIBS_solaris := $(LIBDL) -lc, \ + LIBS_solaris := $(LIBDL), \ LIBS_macosx := -liconv, \ - LIBS_windows := $(JDKLIB_LIBS), \ + LIBS_aix := -liconv, \ VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ RC_FLAGS := $(RC_FLAGS) \ -D "JDK_FNAME=jdwp.dll" \ diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.base/share/classes/java/lang/Byte.java --- a/jdk/src/java.base/share/classes/java/lang/Byte.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/Byte.java Wed Jul 05 20:58:59 2017 +0200 @@ -463,6 +463,22 @@ } /** + * Compares two {@code byte} values numerically treating the values + * as unsigned. + * + * @param x the first {@code byte} to compare + * @param y the second {@code byte} to compare + * @return the value {@code 0} if {@code x == y}; a value less + * than {@code 0} if {@code x < y} as unsigned values; and + * a value greater than {@code 0} if {@code x > y} as + * unsigned values + * @since 9 + */ + public static int compareUnsigned(byte x, byte y) { + return Byte.toUnsignedInt(x) - Byte.toUnsignedInt(y); + } + + /** * Converts the argument to an {@code int} by an unsigned * conversion. In an unsigned conversion to an {@code int}, the * high-order 24 bits of the {@code int} are zero and the diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.base/share/classes/java/lang/Deprecated.java --- a/jdk/src/java.base/share/classes/java/lang/Deprecated.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/Deprecated.java Wed Jul 05 20:58:59 2017 +0200 @@ -36,7 +36,7 @@ * *

Use of the @Deprecated annotation on a local variable * declaration or on a parameter declaration or a package declaration - * has no effect. + * has no effect on the warnings issued by a compiler. * * @author Neal Gafter * @since 1.5 diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.base/share/classes/java/lang/Short.java --- a/jdk/src/java.base/share/classes/java/lang/Short.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/Short.java Wed Jul 05 20:58:59 2017 +0200 @@ -468,6 +468,22 @@ } /** + * Compares two {@code short} values numerically treating the values + * as unsigned. + * + * @param x the first {@code short} to compare + * @param y the second {@code short} to compare + * @return the value {@code 0} if {@code x == y}; a value less + * than {@code 0} if {@code x < y} as unsigned values; and + * a value greater than {@code 0} if {@code x > y} as + * unsigned values + * @since 9 + */ + public static int compareUnsigned(short x, short y) { + return Short.toUnsignedInt(x) - Short.toUnsignedInt(y); + } + + /** * The number of bits used to represent a {@code short} value in two's * complement binary form. * @since 1.5 diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Wed Jul 05 20:58:59 2017 +0200 @@ -66,15 +66,15 @@ private static final String NAME_METHOD_WRITE_REPLACE = "writeReplace"; private static final String NAME_METHOD_READ_OBJECT = "readObject"; private static final String NAME_METHOD_WRITE_OBJECT = "writeObject"; + + private static final String DESCR_CLASS = "Ljava/lang/Class;"; + private static final String DESCR_STRING = "Ljava/lang/String;"; + private static final String DESCR_OBJECT = "Ljava/lang/Object;"; private static final String DESCR_CTOR_SERIALIZED_LAMBDA - = MethodType.methodType(void.class, - Class.class, - String.class, String.class, String.class, - int.class, String.class, String.class, String.class, - String.class, - Object[].class).toMethodDescriptorString(); - private static final String DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION - = MethodType.methodType(void.class, String.class).toMethodDescriptorString(); + = "(" + DESCR_CLASS + DESCR_STRING + DESCR_STRING + DESCR_STRING + "I" + + DESCR_STRING + DESCR_STRING + DESCR_STRING + DESCR_STRING + "[" + DESCR_OBJECT + ")V"; + + private static final String DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION = "(Ljava/lang/String;)V"; private static final String[] SER_HOSTILE_EXCEPTIONS = new String[] {NAME_NOT_SERIALIZABLE_EXCEPTION}; diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Wed Jul 05 20:58:59 2017 +0200 @@ -1187,20 +1187,23 @@ // store them into the implementation-specific final fields. checkRtype(rtype); checkPtypes(ptypes); - UNSAFE.putObject(this, rtypeOffset, rtype); - UNSAFE.putObject(this, ptypesOffset, ptypes); + UNSAFE.putObject(this, OffsetHolder.rtypeOffset, rtype); + UNSAFE.putObject(this, OffsetHolder.ptypesOffset, ptypes); } - // Support for resetting final fields while deserializing - private static final long rtypeOffset, ptypesOffset; - static { - try { - rtypeOffset = UNSAFE.objectFieldOffset - (MethodType.class.getDeclaredField("rtype")); - ptypesOffset = UNSAFE.objectFieldOffset - (MethodType.class.getDeclaredField("ptypes")); - } catch (Exception ex) { - throw new Error(ex); + // Support for resetting final fields while deserializing. Implement Holder + // pattern to make the rarely needed offset calculation lazy. + private static class OffsetHolder { + private static final long rtypeOffset, ptypesOffset; + static { + try { + rtypeOffset = UNSAFE.objectFieldOffset + (MethodType.class.getDeclaredField("rtype")); + ptypesOffset = UNSAFE.objectFieldOffset + (MethodType.class.getDeclaredField("ptypes")); + } catch (Exception ex) { + throw new Error(ex); + } } } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.base/share/classes/java/util/Arrays.java --- a/jdk/src/java.base/share/classes/java/util/Arrays.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.base/share/classes/java/util/Arrays.java Wed Jul 05 20:58:59 2017 +0200 @@ -25,6 +25,8 @@ package java.util; +import jdk.internal.HotSpotIntrinsicCandidate; + import java.lang.reflect.Array; import java.util.concurrent.ForkJoinPool; import java.util.function.BinaryOperator; @@ -42,7 +44,6 @@ import java.util.stream.LongStream; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import jdk.internal.HotSpotIntrinsicCandidate; /** * This class contains various methods for manipulating arrays (such as @@ -2586,6 +2587,55 @@ } /** + * Returns true if the two specified arrays of longs, over the specified + * ranges, are equal to one another. + * + *

Two arrays are considered equal if the number of elements covered by + * each range is the same, and all corresponding pairs of elements over the + * specified ranges in the two arrays are equal. In other words, two arrays + * are equal if they contain, over the specified ranges, the same elements + * in the same order. + * + * @param a the first array to be tested for equality + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested fro equality + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return {@code true} if the two arrays, over the specified ranges, are + * equal + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static boolean equals(long[] a, int aFromIndex, int aToIndex, + long[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; i++) + if (a[aFromIndex++] != b[bFromIndex++]) + return false; + + return true; + } + + /** * Returns {@code true} if the two specified arrays of ints are * equal to one another. Two arrays are considered equal if both * arrays contain the same number of elements, and all corresponding pairs @@ -2615,6 +2665,55 @@ } /** + * Returns true if the two specified arrays of ints, over the specified + * ranges, are equal to one another. + * + *

Two arrays are considered equal if the number of elements covered by + * each range is the same, and all corresponding pairs of elements over the + * specified ranges in the two arrays are equal. In other words, two arrays + * are equal if they contain, over the specified ranges, the same elements + * in the same order. + * + * @param a the first array to be tested for equality + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested fro equality + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return {@code true} if the two arrays, over the specified ranges, are + * equal + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static boolean equals(int[] a, int aFromIndex, int aToIndex, + int[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; i++) + if (a[aFromIndex++] != b[bFromIndex++]) + return false; + + return true; + } + + /** * Returns {@code true} if the two specified arrays of shorts are * equal to one another. Two arrays are considered equal if both * arrays contain the same number of elements, and all corresponding pairs @@ -2644,6 +2743,55 @@ } /** + * Returns true if the two specified arrays of shorts, over the specified + * ranges, are equal to one another. + * + *

Two arrays are considered equal if the number of elements covered by + * each range is the same, and all corresponding pairs of elements over the + * specified ranges in the two arrays are equal. In other words, two arrays + * are equal if they contain, over the specified ranges, the same elements + * in the same order. + * + * @param a the first array to be tested for equality + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested fro equality + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return {@code true} if the two arrays, over the specified ranges, are + * equal + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static boolean equals(short[] a, int aFromIndex, int aToIndex, + short[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; i++) + if (a[aFromIndex++] != b[bFromIndex++]) + return false; + + return true; + } + + /** * Returns {@code true} if the two specified arrays of chars are * equal to one another. Two arrays are considered equal if both * arrays contain the same number of elements, and all corresponding pairs @@ -2674,6 +2822,55 @@ } /** + * Returns true if the two specified arrays of chars, over the specified + * ranges, are equal to one another. + * + *

Two arrays are considered equal if the number of elements covered by + * each range is the same, and all corresponding pairs of elements over the + * specified ranges in the two arrays are equal. In other words, two arrays + * are equal if they contain, over the specified ranges, the same elements + * in the same order. + * + * @param a the first array to be tested for equality + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested fro equality + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return {@code true} if the two arrays, over the specified ranges, are + * equal + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static boolean equals(char[] a, int aFromIndex, int aToIndex, + char[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; i++) + if (a[aFromIndex++] != b[bFromIndex++]) + return false; + + return true; + } + + /** * Returns {@code true} if the two specified arrays of bytes are * equal to one another. Two arrays are considered equal if both * arrays contain the same number of elements, and all corresponding pairs @@ -2703,6 +2900,55 @@ } /** + * Returns true if the two specified arrays of bytes, over the specified + * ranges, are equal to one another. + * + *

Two arrays are considered equal if the number of elements covered by + * each range is the same, and all corresponding pairs of elements over the + * specified ranges in the two arrays are equal. In other words, two arrays + * are equal if they contain, over the specified ranges, the same elements + * in the same order. + * + * @param a the first array to be tested for equality + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested fro equality + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return {@code true} if the two arrays, over the specified ranges, are + * equal + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static boolean equals(byte[] a, int aFromIndex, int aToIndex, + byte[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; i++) + if (a[aFromIndex++] != b[bFromIndex++]) + return false; + + return true; + } + + /** * Returns {@code true} if the two specified arrays of booleans are * equal to one another. Two arrays are considered equal if both * arrays contain the same number of elements, and all corresponding pairs @@ -2732,6 +2978,55 @@ } /** + * Returns true if the two specified arrays of booleans, over the specified + * ranges, are equal to one another. + * + *

Two arrays are considered equal if the number of elements covered by + * each range is the same, and all corresponding pairs of elements over the + * specified ranges in the two arrays are equal. In other words, two arrays + * are equal if they contain, over the specified ranges, the same elements + * in the same order. + * + * @param a the first array to be tested for equality + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested fro equality + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return {@code true} if the two arrays, over the specified ranges, are + * equal + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static boolean equals(boolean[] a, int aFromIndex, int aToIndex, + boolean[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; i++) + if (a[aFromIndex++] != b[bFromIndex++]) + return false; + + return true; + } + + /** * Returns {@code true} if the two specified arrays of doubles are * equal to one another. Two arrays are considered equal if both * arrays contain the same number of elements, and all corresponding pairs @@ -2759,9 +3054,70 @@ if (a2.length != length) return false; - for (int i=0; iequal to one another. + * + *

Two arrays are considered equal if the number of elements covered by + * each range is the same, and all corresponding pairs of elements over the + * specified ranges in the two arrays are equal. In other words, two arrays + * are equal if they contain, over the specified ranges, the same elements + * in the same order. + * + *

Two doubles {@code d1} and {@code d2} are considered equal if: + *

    {@code new Double(d1).equals(new Double(d2))}
+ * (Unlike the {@code ==} operator, this method considers + * {@code NaN} equals to itself, and 0.0d unequal to -0.0d.) + * + * @param a the first array to be tested for equality + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested fro equality + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return {@code true} if the two arrays, over the specified ranges, are + * equal + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @see Double#equals(Object) + * @since 9 + */ + public static boolean equals(double[] a, int aFromIndex, int aToIndex, + double[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; i++) { + Double va = a[aFromIndex++], vb = b[bFromIndex++]; + if (Double.doubleToRawLongBits(va) != Double.doubleToRawLongBits(vb)) + if (!Double.isNaN(va) || !Double.isNaN(vb)) + return false; + } return true; } @@ -2794,9 +3150,70 @@ if (a2.length != length) return false; - for (int i=0; iequal to one another. + * + *

Two arrays are considered equal if the number of elements covered by + * each range is the same, and all corresponding pairs of elements over the + * specified ranges in the two arrays are equal. In other words, two arrays + * are equal if they contain, over the specified ranges, the same elements + * in the same order. + * + *

Two floats {@code f1} and {@code f2} are considered equal if: + *

    {@code new Float(f1).equals(new Float(f2))}
+ * (Unlike the {@code ==} operator, this method considers + * {@code NaN} equals to itself, and 0.0f unequal to -0.0f.) + * + * @param a the first array to be tested for equality + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested fro equality + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return {@code true} if the two arrays, over the specified ranges, are + * equal + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @see Float#equals(Object) + * @since 9 + */ + public static boolean equals(float[] a, int aFromIndex, int aToIndex, + float[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; i++) { + float va = a[aFromIndex++], vb = b[bFromIndex++]; + if (Float.floatToRawIntBits(va) != Float.floatToRawIntBits(vb)) + if (!Float.isNaN(va) || !Float.isNaN(vb)) + return false; + } return true; } @@ -2827,9 +3244,60 @@ return false; for (int i=0; iequal to one another. + * + *

Two arrays are considered equal if the number of elements covered by + * each range is the same, and all corresponding pairs of elements over the + * specified ranges in the two arrays are equal. In other words, two arrays + * are equal if they contain, over the specified ranges, the same elements + * in the same order. + * + *

Two objects {@code e1} and {@code e2} are considered equal if + * {@code Objects.equals(e1, e2)}. + * + * @param a the first array to be tested for equality + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested fro equality + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return {@code true} if the two arrays, over the specified ranges, are + * equal + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static boolean equals(Object[] a, int aFromIndex, int aToIndex, + Object[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; i++) { + if (!Objects.equals(a[aFromIndex++], b[bFromIndex++])) return false; } @@ -5185,4 +5653,3233 @@ public static DoubleStream stream(double[] array, int startInclusive, int endExclusive) { return StreamSupport.doubleStream(spliterator(array, startInclusive, endExclusive), false); } -} + + + // Comparison methods + + // Compare boolean + + /** + * Compares two {@code boolean} arrays lexicographically. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Boolean#compare(boolean, boolean)}, at an index within the + * respective arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(boolean[], boolean[])} for the definition of a + * common and proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + *

The comparison is consistent with {@link #equals(boolean[], boolean[]) equals}, + * more specifically the following holds for arrays {@code a} and {@code b}: + *

{@code
+     *     Arrays.equals(a, b) == (Arrays.compare(a, b) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Boolean.compare(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are equal and + * contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compare(boolean[] a, boolean[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return Boolean.compare(a[i], b[i]); + } + + return a.length - b.length; + } + + /** + * Compares two {@code boolean} arrays lexicographically over the specified + * ranges. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Boolean#compare(boolean, boolean)}, at a + * relative index within the respective arrays that is the length of the + * prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(boolean[], int, int, boolean[], int, int)} for the + * definition of a common and proper prefix.) + * + *

The comparison is consistent with + * {@link #equals(boolean[], int, int, boolean[], int, int) equals}, more + * specifically the following holds for arrays {@code a} and {@code b} with + * specified ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively: + *

{@code
+     *     Arrays.equals(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) ==
+     *         (Arrays.compare(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Boolean.compare(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int compare(boolean[] a, int aFromIndex, int aToIndex, + boolean[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + boolean va = a[aFromIndex++]; + boolean vb = b[bFromIndex++]; + if (va != vb) return Boolean.compare(va, vb); + } + + return aLength - bLength; + } + + // Compare byte + + /** + * Compares two {@code byte} arrays lexicographically. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Byte#compare(byte, byte)}, at an index within the respective + * arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(byte[], byte[])} for the definition of a common and + * proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + *

The comparison is consistent with {@link #equals(byte[], byte[]) equals}, + * more specifically the following holds for arrays {@code a} and {@code b}: + *

{@code
+     *     Arrays.equals(a, b) == (Arrays.compare(a, b) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Byte.compare(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are equal and + * contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compare(byte[] a, byte[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return Byte.compare(a[i], b[i]); + } + + return a.length - b.length; + } + + /** + * Compares two {@code byte} arrays lexicographically over the specified + * ranges. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Byte#compare(byte, byte)}, at a relative index + * within the respective arrays that is the length of the prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(byte[], int, int, byte[], int, int)} for the + * definition of a common and proper prefix.) + * + *

The comparison is consistent with + * {@link #equals(byte[], int, int, byte[], int, int) equals}, more + * specifically the following holds for arrays {@code a} and {@code b} with + * specified ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively: + *

{@code
+     *     Arrays.equals(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) ==
+     *         (Arrays.compare(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Byte.compare(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int compare(byte[] a, int aFromIndex, int aToIndex, + byte[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + byte va = a[aFromIndex++]; + byte vb = b[bFromIndex++]; + if (va != vb) return Byte.compare(va, vb); + } + + return aLength - bLength; + } + + /** + * Compares two {@code byte} arrays lexicographically, numerically treating + * elements as unsigned. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Byte#compareUnsigned(byte, byte)}, at an index within the + * respective arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(byte[], byte[])} for the definition of a common + * and proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Byte.compareUnsigned(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are + * equal and contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compareUnsigned(byte[] a, byte[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return Byte.compareUnsigned(a[i], b[i]); + } + + return a.length - b.length; + } + + + /** + * Compares two {@code byte} arrays lexicographically over the specified + * ranges, numerically treating elements as unsigned. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Byte#compareUnsigned(byte, byte)}, at a + * relative index within the respective arrays that is the length of the + * prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(byte[], int, int, byte[], int, int)} for the + * definition of a common and proper prefix.) + * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Byte.compareUnsigned(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is null + * @since 9 + */ + public static int compareUnsigned(byte[] a, int aFromIndex, int aToIndex, + byte[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + byte va = a[aFromIndex++]; + byte vb = b[bFromIndex++]; + if (va != vb) return Byte.compareUnsigned(va, vb); + } + + return aLength - bLength; + } + + // Compare short + + /** + * Compares two {@code short} arrays lexicographically. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Short#compare(short, short)}, at an index within the respective + * arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(short[], short[])} for the definition of a common + * and proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + *

The comparison is consistent with {@link #equals(short[], short[]) equals}, + * more specifically the following holds for arrays {@code a} and {@code b}: + *

{@code
+     *     Arrays.equals(a, b) == (Arrays.compare(a, b) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Short.compare(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are equal and + * contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compare(short[] a, short[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return Short.compare(a[i], b[i]); + } + + return a.length - b.length; + } + + /** + * Compares two {@code short} arrays lexicographically over the specified + * ranges. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Short#compare(short, short)}, at a relative + * index within the respective arrays that is the length of the prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(short[], int, int, short[], int, int)} for the + * definition of a common and proper prefix.) + * + *

The comparison is consistent with + * {@link #equals(short[], int, int, short[], int, int) equals}, more + * specifically the following holds for arrays {@code a} and {@code b} with + * specified ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively: + *

{@code
+     *     Arrays.equals(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) ==
+     *         (Arrays.compare(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Short.compare(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int compare(short[] a, int aFromIndex, int aToIndex, + short[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + short va = a[aFromIndex++]; + short vb = b[bFromIndex++]; + if (va != vb) return Short.compare(va, vb); + } + + return aLength - bLength; + } + + /** + * Compares two {@code short} arrays lexicographically, numerically treating + * elements as unsigned. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Short#compareUnsigned(short, short)}, at an index within the + * respective arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(short[], short[])} for the definition of a common + * and proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Short.compareUnsigned(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are + * equal and contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compareUnsigned(short[] a, short[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return Short.compareUnsigned(a[i], b[i]); + } + + return a.length - b.length; + } + + /** + * Compares two {@code short} arrays lexicographically over the specified + * ranges, numerically treating elements as unsigned. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Short#compareUnsigned(short, short)}, at a + * relative index within the respective arrays that is the length of the + * prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(short[], int, int, short[], int, int)} for the + * definition of a common and proper prefix.) + * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Short.compareUnsigned(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is null + * @since 9 + */ + public static int compareUnsigned(short[] a, int aFromIndex, int aToIndex, + short[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + short va = a[aFromIndex++]; + short vb = b[bFromIndex++]; + if (va != vb) return Short.compareUnsigned(va, vb); + } + + return aLength - bLength; + } + + // Compare char + + /** + * Compares two {@code char} arrays lexicographically. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Character#compare(char, char)}, at an index within the respective + * arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(char[], char[])} for the definition of a common and + * proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + *

The comparison is consistent with {@link #equals(char[], char[]) equals}, + * more specifically the following holds for arrays {@code a} and {@code b}: + *

{@code
+     *     Arrays.equals(a, b) == (Arrays.compare(a, b) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Character.compare(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are equal and + * contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compare(char[] a, char[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return Character.compare(a[i], b[i]); + } + + return a.length - b.length; + } + + /** + * Compares two {@code char} arrays lexicographically over the specified + * ranges. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Character#compare(char, char)}, at a relative + * index within the respective arrays that is the length of the prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(char[], int, int, char[], int, int)} for the + * definition of a common and proper prefix.) + * + *

The comparison is consistent with + * {@link #equals(char[], int, int, char[], int, int) equals}, more + * specifically the following holds for arrays {@code a} and {@code b} with + * specified ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively: + *

{@code
+     *     Arrays.equals(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) ==
+     *         (Arrays.compare(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Character.compare(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int compare(char[] a, int aFromIndex, int aToIndex, + char[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + char va = a[aFromIndex++]; + char vb = b[bFromIndex++]; + if (va != vb) return Character.compare(va, vb); + } + + return aLength - bLength; + } + + // Compare int + + /** + * Compares two {@code int} arrays lexicographically. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Integer#compare(int, int)}, at an index within the respective + * arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(int[], int[])} for the definition of a common and + * proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + *

The comparison is consistent with {@link #equals(int[], int[]) equals}, + * more specifically the following holds for arrays {@code a} and {@code b}: + *

{@code
+     *     Arrays.equals(a, b) == (Arrays.compare(a, b) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Integer.compare(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are equal and + * contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compare(int[] a, int[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return Integer.compare(a[i], b[i]); + } + + return a.length - b.length; + } + + /** + * Compares two {@code int} arrays lexicographically over the specified + * ranges. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Integer#compare(int, int)}, at a relative index + * within the respective arrays that is the length of the prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(int[], int, int, int[], int, int)} for the + * definition of a common and proper prefix.) + * + *

The comparison is consistent with + * {@link #equals(int[], int, int, int[], int, int) equals}, more + * specifically the following holds for arrays {@code a} and {@code b} with + * specified ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively: + *

{@code
+     *     Arrays.equals(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) ==
+     *         (Arrays.compare(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Integer.compare(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int compare(int[] a, int aFromIndex, int aToIndex, + int[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + int va = a[aFromIndex++]; + int vb = b[bFromIndex++]; + if (va != vb) return Integer.compare(va, vb); + } + + return aLength - bLength; + } + + /** + * Compares two {@code int} arrays lexicographically, numerically treating + * elements as unsigned. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Integer#compareUnsigned(int, int)}, at an index within the + * respective arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(int[], int[])} for the definition of a common + * and proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Integer.compareUnsigned(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are + * equal and contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compareUnsigned(int[] a, int[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return Integer.compareUnsigned(a[i], b[i]); + } + + return a.length - b.length; + } + + /** + * Compares two {@code int} arrays lexicographically over the specified + * ranges, numerically treating elements as unsigned. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Integer#compareUnsigned(int, int)}, at a + * relative index within the respective arrays that is the length of the + * prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(int[], int, int, int[], int, int)} for the + * definition of a common and proper prefix.) + * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Integer.compareUnsigned(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is null + * @since 9 + */ + public static int compareUnsigned(int[] a, int aFromIndex, int aToIndex, + int[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + int va = a[aFromIndex++]; + int vb = b[bFromIndex++]; + if (va != vb) return Integer.compareUnsigned(va, vb); + } + + return aLength - bLength; + } + + // Compare long + + /** + * Compares two {@code long} arrays lexicographically. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Long#compare(long, long)}, at an index within the respective + * arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(long[], long[])} for the definition of a common and + * proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + *

The comparison is consistent with {@link #equals(long[], long[]) equals}, + * more specifically the following holds for arrays {@code a} and {@code b}: + *

{@code
+     *     Arrays.equals(a, b) == (Arrays.compare(a, b) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Long.compare(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are equal and + * contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compare(long[] a, long[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return Long.compare(a[i], b[i]); + } + + return a.length - b.length; + } + + /** + * Compares two {@code long} arrays lexicographically over the specified + * ranges. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Long#compare(long, long)}, at a relative index + * within the respective arrays that is the length of the prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(long[], int, int, long[], int, int)} for the + * definition of a common and proper prefix.) + * + *

The comparison is consistent with + * {@link #equals(long[], int, int, long[], int, int) equals}, more + * specifically the following holds for arrays {@code a} and {@code b} with + * specified ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively: + *

{@code
+     *     Arrays.equals(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) ==
+     *         (Arrays.compare(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Long.compare(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int compare(long[] a, int aFromIndex, int aToIndex, + long[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + long va = a[aFromIndex++]; + long vb = b[bFromIndex++]; + if (va != vb) return Long.compare(va, vb); + } + + return aLength - bLength; + } + + /** + * Compares two {@code long} arrays lexicographically, numerically treating + * elements as unsigned. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Long#compareUnsigned(long, long)}, at an index within the + * respective arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(long[], long[])} for the definition of a common + * and proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Long.compareUnsigned(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are + * equal and contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compareUnsigned(long[] a, long[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return Long.compareUnsigned(a[i], b[i]); + } + + return a.length - b.length; + } + + /** + * Compares two {@code long} arrays lexicographically over the specified + * ranges, numerically treating elements as unsigned. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Long#compareUnsigned(long, long)}, at a + * relative index within the respective arrays that is the length of the + * prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(long[], int, int, long[], int, int)} for the + * definition of a common and proper prefix.) + * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Long.compareUnsigned(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is null + * @since 9 + */ + public static int compareUnsigned(long[] a, int aFromIndex, int aToIndex, + long[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + long va = a[aFromIndex++]; + long vb = b[bFromIndex++]; + if (va != vb) return Long.compareUnsigned(va, vb); + } + + return aLength - bLength; + } + + // Compare float + + /** + * Compares two {@code float} arrays lexicographically. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Float#compare(float, float)}, at an index within the respective + * arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(float[], float[])} for the definition of a common + * and proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + *

The comparison is consistent with {@link #equals(float[], float[]) equals}, + * more specifically the following holds for arrays {@code a} and {@code b}: + *

{@code
+     *     Arrays.equals(a, b) == (Arrays.compare(a, b) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Float.compare(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are equal and + * contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compare(float[] a, float[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + float va = a[i], vb = b[i]; + if (Float.floatToRawIntBits(va) != Float.floatToRawIntBits(vb)) { + int c = Float.compare(va, vb); + if (c != 0) return c; + } + } + + return a.length - b.length; + } + + /** + * Compares two {@code float} arrays lexicographically over the specified + * ranges. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Float#compare(float, float)}, at a relative + * index within the respective arrays that is the length of the prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(float[], int, int, float[], int, int)} for the + * definition of a common and proper prefix.) + * + *

The comparison is consistent with + * {@link #equals(float[], int, int, float[], int, int) equals}, more + * specifically the following holds for arrays {@code a} and {@code b} with + * specified ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively: + *

{@code
+     *     Arrays.equals(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) ==
+     *         (Arrays.compare(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Float.compare(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int compare(float[] a, int aFromIndex, int aToIndex, + float[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + float va = a[aFromIndex++], vb = b[bFromIndex++]; + if (Float.floatToRawIntBits(va) != Float.floatToRawIntBits(vb)) { + int c = Float.compare(va, vb); + if (c != 0) return c; + } + } + + return aLength - bLength; + } + + // Compare double + + /** + * Compares two {@code double} arrays lexicographically. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements, as if by + * {@link Double#compare(double, double)}, at an index within the respective + * arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(double[], double[])} for the definition of a common + * and proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + *

The comparison is consistent with {@link #equals(double[], double[]) equals}, + * more specifically the following holds for arrays {@code a} and {@code b}: + *

{@code
+     *     Arrays.equals(a, b) == (Arrays.compare(a, b) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return Double.compare(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @return the value {@code 0} if the first and second array are equal and + * contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static int compare(double[] a, double[] b) { + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + double va = a[i], vb = b[i]; + if (Double.doubleToRawLongBits(va) != Double.doubleToRawLongBits(vb)) { + int c = Double.compare(va, vb); + if (c != 0) return c; + } + } + + return a.length - b.length; + } + + /** + * Compares two {@code double} arrays lexicographically over the specified + * ranges. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements, as if by {@link Double#compare(double, double)}, at a relative + * index within the respective arrays that is the length of the prefix. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(double[], int, int, double[], int, int)} for the + * definition of a common and proper prefix.) + * + *

The comparison is consistent with + * {@link #equals(double[], int, int, double[], int, int) equals}, more + * specifically the following holds for arrays {@code a} and {@code b} with + * specified ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively: + *

{@code
+     *     Arrays.equals(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) ==
+     *         (Arrays.compare(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if: + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return Double.compare(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int compare(double[] a, int aFromIndex, int aToIndex, + double[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + double va = a[aFromIndex++], vb = b[bFromIndex++]; + if (Double.doubleToRawLongBits(va) != Double.doubleToRawLongBits(vb)) { + int c = Double.compare(va, vb); + if (c != 0) return c; + } + } + + return aLength - bLength; + } + + // Compare objects + + /** + * Compares two {@code Object} arrays, within comparable elements, + * lexicographically. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing two elements of type {@code T} at + * an index {@code i} within the respective arrays that is the prefix + * length, as if by: + *

{@code
+     *     Comparator.nullsFirst(Comparator.naturalOrder()).
+     *         compare(a[i], b[i])
+     * }
+ * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(Object[], Object[])} for the definition of a common + * and proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * A {@code null} array element is considered lexicographically than a + * non-{@code null} array element. Two {@code null} array elements are + * considered equal. + * + *

The comparison is consistent with {@link #equals(Object[], Object[]) equals}, + * more specifically the following holds for arrays {@code a} and {@code b}: + *

{@code
+     *     Arrays.equals(a, b) == (Arrays.compare(a, b) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if (for non-{@code null} array references + * and elements): + *

{@code
+     *     int i = Arrays.mismatch(a, b);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return a[i].compareTo(b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @param the type of comparable array elements + * @return the value {@code 0} if the first and second array are equal and + * contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @since 9 + */ + public static > int compare(T[] a, T[] b) { + if (a == b) + return 0; + // A null array is less than a non-null array + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + T oa = a[i]; + T ob = b[i]; + if (oa != ob) { + // A null element is less than a non-null element + if (oa == null || ob == null) + return oa == null ? -1 : 1; + int v = oa.compareTo(ob); + if (v != 0) { + return v; + } + } + } + + return a.length - b.length; + } + + /** + * Compares two {@code Object} arrays lexicographically over the specified + * ranges. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing two + * elements of type {@code T} at a relative index {@code i} within the + * respective arrays that is the prefix length, as if by: + *

{@code
+     *     Comparator.nullsFirst(Comparator.naturalOrder()).
+     *         compare(a[aFromIndex + i, b[bFromIndex + i])
+     * }
+ * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(Object[], int, int, Object[], int, int)} for the + * definition of a common and proper prefix.) + * + *

The comparison is consistent with + * {@link #equals(Object[], int, int, Object[], int, int) equals}, more + * specifically the following holds for arrays {@code a} and {@code b} with + * specified ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively: + *

{@code
+     *     Arrays.equals(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) ==
+     *         (Arrays.compare(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex) == 0)
+     * }
+ * + * @apiNote + *

This method behaves as if (for non-{@code null} array elements): + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return a[aFromIndex + i].compareTo(b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @param the type of comparable array elements + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static > int compare( + T[] a, int aFromIndex, int aToIndex, + T[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + T oa = a[aFromIndex++]; + T ob = b[bFromIndex++]; + if (oa != ob) { + if (oa == null || ob == null) + return oa == null ? -1 : 1; + int v = oa.compareTo(ob); + if (v != 0) { + return v; + } + } + } + + return aLength - bLength; + } + + /** + * Compares two {@code Object} arrays lexicographically using a specified + * comparator. + * + *

If the two arrays share a common prefix then the lexicographic + * comparison is the result of comparing with the specified comparator two + * elements at an index within the respective arrays that is the prefix + * length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two array lengths. + * (See {@link #mismatch(Object[], Object[])} for the definition of a common + * and proper prefix.) + * + *

A {@code null} array reference is considered lexicographically less + * than a non-{@code null} array reference. Two {@code null} array + * references are considered equal. + * + * @apiNote + *

This method behaves as if (for non-{@code null} array references): + *

{@code
+     *     int i = Arrays.mismatch(a, b, cmp);
+     *     if (i >= 0 && i < Math.min(a.length, b.length))
+     *         return cmp.compare(a[i], b[i]);
+     *     return a.length - b.length;
+     * }
+ * + * @param a the first array to compare + * @param b the second array to compare + * @param cmp the comparator to compare array elements + * @param the type of array elements + * @return the value {@code 0} if the first and second array are equal and + * contain the same elements in the same order; + * a value less than {@code 0} if the first array is + * lexicographically less than the second array; and + * a value greater than {@code 0} if the first array is + * lexicographically greater than the second array + * @throws NullPointerException if the comparator is {@code null} + * @since 9 + */ + public static int compare(T[] a, T[] b, + Comparator cmp) { + Objects.requireNonNull(cmp); + if (a == b) + return 0; + if (a == null || b == null) + return a == null ? -1 : 1; + + int length = Math.min(a.length, b.length); + for (int i = 0; i < length; i++) { + T oa = a[i]; + T ob = b[i]; + if (oa != ob) { + // Null-value comparison is deferred to the comparator + int v = cmp.compare(oa, ob); + if (v != 0) { + return v; + } + } + } + + return a.length - b.length; + } + + /** + * Compares two {@code Object} arrays lexicographically over the specified + * ranges. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the lexicographic comparison is the result of comparing with the + * specified comparator two elements at a relative index within the + * respective arrays that is the prefix length. + * Otherwise, one array is a proper prefix of the other and, lexicographic + * comparison is the result of comparing the two range lengths. + * (See {@link #mismatch(Object[], int, int, Object[], int, int)} for the + * definition of a common and proper prefix.) + * + * @apiNote + *

This method behaves as if (for non-{@code null} array elements): + *

{@code
+     *     int i = Arrays.mismatch(a, aFromIndex, aToIndex,
+     *                             b, bFromIndex, bToIndex, cmp);
+     *     if (i >= 0 && i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     *         return cmp.compare(a[aFromIndex + i], b[bFromIndex + i]);
+     *     return (aToIndex - aFromIndex) - (bToIndex - bFromIndex);
+     * }
+ * + * @param a the first array to compare + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be compared + * @param aToIndex the index (exclusive) of the last element in the + * first array to be compared + * @param b the second array to compare + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be compared + * @param bToIndex the index (exclusive) of the last element in the + * second array to be compared + * @param cmp the comparator to compare array elements + * @param the type of array elements + * @return the value {@code 0} if, over the specified ranges, the first and + * second array are equal and contain the same elements in the same + * order; + * a value less than {@code 0} if, over the specified ranges, the + * first array is lexicographically less than the second array; and + * a value greater than {@code 0} if, over the specified ranges, the + * first array is lexicographically greater than the second array + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array or the comparator is {@code null} + * @since 9 + */ + public static int compare( + T[] a, int aFromIndex, int aToIndex, + T[] b, int bFromIndex, int bToIndex, + Comparator cmp) { + Objects.requireNonNull(cmp); + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + T oa = a[aFromIndex++]; + T ob = b[bFromIndex++]; + if (oa != ob) { + // Null-value comparison is deferred to the comparator + int v = cmp.compare(oa, ob); + if (v != 0) { + return v; + } + } + } + + return aLength - bLength; + } + + + // Mismatch methods + + // Mismatch boolean + + /** + * Finds and returns the index of the first mismatch between two + * {@code boolean} arrays, otherwise return -1 if no mismatch is found. The + * index will be in the range of 0 (inclusive) up to the length (inclusive) + * of the smaller array. + * + *

If the two arrays share a common prefix then the returned index is the + * length of the common prefix and it follows that there is a mismatch + * between the two elements at that index within the respective arrays. + * If one array is a proper prefix of the other then the returned index is + * the length of the smaller array and it follows that the index is only + * valid for the larger array. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(a.length, b.length) &&
+     *     Arrays.equals(a, 0, pl, b, 0, pl) &&
+     *     a[pl] != b[pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a proper + * prefix if the following expression is true: + *

{@code
+     *     a.length != b.length &&
+     *     Arrays.equals(a, 0, Math.min(a.length, b.length),
+     *                   b, 0, Math.min(a.length, b.length))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param b the second array to be tested for a mismatch + * @return the index of the first mismatch between the two arrays, + * otherwise {@code -1}. + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(boolean[] a, boolean[] b) { + int length = Math.min(a.length, b.length); // Check null array refs + if (a == b) + return -1; + + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return i; + } + + return a.length != b.length ? length : -1; + } + + /** + * Finds and returns the relative index of the first mismatch between two + * {@code boolean} arrays over the specified ranges, otherwise return -1 if + * no mismatch is found. The index will be in the range of 0 (inclusive) up + * to the length (inclusive) of the smaller range. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the returned relative index is the length of the common prefix and + * it follows that there is a mismatch between the two elements at that + * relative index within the respective arrays. + * If one array is a proper prefix of the other, over the specified ranges, + * then the returned relative index is the length of the smaller range and + * it follows that the relative index is only valid for the array with the + * larger range. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, aFromIndex, aFromIndex + pl, b, bFromIndex, bFromIndex + pl) &&
+     *     a[aFromIndex + pl] != b[bFromIndex + pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a proper + * if the following expression is true: + *

{@code
+     *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   b, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested for a mismatch + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return the relative index of the first mismatch between the two arrays + * over the specified ranges, otherwise {@code -1}. + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(boolean[] a, int aFromIndex, int aToIndex, + boolean[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + if (a[aFromIndex++] != b[bFromIndex++]) return i; + } + + return aLength != bLength ? length : -1; + } + + // Mismatch byte + + /** + * Finds and returns the index of the first mismatch between two {@code byte} + * arrays, otherwise return -1 if no mismatch is found. The index will be + * in the range of 0 (inclusive) up to the length (inclusive) of the smaller + * array. + * + *

If the two arrays share a common prefix then the returned index is the + * length of the common prefix and it follows that there is a mismatch + * between the two elements at that index within the respective arrays. + * If one array is a proper prefix of the other then the returned index is + * the length of the smaller array and it follows that the index is only + * valid for the larger array. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(a.length, b.length) &&
+     *     Arrays.equals(a, 0, pl, b, 0, pl) &&
+     *     a[pl] != b[pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a proper + * prefix if the following expression is true: + *

{@code
+     *     a.length != b.length &&
+     *     Arrays.equals(a, 0, Math.min(a.length, b.length),
+     *                   b, 0, Math.min(a.length, b.length))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param b the second array to be tested for a mismatch + * @return the index of the first mismatch between the two arrays, + * otherwise {@code -1}. + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(byte[] a, byte[] b) { + int length = Math.min(a.length, b.length); // Check null array refs + if (a == b) + return -1; + + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return i; + } + + return a.length != b.length ? length : -1; + } + + /** + * Finds and returns the relative index of the first mismatch between two + * {@code byte} arrays over the specified ranges, otherwise return -1 if no + * mismatch is found. The index will be in the range of 0 (inclusive) up to + * the length (inclusive) of the smaller range. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the returned relative index is the length of the common prefix and + * it follows that there is a mismatch between the two elements at that + * relative index within the respective arrays. + * If one array is a proper prefix of the other, over the specified ranges, + * then the returned relative index is the length of the smaller range and + * it follows that the relative index is only valid for the array with the + * larger range. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, aFromIndex, aFromIndex + pl, b, bFromIndex, bFromIndex + pl) &&
+     *     a[aFromIndex + pl] != b[bFromIndex + pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a proper + * if the following expression is true: + *

{@code
+     *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   b, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested for a mismatch + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return the relative index of the first mismatch between the two arrays + * over the specified ranges, otherwise {@code -1}. + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(byte[] a, int aFromIndex, int aToIndex, + byte[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + if (a[aFromIndex++] != b[bFromIndex++]) return i; + } + + return aLength != bLength ? length : -1; + } + + // Mismatch char + + /** + * Finds and returns the index of the first mismatch between two {@code char} + * arrays, otherwise return -1 if no mismatch is found. The index will be + * in the range of 0 (inclusive) up to the length (inclusive) of the smaller + * array. + * + *

If the two arrays share a common prefix then the returned index is the + * length of the common prefix and it follows that there is a mismatch + * between the two elements at that index within the respective arrays. + * If one array is a proper prefix of the other then the returned index is + * the length of the smaller array and it follows that the index is only + * valid for the larger array. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(a.length, b.length) &&
+     *     Arrays.equals(a, 0, pl, b, 0, pl) &&
+     *     a[pl] != b[pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a proper + * prefix if the following expression is true: + *

{@code
+     *     a.length != b.length &&
+     *     Arrays.equals(a, 0, Math.min(a.length, b.length),
+     *                   b, 0, Math.min(a.length, b.length))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param b the second array to be tested for a mismatch + * @return the index of the first mismatch between the two arrays, + * otherwise {@code -1}. + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(char[] a, char[] b) { + int length = Math.min(a.length, b.length); // Check null array refs + if (a == b) + return -1; + + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return i; + } + + return a.length != b.length ? length : -1; + } + + /** + * Finds and returns the relative index of the first mismatch between two + * {@code char} arrays over the specified ranges, otherwise return -1 if no + * mismatch is found. The index will be in the range of 0 (inclusive) up to + * the length (inclusive) of the smaller range. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the returned relative index is the length of the common prefix and + * it follows that there is a mismatch between the two elements at that + * relative index within the respective arrays. + * If one array is a proper prefix of the other, over the specified ranges, + * then the returned relative index is the length of the smaller range and + * it follows that the relative index is only valid for the array with the + * larger range. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, aFromIndex, aFromIndex + pl, b, bFromIndex, bFromIndex + pl) &&
+     *     a[aFromIndex + pl] != b[bFromIndex + pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a proper + * if the following expression is true: + *

{@code
+     *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   b, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested for a mismatch + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return the relative index of the first mismatch between the two arrays + * over the specified ranges, otherwise {@code -1}. + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(char[] a, int aFromIndex, int aToIndex, + char[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + if (a[aFromIndex++] != b[bFromIndex++]) return i; + } + + return aLength != bLength ? length : -1; + } + + // Mismatch short + + /** + * Finds and returns the index of the first mismatch between two {@code short} + * arrays, otherwise return -1 if no mismatch is found. The index will be + * in the range of 0 (inclusive) up to the length (inclusive) of the smaller + * array. + * + *

If the two arrays share a common prefix then the returned index is the + * length of the common prefix and it follows that there is a mismatch + * between the two elements at that index within the respective arrays. + * If one array is a proper prefix of the other then the returned index is + * the length of the smaller array and it follows that the index is only + * valid for the larger array. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(a.length, b.length) &&
+     *     Arrays.equals(a, 0, pl, b, 0, pl) &&
+     *     a[pl] != b[pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a proper + * prefix if the following expression is true: + *

{@code
+     *     a.length != b.length &&
+     *     Arrays.equals(a, 0, Math.min(a.length, b.length),
+     *                   b, 0, Math.min(a.length, b.length))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param b the second array to be tested for a mismatch + * @return the index of the first mismatch between the two arrays, + * otherwise {@code -1}. + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(short[] a, short[] b) { + int length = Math.min(a.length, b.length); // Check null array refs + if (a == b) + return -1; + + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return i; + } + + return a.length != b.length ? length : -1; + } + + /** + * Finds and returns the relative index of the first mismatch between two + * {@code short} arrays over the specified ranges, otherwise return -1 if no + * mismatch is found. The index will be in the range of 0 (inclusive) up to + * the length (inclusive) of the smaller range. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the returned relative index is the length of the common prefix and + * it follows that there is a mismatch between the two elements at that + * relative index within the respective arrays. + * If one array is a proper prefix of the other, over the specified ranges, + * then the returned relative index is the length of the smaller range and + * it follows that the relative index is only valid for the array with the + * larger range. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, aFromIndex, aFromIndex + pl, b, bFromIndex, bFromIndex + pl) &&
+     *     a[aFromIndex + pl] != b[bFromIndex + pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a proper + * if the following expression is true: + *

{@code
+     *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   b, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested for a mismatch + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return the relative index of the first mismatch between the two arrays + * over the specified ranges, otherwise {@code -1}. + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(short[] a, int aFromIndex, int aToIndex, + short[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + if (a[aFromIndex++] != b[bFromIndex++]) return i; + } + + return aLength != bLength ? length : -1; + } + + // Mismatch int + + /** + * Finds and returns the index of the first mismatch between two {@code int} + * arrays, otherwise return -1 if no mismatch is found. The index will be + * in the range of 0 (inclusive) up to the length (inclusive) of the smaller + * array. + * + *

If the two arrays share a common prefix then the returned index is the + * length of the common prefix and it follows that there is a mismatch + * between the two elements at that index within the respective arrays. + * If one array is a proper prefix of the other then the returned index is + * the length of the smaller array and it follows that the index is only + * valid for the larger array. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(a.length, b.length) &&
+     *     Arrays.equals(a, 0, pl, b, 0, pl) &&
+     *     a[pl] != b[pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a proper + * prefix if the following expression is true: + *

{@code
+     *     a.length != b.length &&
+     *     Arrays.equals(a, 0, Math.min(a.length, b.length),
+     *                   b, 0, Math.min(a.length, b.length))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param b the second array to be tested for a mismatch + * @return the index of the first mismatch between the two arrays, + * otherwise {@code -1}. + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(int[] a, int[] b) { + int length = Math.min(a.length, b.length); // Check null array refs + if (a == b) + return -1; + + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return i; + } + + return a.length != b.length ? length : -1; + } + + /** + * Finds and returns the relative index of the first mismatch between two + * {@code int} arrays over the specified ranges, otherwise return -1 if no + * mismatch is found. The index will be in the range of 0 (inclusive) up to + * the length (inclusive) of the smaller range. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the returned relative index is the length of the common prefix and + * it follows that there is a mismatch between the two elements at that + * relative index within the respective arrays. + * If one array is a proper prefix of the other, over the specified ranges, + * then the returned relative index is the length of the smaller range and + * it follows that the relative index is only valid for the array with the + * larger range. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, aFromIndex, aFromIndex + pl, b, bFromIndex, bFromIndex + pl) &&
+     *     a[aFromIndex + pl] != b[bFromIndex + pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a proper + * if the following expression is true: + *

{@code
+     *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   b, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested for a mismatch + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return the relative index of the first mismatch between the two arrays + * over the specified ranges, otherwise {@code -1}. + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(int[] a, int aFromIndex, int aToIndex, + int[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + if (a[aFromIndex++] != b[bFromIndex++]) return i; + } + + return aLength != bLength ? length : -1; + } + + // Mismatch long + + /** + * Finds and returns the index of the first mismatch between two {@code long} + * arrays, otherwise return -1 if no mismatch is found. The index will be + * in the range of 0 (inclusive) up to the length (inclusive) of the smaller + * array. + * + *

If the two arrays share a common prefix then the returned index is the + * length of the common prefix and it follows that there is a mismatch + * between the two elements at that index within the respective arrays. + * If one array is a proper prefix of the other then the returned index is + * the length of the smaller array and it follows that the index is only + * valid for the larger array. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(a.length, b.length) &&
+     *     Arrays.equals(a, 0, pl, b, 0, pl) &&
+     *     a[pl] != b[pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a proper + * prefix if the following expression is true: + *

{@code
+     *     a.length != b.length &&
+     *     Arrays.equals(a, 0, Math.min(a.length, b.length),
+     *                   b, 0, Math.min(a.length, b.length))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param b the second array to be tested for a mismatch + * @return the index of the first mismatch between the two arrays, + * otherwise {@code -1}. + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(long[] a, long[] b) { + int length = Math.min(a.length, b.length); // Check null array refs + if (a == b) + return -1; + + for (int i = 0; i < length; i++) { + if (a[i] != b[i]) return i; + } + + return a.length != b.length ? length : -1; + } + + /** + * Finds and returns the relative index of the first mismatch between two + * {@code long} arrays over the specified ranges, otherwise return -1 if no + * mismatch is found. The index will be in the range of 0 (inclusive) up to + * the length (inclusive) of the smaller range. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the returned relative index is the length of the common prefix and + * it follows that there is a mismatch between the two elements at that + * relative index within the respective arrays. + * If one array is a proper prefix of the other, over the specified ranges, + * then the returned relative index is the length of the smaller range and + * it follows that the relative index is only valid for the array with the + * larger range. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, aFromIndex, aFromIndex + pl, b, bFromIndex, bFromIndex + pl) &&
+     *     a[aFromIndex + pl] != b[bFromIndex + pl]
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a proper + * if the following expression is true: + *

{@code
+     *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   b, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested for a mismatch + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return the relative index of the first mismatch between the two arrays + * over the specified ranges, otherwise {@code -1}. + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(long[] a, int aFromIndex, int aToIndex, + long[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + if (a[aFromIndex++] != b[bFromIndex++]) return i; + } + + return aLength != bLength ? length : -1; + } + + // Mismatch float + + /** + * Finds and returns the index of the first mismatch between two {@code float} + * arrays, otherwise return -1 if no mismatch is found. The index will be + * in the range of 0 (inclusive) up to the length (inclusive) of the smaller + * array. + * + *

If the two arrays share a common prefix then the returned index is the + * length of the common prefix and it follows that there is a mismatch + * between the two elements at that index within the respective arrays. + * If one array is a proper prefix of the other then the returned index is + * the length of the smaller array and it follows that the index is only + * valid for the larger array. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(a.length, b.length) &&
+     *     Arrays.equals(a, 0, pl, b, 0, pl) &&
+     *     Float.compare(a[pl], b[pl]) != 0
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a proper + * prefix if the following expression is true: + *

{@code
+     *     a.length != b.length &&
+     *     Arrays.equals(a, 0, Math.min(a.length, b.length),
+     *                   b, 0, Math.min(a.length, b.length))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param b the second array to be tested for a mismatch + * @return the index of the first mismatch between the two arrays, + * otherwise {@code -1}. + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(float[] a, float[] b) { + int length = Math.min(a.length, b.length); // Check null array refs + if (a == b) + return -1; + + for (int i = 0; i < length; i++) { + float va = a[i], vb = b[i]; + if (Float.floatToRawIntBits(va) != Float.floatToRawIntBits(vb)) + if (!Float.isNaN(va) || !Float.isNaN(vb)) + return i; + } + + return a.length != b.length ? length : -1; + } + + /** + * Finds and returns the relative index of the first mismatch between two + * {@code float} arrays over the specified ranges, otherwise return -1 if no + * mismatch is found. The index will be in the range of 0 (inclusive) up to + * the length (inclusive) of the smaller range. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the returned relative index is the length of the common prefix and + * it follows that there is a mismatch between the two elements at that + * relative index within the respective arrays. + * If one array is a proper prefix of the other, over the specified ranges, + * then the returned relative index is the length of the smaller range and + * it follows that the relative index is only valid for the array with the + * larger range. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, aFromIndex, aFromIndex + pl, b, bFromIndex, bFromIndex + pl) &&
+     *     Float.compare(a[aFromIndex + pl], b[bFromIndex + pl]) != 0
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a proper + * if the following expression is true: + *

{@code
+     *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   b, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested for a mismatch + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return the relative index of the first mismatch between the two arrays + * over the specified ranges, otherwise {@code -1}. + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(float[] a, int aFromIndex, int aToIndex, + float[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + float va = a[aFromIndex++], vb = b[bFromIndex++]; + if (Float.floatToRawIntBits(va) != Float.floatToRawIntBits(vb)) + if (!Float.isNaN(va) || !Float.isNaN(vb)) + return i; + } + + return aLength != bLength ? length : -1; + } + + // Mismatch double + + /** + * Finds and returns the index of the first mismatch between two + * {@code double} arrays, otherwise return -1 if no mismatch is found. The + * index will be in the range of 0 (inclusive) up to the length (inclusive) + * of the smaller array. + * + *

If the two arrays share a common prefix then the returned index is the + * length of the common prefix and it follows that there is a mismatch + * between the two elements at that index within the respective arrays. + * If one array is a proper prefix of the other then the returned index is + * the length of the smaller array and it follows that the index is only + * valid for the larger array. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(a.length, b.length) &&
+     *     Arrays.equals(a, 0, pl, b, 0, pl) &&
+     *     Double.compare(a[pl], b[pl]) != 0
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a proper + * prefix if the following expression is true: + *

{@code
+     *     a.length != b.length &&
+     *     Arrays.equals(a, 0, Math.min(a.length, b.length),
+     *                   b, 0, Math.min(a.length, b.length))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param b the second array to be tested for a mismatch + * @return the index of the first mismatch between the two arrays, + * otherwise {@code -1}. + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(double[] a, double[] b) { + int length = Math.min(a.length, b.length); // Check null array refs + if (a == b) + return -1; + + for (int i = 0; i < length; i++) { + double va = a[i], vb = b[i]; + if (Double.doubleToRawLongBits(va) != Double.doubleToRawLongBits(vb)) + if (!Double.isNaN(va) || !Double.isNaN(vb)) + return i; + } + + return a.length != b.length ? length : -1; + } + + /** + * Finds and returns the relative index of the first mismatch between two + * {@code double} arrays over the specified ranges, otherwise return -1 if + * no mismatch is found. The index will be in the range of 0 (inclusive) up + * to the length (inclusive) of the smaller range. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the returned relative index is the length of the common prefix and + * it follows that there is a mismatch between the two elements at that + * relative index within the respective arrays. + * If one array is a proper prefix of the other, over the specified ranges, + * then the returned relative index is the length of the smaller range and + * it follows that the relative index is only valid for the array with the + * larger range. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, aFromIndex, aFromIndex + pl, b, bFromIndex, bFromIndex + pl) &&
+     *     Double.compare(a[aFromIndex + pl], b[bFromIndex + pl]) != 0
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a proper + * if the following expression is true: + *

{@code
+     *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   b, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested for a mismatch + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return the relative index of the first mismatch between the two arrays + * over the specified ranges, otherwise {@code -1}. + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(double[] a, int aFromIndex, int aToIndex, + double[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + double va = a[aFromIndex++], vb = b[bFromIndex++]; + if (Double.doubleToRawLongBits(va) != Double.doubleToRawLongBits(vb)) + if (!Double.isNaN(va) || !Double.isNaN(vb)) + return i; + } + + return aLength != bLength ? length : -1; + } + + // Mismatch objects + + /** + * Finds and returns the index of the first mismatch between two + * {@code Object} arrays, otherwise return -1 if no mismatch is found. The + * index will be in the range of 0 (inclusive) up to the length (inclusive) + * of the smaller array. + * + *

If the two arrays share a common prefix then the returned index is the + * length of the common prefix and it follows that there is a mismatch + * between the two elements at that index within the respective arrays. + * If one array is a proper prefix of the other then the returned index is + * the length of the smaller array and it follows that the index is only + * valid for the larger array. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(a.length, b.length) &&
+     *     Arrays.equals(a, 0, pl, b, 0, pl) &&
+     *     !Objects.equals(a[pl], b[pl])
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a proper + * prefix if the following expression is true: + *

{@code
+     *     a.length != b.length &&
+     *     Arrays.equals(a, 0, Math.min(a.length, b.length),
+     *                   b, 0, Math.min(a.length, b.length))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param b the second array to be tested for a mismatch + * @return the index of the first mismatch between the two arrays, + * otherwise {@code -1}. + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch(Object[] a, Object[] b) { + int length = Math.min(a.length, b.length); // Check null array refs + if (a == b) + return -1; + + for (int i = 0; i < length; i++) { + if (!Objects.equals(a[i], b[i])) + return i; + } + + return a.length != b.length ? length : -1; + } + + /** + * Finds and returns the relative index of the first mismatch between two + * {@code Object} arrays over the specified ranges, otherwise return -1 if + * no mismatch is found. The index will be in the range of 0 (inclusive) up + * to the length (inclusive) of the smaller range. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the returned relative index is the length of the common prefix and + * it follows that there is a mismatch between the two elements at that + * relative index within the respective arrays. + * If one array is a proper prefix of the other, over the specified ranges, + * then the returned relative index is the length of the smaller range and + * it follows that the relative index is only valid for the array with the + * larger range. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, aFromIndex, aFromIndex + pl, b, bFromIndex, bFromIndex + pl) &&
+     *     !Objects.equals(a[aFromIndex + pl], b[bFromIndex + pl])
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a proper + * if the following expression is true: + *

{@code
+     *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
+     *     Arrays.equals(a, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   b, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested for a mismatch + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @return the relative index of the first mismatch between the two arrays + * over the specified ranges, otherwise {@code -1}. + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array is {@code null} + * @since 9 + */ + public static int mismatch( + Object[] a, int aFromIndex, int aToIndex, + Object[] b, int bFromIndex, int bToIndex) { + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + if (!Objects.equals(a[aFromIndex++], b[bFromIndex++])) + return i; + } + + return aLength != bLength ? length : -1; + } + + /** + * Finds and returns the index of the first mismatch between two + * {@code Object} arrays, otherwise return -1 if no mismatch is found. + * The index will be in the range of 0 (inclusive) up to the length + * (inclusive) of the smaller array. + * + *

The specified comparator is used to determine if two array elements + * from the each array are not equal. + * + *

If the two arrays share a common prefix then the returned index is the + * length of the common prefix and it follows that there is a mismatch + * between the two elements at that index within the respective arrays. + * If one array is a proper prefix of the other then the returned index is + * the length of the smaller array and it follows that the index is only + * valid for the larger array. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(a.length, b.length) &&
+     *     IntStream.range(0, pl).
+     *         map(i -> cmp.compare(a[i], b[i])).
+     *         allMatch(c -> c == 0) &&
+     *     cmp.compare(a[pl], b[pl]) != 0
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b}, share a proper + * prefix if the following expression is true: + *

{@code
+     *     a.length != b.length &&
+     *     IntStream.range(0, Math.min(a.length, b.length)).
+     *         map(i -> cmp.compare(a[i], b[i])).
+     *         allMatch(c -> c == 0) &&
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param b the second array to be tested for a mismatch + * @param cmp the comparator to compare array elements + * @param the type of array elements + * @return the index of the first mismatch between the two arrays, + * otherwise {@code -1}. + * @throws NullPointerException + * if either array or the comparator is {@code null} + * @since 9 + */ + public static int mismatch(T[] a, T[] b, Comparator cmp) { + Objects.requireNonNull(cmp); + int length = Math.min(a.length, b.length); // Check null array refs + if (a == b) + return -1; + + for (int i = 0; i < length; i++) { + T oa = a[i]; + T ob = b[i]; + if (oa != ob) { + // Null-value comparison is deferred to the comparator + int v = cmp.compare(oa, ob); + if (v != 0) { + return i; + } + } + } + + return a.length != b.length ? length : -1; + } + + /** + * Finds and returns the relative index of the first mismatch between two + * {@code Object} arrays over the specified ranges, otherwise return -1 if + * no mismatch is found. The index will be in the range of 0 (inclusive) up + * to the length (inclusive) of the smaller range. + * + *

If the two arrays, over the specified ranges, share a common prefix + * then the returned relative index is the length of the common prefix and + * it follows that there is a mismatch between the two elements at that + * relative index within the respective arrays. + * If one array is a proper prefix of the other, over the specified ranges, + * then the returned relative index is the length of the smaller range and + * it follows that the relative index is only valid for the array with the + * larger range. + * Otherwise, there is no mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a common + * prefix of length {@code pl} if the following expression is true: + *

{@code
+     *     pl >= 0 &&
+     *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
+     *     IntStream.range(0, pl).
+     *         map(i -> cmp.compare(a[aFromIndex + i], b[bFromIndex + i])).
+     *         allMatch(c -> c == 0) &&
+     *     cmp.compare(a[aFromIndex + pl], b[bFromIndex + pl]) != 0
+     * }
+ * Note that a common prefix length of {@code 0} indicates that the first + * elements from each array mismatch. + * + *

Two non-{@code null} arrays, {@code a} and {@code b} with specified + * ranges [{@code aFromIndex}, {@code atoIndex}) and + * [{@code bFromIndex}, {@code btoIndex}) respectively, share a proper + * if the following expression is true: + *

{@code
+     *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
+     *     IntStream.range(0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex)).
+     *         map(i -> cmp.compare(a[aFromIndex + i], b[bFromIndex + i])).
+     *         allMatch(c -> c == 0)
+     * }
+ * + * @param a the first array to be tested for a mismatch + * @param aFromIndex the index (inclusive) of the first element in the + * first array to be tested + * @param aToIndex the index (exclusive) of the last element in the + * first array to be tested + * @param b the second array to be tested for a mismatch + * @param bFromIndex the index (inclusive) of the first element in the + * second array to be tested + * @param bToIndex the index (exclusive) of the last element in the + * second array to be tested + * @param cmp the comparator to compare array elements + * @param the type of array elements + * @return the relative index of the first mismatch between the two arrays + * over the specified ranges, otherwise {@code -1}. + * @throws IllegalArgumentException + * if {@code aFromIndex > aToIndex} or + * if {@code bFromIndex > bToIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code aFromIndex < 0 or aToIndex > a.length} or + * if {@code bFromIndex < 0 or bToIndex > b.length} + * @throws NullPointerException + * if either array or the comparator is {@code null} + * @since 9 + */ + public static int mismatch( + T[] a, int aFromIndex, int aToIndex, + T[] b, int bFromIndex, int bToIndex, + Comparator cmp) { + Objects.requireNonNull(cmp); + rangeCheck(a.length, aFromIndex, aToIndex); + rangeCheck(b.length, bFromIndex, bToIndex); + + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + int length = Math.min(aLength, bLength); + for (int i = 0; i < length; i++) { + T oa = a[aFromIndex++]; + T ob = b[bFromIndex++]; + if (oa != ob) { + // Null-value comparison is deferred to the comparator + int v = cmp.compare(oa, ob); + if (v != 0) { + return i; + } + } + } + + return aLength != bLength ? length : -1; + } +} \ No newline at end of file diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java --- a/jdk/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java Wed Jul 05 20:58:59 2017 +0200 @@ -123,25 +123,27 @@ *
    *
  • "CLDR": A provider based on Unicode Consortium's * CLDR Project. - *
  • "JRE": represents the locale sensitive services that is compatible - * with the prior JDK releases (same with JDK8's "JRE"). + *
  • "COMPAT": represents the locale sensitive services that is compatible + * with the prior JDK releases up to JDK8 (same as JDK8's "JRE"). *
  • "SPI": represents the locale sensitive services implementing the subclasses of * this {@code LocaleServiceProvider} class. *
  • "HOST": A provider that reflects the user's custom settings in the * underlying operating system. This provider may not be available, depending * on the Java Runtime Environment implementation. + *
  • "JRE": represents a synonym to "COMPAT". This name + * is deprecated and will be removed in the future release of JDK. *
*

* For example, if the following is specified in the property: *

- * java.locale.providers=SPI,CLDR,JRE
+ * java.locale.providers=SPI,CLDR,COMPAT
  * 
* the locale sensitive services in the SPI providers are looked up first. If the * desired locale sensitive service is not available, then the runtime looks for CLDR, - * JRE in that order. + * COMPAT in that order. *

- * The default order for looking up the preferred locale providers is "CLDR,JRE", - * so specifying "CLDR,JRE" is identical to the default behavior. Applications which + * The default order for looking up the preferred locale providers is "CLDR,COMPAT", + * so specifying "CLDR,COMPAT" is identical to the default behavior. Applications which * require implementations of the locale sensitive services must explicitly specify * "SPI" in order for the Java runtime to load them from the classpath. * diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java --- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Wed Jul 05 20:58:59 2017 +0200 @@ -124,6 +124,10 @@ if (order != null && order.length() != 0) { String[] types = order.split(","); for (String type : types) { + type = type.trim().toUpperCase(Locale.ROOT); + if (type.equals("COMPAT")) { + type = "JRE"; + } try { Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT)); if (!typeList.contains(aType)) { diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.base/share/native/libjimage/ImageNativeSubstrate.cpp --- a/jdk/src/java.base/share/native/libjimage/ImageNativeSubstrate.cpp Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.base/share/native/libjimage/ImageNativeSubstrate.cpp Wed Jul 05 20:58:59 2017 +0200 @@ -26,8 +26,7 @@ #include #include "jni.h" -#include "jni_util.h" -#include "jdk_util.h" + #include "endian.hpp" #include "imageDecompressor.hpp" #include "imageFile.hpp" @@ -39,6 +38,17 @@ extern bool MemoryMapImage; +///////////////////////////////////////////////////////////////////////////// + +// Static function for primitive throw since libjimage is not linked with libjava +static void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg) +{ + jclass cls = (env)->FindClass(name); + + if (cls != 0) /* Otherwise an exception has already been thrown */ + (env)->ThrowNew(cls, msg); +} + // jdk.internal.jimage ///////////////////////////////////////////////////////// // Java entry to open an image file for sharing. @@ -446,6 +456,23 @@ jlong size = 0; jlong ret = 0; + if (moduleName == NULL) { + ThrowByName(env, "java/lang/NullPointerException", "moduleName"); + return 0; + } + if (version == NULL) { + ThrowByName(env, "java/lang/NullPointerException", "version"); + return 0; + } + if (path == NULL) { + ThrowByName(env, "java/lang/NullPointerException", "path"); + return 0; + } + if (output_size == NULL) { + ThrowByName(env, "java/lang/NullPointerException", "size"); + return 0; + } + do { native_module = env->GetStringUTFChars(moduleName, NULL); if (native_module == NULL) @@ -529,25 +556,47 @@ // Store if there is room in the array // Concatenate to get full path char fullpath[IMAGE_MAX_PATH]; - fullpath[0] = '\0'; - if (*module != '\0') { - strncpy(fullpath, "/", IMAGE_MAX_PATH - 1); - strncat(fullpath, module, IMAGE_MAX_PATH - 1); - strncat(fullpath, "/", IMAGE_MAX_PATH - 1); + size_t moduleLen = strlen(module); + size_t packageLen = strlen(package); + size_t nameLen = strlen(name); + size_t extLen = strlen(extension); + size_t index; + + if (1 + moduleLen + 1 + packageLen + 1 + nameLen + 1 + extLen + 1 > IMAGE_MAX_PATH) { + ThrowByName(env, "java/lang/InternalError", "concatenated name too long"); + return true; } - if (*package != '\0') { - strncat(fullpath, package, IMAGE_MAX_PATH - 1); - strncat(fullpath, "/", IMAGE_MAX_PATH - 1); + + index = 0; + if (moduleLen > 0) { + fullpath[index++] = '/'; + memcpy(&fullpath[index], module, moduleLen); + index += moduleLen; + fullpath[index++] = '/'; } - strncat(fullpath, name, IMAGE_MAX_PATH - 1); - if (*extension != '\0') { - strncat(fullpath, ".", IMAGE_MAX_PATH - 1); - strncat(fullpath, extension, IMAGE_MAX_PATH - 1); + if (packageLen > 0) { + memcpy(&fullpath[index], package, packageLen); + index += packageLen; + fullpath[index++] = '/'; + } + memcpy(&fullpath[index], name, nameLen); + index += nameLen; + if (extLen > 0) { + fullpath[index++] = '.'; + memcpy(&fullpath[index], extension, extLen); + index += extLen; } + fullpath[index++] = '\0'; + jobject str = env->NewStringUTF(fullpath); - JNU_CHECK_EXCEPTION_RETURN(env, true); + if (env->ExceptionCheck()) { + return true; + } + env->SetObjectArrayElement(vdata->array, vdata->size, str); - JNU_CHECK_EXCEPTION_RETURN(env, true); + if (env->ExceptionCheck()) { + return true; + } } vdata->size++; // always count so the total size is returned return true; @@ -584,7 +633,10 @@ jstring module = NULL; native_package = env->GetStringUTFChars(package_name, NULL); - JNU_CHECK_EXCEPTION_RETURN(env, NULL); + if (env->ExceptionCheck()) { + return NULL; + } + native_module = JIMAGE_PackageToModule((JImageFile*) jimageHandle, native_package); if (native_module != NULL) { diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.base/share/native/libjimage/jimage.cpp --- a/jdk/src/java.base/share/native/libjimage/jimage.cpp Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.base/share/native/libjimage/jimage.cpp Wed Jul 05 20:58:59 2017 +0200 @@ -102,14 +102,29 @@ extern "C" JImageLocationRef JIMAGE_FindResource(JImageFile* image, const char* module_name, const char* version, const char* name, jlong* size) { - ImageLocation location; + // Concatenate to get full path char fullpath[IMAGE_MAX_PATH]; + size_t moduleNameLen = strlen(module_name); + size_t nameLen = strlen(name); + size_t index; + + // TBD: assert(moduleNameLen > 0 && "module name must be non-empty"); + assert(nameLen > 0 && "name must non-empty"); - // Concatenate to get full path - strncpy(fullpath, "/", IMAGE_MAX_PATH - 1); - strncat(fullpath, module_name, IMAGE_MAX_PATH - 1); - strncat(fullpath, "/", IMAGE_MAX_PATH - 1); - strncat(fullpath, name, IMAGE_MAX_PATH - 1); + // If the concatenated string is too long for the buffer, return not found + if (1 + moduleNameLen + 1 + nameLen + 1 > IMAGE_MAX_PATH) { + return 0L; + } + + index = 0; + fullpath[index++] = '/'; + memcpy(&fullpath[index], module_name, moduleNameLen); + index += moduleNameLen; + fullpath[index++] = '/'; + memcpy(&fullpath[index], name, nameLen); + index += nameLen; + fullpath[index++] = '\0'; + JImageLocationRef loc = (JImageLocationRef) ((ImageFileReader*) image)->find_location_index(fullpath, (u8*) size); return loc; diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.datatransfer/macosx/classes/sun/datatransfer/resources/flavormap.properties --- a/jdk/src/java.datatransfer/macosx/classes/sun/datatransfer/resources/flavormap.properties Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.datatransfer/macosx/classes/sun/datatransfer/resources/flavormap.properties Wed Jul 05 20:58:59 2017 +0200 @@ -72,6 +72,7 @@ TIFF=image/x-java-image;class=java.awt.Image RICH_TEXT=text/rtf HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1 -URL=application/x-java-url;class=java.net.URL,\ - text/uri-list;eoln="\r\n";terminators=1 +URL=application/x-java-url;class=java.net.URL +FILE_NAME=text/uri-list;eoln="\r\n";terminators=1 +URL=text/uri-list;eoln="\r\n";terminators=1 XPICT=image/x-pict;class=java.io.InputStream diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneUI.java --- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneUI.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneUI.java Wed Jul 05 20:58:59 2017 +0200 @@ -845,7 +845,7 @@ boolean isDefaultFocusReceiver(final JComponent component) { if (isDefaultFocusReceiver == null) { Component defaultFocusReceiver = KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTraversalPolicy().getDefaultComponent(getTopLevelFocusCycleRootAncestor(component)); - isDefaultFocusReceiver = new Boolean(defaultFocusReceiver != null && defaultFocusReceiver.equals(component)); + isDefaultFocusReceiver = defaultFocusReceiver != null && defaultFocusReceiver.equals(component); } return isDefaultFocusReceiver.booleanValue(); } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java Wed Jul 05 20:58:59 2017 +0200 @@ -175,7 +175,7 @@ final AccessibleSelection as = ac.getAccessibleSelection(); if (as == null) return Boolean.FALSE; - return new Boolean(as.isAccessibleChildSelected(index)); + return as.isAccessibleChildSelected(index); } }, c); } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java Wed Jul 05 20:58:59 2017 +0200 @@ -1,3 +1,4 @@ + /* * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -28,12 +29,13 @@ import java.awt.*; import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.Charset; import java.text.Normalizer; import java.text.Normalizer.Form; import java.util.*; -import java.util.regex.*; import java.awt.datatransfer.*; import sun.awt.datatransfer.*; @@ -127,51 +129,33 @@ long format, Transferable transferable) throws IOException { if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass())) { - String charset = Charset.defaultCharset().name(); - if (transferable != null && transferable.isDataFlavorSupported(javaTextEncodingFlavor)) { - try { - charset = new String((byte[]) transferable.getTransferData(javaTextEncodingFlavor), "UTF-8"); - } catch (UnsupportedFlavorException cannotHappen) { - } + String[] strings = dragQueryFile(bytes); + if(strings == null || strings.length == 0) { + return null; } - String xml = new String(bytes, charset); - // macosx pasteboard returns a property list that consists of one URL - // let's extract it. - return new URL(extractURL(xml)); - } - - if (format == CF_STRING) { + return new URL(strings[0]); + } else if(isUriListFlavor(flavor)) { + // dragQueryFile works fine with files and url, + // it parses and extracts values from property list. + // maxosx always returns property list for + // CF_URL and CF_FILE + String[] strings = dragQueryFile(bytes); + if(strings == null) { + return null; + } + bytes = String.join(System.getProperty("line.separator"), + strings).getBytes(); + // now we extracted uri from xml, now we should treat it as + // regular string that allows to translate data to target represantation + // class by base method + format = CF_STRING; + } else if (format == CF_STRING) { bytes = Normalizer.normalize(new String(bytes, "UTF8"), Form.NFC).getBytes("UTF8"); } return super.translateBytes(bytes, flavor, format, transferable); } - /** - * Macosx pasteboard returns xml document that contains one URL, for exmple: - *

-     *     {@code
-     * 
-     * 
-     * 
-     *      
-     *          file:///path_to_file
-     *          
-     *      
-     * 
-     *     }
-     * 
- */ - private String extractURL(String xml) { - Pattern urlExtractorPattern = Pattern.compile("(.*)"); - Matcher matcher = urlExtractorPattern.matcher(xml); - if (matcher.find()) { - return matcher.group(1); - } else { - return null; - } - } - @Override protected synchronized Long getFormatForNativeAsLong(String str) { Long format = predefinedClipboardNameMap.get(str); @@ -247,6 +231,7 @@ return nativeDragQueryFile(bytes); } + @Override protected Image platformImageBytesToImage(byte[] bytes, long format) throws IOException { return CImage.getCreator().createImageFromPlatformImageBytes(bytes); @@ -271,7 +256,7 @@ } try { DataFlavor df = new DataFlavor(nat); - if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) { + if (isUriListFlavor(df)) { return true; } } catch (Exception e) { @@ -279,4 +264,11 @@ } return false; } + + private boolean isUriListFlavor(DataFlavor df) { + if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) { + return true; + } + return false; + } } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Wed Jul 05 20:58:59 2017 +0200 @@ -380,7 +380,7 @@ desktopProperties.put("DnD.Autoscroll.interval", new Integer(50)); desktopProperties.put("DnD.Autoscroll.cursorHysteresis", new Integer(5)); - desktopProperties.put("DnD.isDragImageSupported", new Boolean(true)); + desktopProperties.put("DnD.isDragImageSupported", Boolean.TRUE); // Register DnD cursors desktopProperties.put("DnD.Cursor.CopyDrop", new NamedCursor("DnD.Cursor.CopyDrop")); diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsEnv.m --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsEnv.m Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsEnv.m Wed Jul 05 20:58:59 2017 +0200 @@ -26,6 +26,7 @@ #import "AWT_debug.h" #import "jni_util.h" +#import "ThreadUtilities.h" #import @@ -114,17 +115,20 @@ { if (flags == kCGDisplayBeginConfigurationFlag) return; - JNFPerformEnvBlock(JNFThreadDetachImmediately, ^(JNIEnv *env) { - JNFWeakJObjectWrapper *wrapper = (JNFWeakJObjectWrapper *)userInfo; + [ThreadUtilities performOnMainThreadWaiting:NO block:^() { + + JNFPerformEnvBlock(JNFThreadDetachImmediately, ^(JNIEnv *env) { + JNFWeakJObjectWrapper *wrapper = (JNFWeakJObjectWrapper *)userInfo; - jobject graphicsEnv = [wrapper jObjectWithEnv:env]; - if (graphicsEnv == NULL) return; // ref already GC'd - static JNF_CLASS_CACHE(jc_CGraphicsEnvironment, "sun/awt/CGraphicsEnvironment"); - static JNF_MEMBER_CACHE(jm_displayReconfiguration, jc_CGraphicsEnvironment, "_displayReconfiguration", "(IZ)V"); - JNFCallVoidMethod(env, graphicsEnv, jm_displayReconfiguration, - (jint) display, - (jboolean) flags & kCGDisplayRemoveFlag); - }); + jobject graphicsEnv = [wrapper jObjectWithEnv:env]; + if (graphicsEnv == NULL) return; // ref already GC'd + static JNF_CLASS_CACHE(jc_CGraphicsEnvironment, "sun/awt/CGraphicsEnvironment"); + static JNF_MEMBER_CACHE(jm_displayReconfiguration, + jc_CGraphicsEnvironment, "_displayReconfiguration","(IZ)V"); + JNFCallVoidMethod(env, graphicsEnv, jm_displayReconfiguration, + (jint) display, (jboolean) flags & kCGDisplayRemoveFlag); + }); + }]; } /* diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m Wed Jul 05 20:58:59 2017 +0200 @@ -233,6 +233,7 @@ } NSOpenGLPixelFormatAttribute attrs[] = { + NSOpenGLPFAAllowOfflineRenderers, NSOpenGLPFAClosestPolicy, NSOpenGLPFAWindow, NSOpenGLPFAPixelBuffer, diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPMetadata.java --- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPMetadata.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPMetadata.java Wed Jul 05 20:58:59 2017 +0200 @@ -247,11 +247,11 @@ node.appendChild(subNode); subNode = new IIOMetadataNode("HorizontalPhysicalPixelSpacing"); - subNode.setAttribute("value", "" + (1 / xPixelsPerMeter * 1000)); + subNode.setAttribute("value", "" + (1000.0F / xPixelsPerMeter)); node.appendChild(subNode); subNode = new IIOMetadataNode("VerticalPhysicalPixelSpacing"); - subNode.setAttribute("value", "" + (1 / yPixelsPerMeter * 1000)); + subNode.setAttribute("value", "" + (1000.0F / yPixelsPerMeter)); node.appendChild(subNode); return node; diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/share/classes/java/awt/Component.java --- a/jdk/src/java.desktop/share/classes/java/awt/Component.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java Wed Jul 05 20:58:59 2017 +0200 @@ -312,7 +312,7 @@ * @see GraphicsConfiguration * @see #getGraphicsConfiguration */ - private transient GraphicsConfiguration graphicsConfig = null; + private transient volatile GraphicsConfiguration graphicsConfig; /** * A reference to a BufferStrategy object @@ -1143,9 +1143,7 @@ * @since 1.3 */ public GraphicsConfiguration getGraphicsConfiguration() { - synchronized(getTreeLock()) { - return getGraphicsConfiguration_NoClientCode(); - } + return getGraphicsConfiguration_NoClientCode(); } final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() { @@ -3622,18 +3620,17 @@ } /** - * Creates an off-screen drawable image - * to be used for double buffering. - * @param width the specified width - * @param height the specified height - * @return an off-screen drawable image, which can be used for double - * buffering. The return value may be null if the - * component is not displayable. This will always happen if - * GraphicsEnvironment.isHeadless() returns - * true. + * Creates an off-screen drawable image to be used for double buffering. + * + * @param width the specified width + * @param height the specified height + * @return an off-screen drawable image, which can be used for double + * buffering. The {@code null} value if the component is not + * displayable or {@code GraphicsEnvironment.isHeadless()} returns + * {@code true}. * @see #isDisplayable * @see GraphicsEnvironment#isHeadless - * @since 1.0 + * @since 1.0 */ public Image createImage(int width, int height) { ComponentPeer peer = this.peer; @@ -3646,19 +3643,19 @@ } /** - * Creates a volatile off-screen drawable image - * to be used for double buffering. - * @param width the specified width. - * @param height the specified height. - * @return an off-screen drawable image, which can be used for double - * buffering. The return value may be null if the - * component is not displayable. This will always happen if - * GraphicsEnvironment.isHeadless() returns - * true. + * Creates a volatile off-screen drawable image to be used for double + * buffering. + * + * @param width the specified width + * @param height the specified height + * @return an off-screen drawable image, which can be used for double + * buffering. The {@code null} value if the component is not + * displayable or {@code GraphicsEnvironment.isHeadless()} returns + * {@code true}. * @see java.awt.image.VolatileImage * @see #isDisplayable * @see GraphicsEnvironment#isHeadless - * @since 1.4 + * @since 1.4 */ public VolatileImage createVolatileImage(int width, int height) { ComponentPeer peer = this.peer; @@ -3674,22 +3671,26 @@ } /** - * Creates a volatile off-screen drawable image, with the given capabilities. - * The contents of this image may be lost at any time due - * to operating system issues, so the image must be managed - * via the VolatileImage interface. - * @param width the specified width. - * @param height the specified height. - * @param caps the image capabilities - * @exception AWTException if an image with the specified capabilities cannot - * be created - * @return a VolatileImage object, which can be used - * to manage surface contents loss and capabilities. + * Creates a volatile off-screen drawable image, with the given + * capabilities. The contents of this image may be lost at any time due to + * operating system issues, so the image must be managed via the + * {@code VolatileImage} interface. + * + * @param width the specified width + * @param height the specified height + * @param caps the image capabilities + * @return a VolatileImage object, which can be used to manage surface + * contents loss and capabilities. The {@code null} value if the + * component is not displayable or + * {@code GraphicsEnvironment.isHeadless()} returns {@code true}. + * @throws AWTException if an image with the specified capabilities cannot + * be created * @see java.awt.image.VolatileImage * @since 1.4 */ public VolatileImage createVolatileImage(int width, int height, - ImageCapabilities caps) throws AWTException { + ImageCapabilities caps) + throws AWTException { // REMIND : check caps return createVolatileImage(width, height); } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/share/classes/java/awt/Window.java --- a/jdk/src/java.desktop/share/classes/java/awt/Window.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/share/classes/java/awt/Window.java Wed Jul 05 20:58:59 2017 +0200 @@ -347,7 +347,7 @@ * @see #getOpacity() * @since 1.7 */ - private float opacity = 1.0f; + private volatile float opacity = 1.0f; /** * The shape assigned to this window. This field is set to {@code null} if @@ -1040,9 +1040,7 @@ closeSplashScreen(); Dialog.checkShouldBeBlocked(this); super.show(); - synchronized (getTreeLock()) { - this.locationByPlatform = false; - } + locationByPlatform = false; for (int i = 0; i < ownedWindowList.size(); i++) { Window child = ownedWindowList.elementAt(i).get(); if ((child != null) && child.showWithParent) { @@ -1115,9 +1113,7 @@ modalBlocker.unblockWindow(this); } super.hide(); - synchronized (getTreeLock()) { - this.locationByPlatform = false; - } + locationByPlatform = false; } final void clearMostRecentFocusOwnerOnHide() { @@ -3411,7 +3407,7 @@ return super.canContainFocusOwner(focusOwnerCandidate) && isFocusableWindow(); } - private boolean locationByPlatform = locationByPlatformProp; + private volatile boolean locationByPlatform = locationByPlatformProp; /** @@ -3482,9 +3478,7 @@ * @since 1.5 */ public boolean isLocationByPlatform() { - synchronized (getTreeLock()) { - return locationByPlatform; - } + return locationByPlatform; } /** @@ -3573,9 +3567,7 @@ * @since 1.7 */ public float getOpacity() { - synchronized (getTreeLock()) { - return opacity; - } + return opacity; } /** diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/share/classes/sun/swing/CachedPainter.java --- a/jdk/src/java.desktop/share/classes/sun/swing/CachedPainter.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/share/classes/sun/swing/CachedPainter.java Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -53,9 +53,7 @@ */ public abstract class CachedPainter { // CacheMap maps from class to ImageCache. - private static final Map cacheMap = - new HashMap(); - + private static final Map cacheMap = new HashMap<>(); private static ImageCache getCache(Object key) { synchronized(CachedPainter.class) { @@ -96,20 +94,8 @@ if (w <= 0 || h <= 0) { return; } - if (c != null) { - synchronized(c.getTreeLock()) { - synchronized(CachedPainter.class) { - // If c is non-null, synchronize on the tree lock. - // This is necessary because asking for the - // GraphicsConfiguration will grab a tree lock. - paint0(c, g, x, y, w, h, args); - } - } - } - else { - synchronized(CachedPainter.class) { - paint0(c, g, x, y, w, h, args); - } + synchronized (CachedPainter.class) { + paint0(c, g, x, y, w, h, args); } } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java Wed Jul 05 20:58:59 2017 +0200 @@ -272,7 +272,8 @@ } protected String[] getWMClass() { - return new String[] {XToolkit.getCorrectXIDString(getClass().getName()), XToolkit.getAWTAppClassName()}; + return new String[] {XToolkit.getAWTAppClassName(), + XToolkit.getAWTAppClassName()}; } void setReparented(boolean newValue) { @@ -992,10 +993,13 @@ // if ( Check if it's a resize, a move, or a stacking order change ) // { Rectangle bounds = getBounds(); + final ComponentAccessor acc = AWTAccessor.getComponentAccessor(); if (!bounds.getSize().equals(oldBounds.getSize())) { + acc.setSize(target, bounds.width, bounds.height); postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_RESIZED)); } if (!bounds.getLocation().equals(oldBounds.getLocation())) { + acc.setLocation(target, bounds.x, bounds.y); postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_MOVED)); } // } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java Wed Jul 05 20:58:59 2017 +0200 @@ -494,24 +494,48 @@ */ float fontSize = font.getSize2D(); + double devResX = wPrinterJob.getXRes(); + double devResY = wPrinterJob.getYRes(); + + double fontDevScaleY = devResY / DEFAULT_USER_RES; + + int orient = getPageFormat().getOrientation(); + if (orient == PageFormat.LANDSCAPE || + orient == PageFormat.REVERSE_LANDSCAPE) + { + double tmp = devResX; + devResX = devResY; + devResY = tmp; + } + + double devScaleX = devResX / DEFAULT_USER_RES; + double devScaleY = devResY / DEFAULT_USER_RES; + fontTransform.scale(1.0/devScaleX, 1.0/devScaleY); + Point2D.Double pty = new Point2D.Double(0.0, 1.0); fontTransform.deltaTransform(pty, pty); double scaleFactorY = Math.sqrt(pty.x*pty.x+pty.y*pty.y); - float scaledFontSizeY = (float)(fontSize * scaleFactorY); + float scaledFontSizeY = (float)(fontSize * scaleFactorY * fontDevScaleY); Point2D.Double ptx = new Point2D.Double(1.0, 0.0); fontTransform.deltaTransform(ptx, ptx); double scaleFactorX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y); - float scaledFontSizeX = (float)(fontSize * scaleFactorX); float awScale = getAwScale(scaleFactorX, scaleFactorY); int iangle = getAngle(ptx); + ptx = new Point2D.Double(1.0, 0.0); + deviceTransform.deltaTransform(ptx, ptx); + double advanceScaleX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y); + pty = new Point2D.Double(0.0, 1.0); + deviceTransform.deltaTransform(pty, pty); + double advanceScaleY = Math.sqrt(pty.x*pty.x+pty.y*pty.y); + Font2D font2D = FontUtilities.getFont2D(font); if (font2D instanceof TrueTypeFont) { textOut(str, font, (TrueTypeFont)font2D, frc, scaledFontSizeY, iangle, awScale, - deviceTransform, scaleFactorX, + advanceScaleX, advanceScaleY, x, y, devpos.x, devpos.y, targetW); } else if (font2D instanceof CompositeFont) { /* Composite fonts are made up of multiple fonts and each @@ -542,7 +566,7 @@ PhysicalFont slotFont = compFont.getSlotFont(slot); textOut(substr, font, slotFont, frc, scaledFontSizeY, iangle, awScale, - deviceTransform, scaleFactorX, + advanceScaleX, advanceScaleY, userx, usery, devx, devy, 0f); Rectangle2D bds = font.getStringBounds(substr, frc); float xAdvance = (float)bds.getWidth(); @@ -635,18 +659,42 @@ */ float fontSize = font.getSize2D(); + double devResX = wPrinterJob.getXRes(); + double devResY = wPrinterJob.getYRes(); + + double fontDevScaleY = devResY / DEFAULT_USER_RES; + + int orient = getPageFormat().getOrientation(); + if (orient == PageFormat.LANDSCAPE || + orient == PageFormat.REVERSE_LANDSCAPE) + { + double tmp = devResX; + devResX = devResY; + devResY = tmp; + } + + double devScaleX = devResX / DEFAULT_USER_RES; + double devScaleY = devResY / DEFAULT_USER_RES; + fontTransform.scale(1.0/devScaleX, 1.0/devScaleY); + Point2D.Double pty = new Point2D.Double(0.0, 1.0); fontTransform.deltaTransform(pty, pty); double scaleFactorY = Math.sqrt(pty.x*pty.x+pty.y*pty.y); - float scaledFontSizeY = (float)(fontSize * scaleFactorY); + float scaledFontSizeY = (float)(fontSize * scaleFactorY * fontDevScaleY); - Point2D.Double pt = new Point2D.Double(1.0, 0.0); - fontTransform.deltaTransform(pt, pt); - double scaleFactorX = Math.sqrt(pt.x*pt.x+pt.y*pt.y); - float scaledFontSizeX = (float)(fontSize * scaleFactorX); + Point2D.Double ptx = new Point2D.Double(1.0, 0.0); + fontTransform.deltaTransform(ptx, ptx); + double scaleFactorX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y); float awScale = getAwScale(scaleFactorX, scaleFactorY); - int iangle = getAngle(pt); + int iangle = getAngle(ptx); + + ptx = new Point2D.Double(1.0, 0.0); + deviceTransform.deltaTransform(ptx, ptx); + double advanceScaleX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y); + pty = new Point2D.Double(0.0, 1.0); + deviceTransform.deltaTransform(pty, pty); + double advanceScaleY = Math.sqrt(pty.x*pty.x+pty.y*pty.y); int numGlyphs = gv.getNumGlyphs(); int[] glyphCodes = gv.getGlyphCodes(0, numGlyphs, null); @@ -705,8 +753,7 @@ * rotation element of the deviceTransform. */ AffineTransform advanceTransform = - new AffineTransform(deviceTransform); - advanceTransform.rotate(iangle*Math.PI/1800.0); + AffineTransform.getScaleInstance(advanceScaleX, advanceScaleY); float[] glyphAdvPos = new float[glyphPos.length]; advanceTransform.transform(glyphPos, 0, //source @@ -784,8 +831,7 @@ Font font, PhysicalFont font2D, FontRenderContext frc, float deviceSize, int rotation, float awScale, - AffineTransform deviceTransform, - double scaleFactorX, + double scaleFactorX, double scaleFactorY, float userx, float usery, float devx, float devy, float targetW) { @@ -826,8 +872,7 @@ * See earlier comment in printGlyphVector() for details. */ AffineTransform advanceTransform = - new AffineTransform(deviceTransform); - advanceTransform.rotate(rotation*Math.PI/1800.0); + AffineTransform.getScaleInstance(scaleFactorX, scaleFactorY); float[] glyphAdvPos = new float[glyphPos.length]; advanceTransform.transform(glyphPos, 0, //source @@ -841,11 +886,11 @@ /* If 2D and GDI agree on the advance of the string we do not * need to explicitly assign glyph positions. * If we are to use the GDI advance, require it to agree with - * JDK to a precision of <= 0.2% - ie 1 pixel in 500 + * JDK to a precision of <= 1.0% - ie 1 pixel in 100 * discrepancy after rounding the 2D advance to the * nearest pixel and is greater than one pixel in total. - * ie strings < 500 pixels in length will be OK so long - * as they differ by only 1 pixel even though that is > 0.02% + * ie strings < 100 pixels in length will be OK so long + * as they differ by only 1 pixel even though that is > 1% * The bounds from 2D are in user space so need to * be scaled to device space for comparison with GDI. * scaleX is the scale from user space to device space needed for this. @@ -863,7 +908,7 @@ if (ratio < 1) { ratio = 1/ratio; } - return diff <= 1 || ratio < 1.002; + return diff <= 1 || ratio < 1.01; } return true; } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/windows/native/libawt/java2d/windows/GDIWindowSurfaceData.cpp --- a/jdk/src/java.desktop/windows/native/libawt/java2d/windows/GDIWindowSurfaceData.cpp Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/windows/native/libawt/java2d/windows/GDIWindowSurfaceData.cpp Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -114,8 +114,9 @@ // which may've been disposed by this time, and we have // no means of checking against it. if (oldhDC != NULL) { - MoveDCToPassiveList(oldhDC); + MoveDCToPassiveList(oldhDC, info->hWnd); info->hDC = NULL; + info->hWnd = NULL; } if (wsdo->window != NULL){ @@ -150,6 +151,7 @@ // Finally, set these new values in the info for this thread info->hDC = hDC; + info->hWnd = wsdo->window; } // cached brush and pen are not associated with any DC, and can be @@ -187,7 +189,7 @@ if (info->hDC != NULL) { // move the DC from the active dcs list to // the passive dc list to be released later - MoveDCToPassiveList(info->hDC); + MoveDCToPassiveList(info->hDC, info->hWnd); } if (info->clip != NULL) { diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/windows/native/libawt/java2d/windows/GDIWindowSurfaceData.h --- a/jdk/src/java.desktop/windows/native/libawt/java2d/windows/GDIWindowSurfaceData.h Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/windows/native/libawt/java2d/windows/GDIWindowSurfaceData.h Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -196,6 +196,7 @@ */ typedef struct { HDC hDC; + HWND hWnd; GDIWinSDOps *wsdo; LONG wsdoTimeStamp; // wsdo creation time stamp. // Other threads may deallocate wsdo diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp Wed Jul 05 20:58:59 2017 +0200 @@ -1382,7 +1382,7 @@ case WM_AWT_RELEASEDC: { HDC hDC = (HDC)wParam; - MoveDCToPassiveList(hDC); + MoveDCToPassiveList(hDC, GetHWnd()); ReleaseDCList(GetHWnd(), passiveDCList); mr = mrConsume; break; @@ -7165,8 +7165,8 @@ } /** - * Given a DC, remove it from the DC list and return - * TRUE if it exists on the current list. Otherwise + * Given a DC and window handle, remove the DC from the DC list + * and return TRUE if it exists on the current list. Otherwise * return FALSE. * A DC may not exist on the list because it has already * been released elsewhere (for example, the window @@ -7174,14 +7174,14 @@ * thread may also want to release a DC when it notices that * its DC is obsolete for the current window). */ -DCItem *DCList::RemoveDC(HDC hDC) +DCItem *DCList::RemoveDC(HDC hDC, HWND hWnd) { listLock.Enter(); DCItem **prevPtrPtr = &head; DCItem *listPtr = head; while (listPtr) { DCItem *nextPtr = listPtr->next; - if (listPtr->hDC == hDC) { + if (listPtr->hDC == hDC && listPtr->hWnd == hWnd) { *prevPtrPtr = nextPtr; break; } @@ -7235,9 +7235,9 @@ listLock.Leave(); } -void MoveDCToPassiveList(HDC hDC) { +void MoveDCToPassiveList(HDC hDC, HWND hWnd) { DCItem *removedDC; - if ((removedDC = activeDCList.RemoveDC(hDC)) != NULL) { + if ((removedDC = activeDCList.RemoveDC(hDC, hWnd)) != NULL) { passiveDCList.AddDCItem(removedDC); } } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.h --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.h Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.h Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -900,13 +900,13 @@ void AddDC(HDC hDC, HWND hWnd); void AddDCItem(DCItem *newItem); - DCItem *RemoveDC(HDC hDC); + DCItem *RemoveDC(HDC hDC, HWND hWnd); DCItem *RemoveAllDCs(HWND hWnd); void RealizePalettes(int screen); }; void ReleaseDCList(HWND hwnd, DCList &list); -void MoveDCToPassiveList(HDC hDC); +void MoveDCToPassiveList(HDC hDC, HWND hWnd); #include "ObjectList.h" diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.management/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java --- a/jdk/src/java.management/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.management/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Wed Jul 05 20:58:59 2017 +0200 @@ -60,6 +60,7 @@ import javax.management.JMX; import javax.management.ObjectName; +import javax.management.ConstructorParameters; import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeDataInvocationHandler; @@ -1132,8 +1133,8 @@ } /** Builder for when the target class has a constructor that is - annotated with @ConstructorProperties so we can see the correspondence - to getters. */ + annotated with {@linkplain ConstructorParameters @ConstructorParameters} + or {@code @ConstructorProperties} so we can see the correspondence to getters. */ private static final class CompositeBuilderViaConstructor extends CompositeBuilder { @@ -1141,10 +1142,19 @@ super(targetClass, itemNames); } + private String[] getConstPropValues(Constructor ctr) { + // is constructor annotated by javax.management.ConstructorParameters ? + ConstructorParameters ctrProps = ctr.getAnnotation(ConstructorParameters.class); + if (ctrProps != null) { + return ctrProps.value(); + } else { + // try the legacy java.beans.ConstructorProperties annotation + String[] vals = JavaBeansAccessor.getConstructorPropertiesValue(ctr); + return vals; + } + } + String applicable(Method[] getters) throws InvalidObjectException { - if (!JavaBeansAccessor.isAvailable()) - return "@ConstructorProperties annotation not available"; - Class targetClass = getTargetClass(); Constructor[] constrs = targetClass.getConstructors(); @@ -1152,12 +1162,13 @@ List> annotatedConstrList = newList(); for (Constructor constr : constrs) { if (Modifier.isPublic(constr.getModifiers()) - && JavaBeansAccessor.getConstructorPropertiesValue(constr) != null) + && getConstPropValues(constr) != null) annotatedConstrList.add(constr); } if (annotatedConstrList.isEmpty()) - return "no constructor has @ConstructorProperties annotation"; + return "no constructor has either @ConstructorParameters " + + "or @ConstructorProperties annotation"; annotatedConstructors = newList(); @@ -1181,13 +1192,17 @@ // so we can test unambiguity. Set getterIndexSets = newSet(); for (Constructor constr : annotatedConstrList) { - String[] propertyNames = JavaBeansAccessor.getConstructorPropertiesValue(constr); + String annotationName = + constr.isAnnotationPresent(ConstructorParameters.class) ? + "@ConstructorParameters" : "@ConstructorProperties"; + + String[] propertyNames = getConstPropValues(constr); Type[] paramTypes = constr.getGenericParameterTypes(); if (paramTypes.length != propertyNames.length) { final String msg = "Number of constructor params does not match " + - "@ConstructorProperties annotation: " + constr; + annotationName + " annotation: " + constr; throw new InvalidObjectException(msg); } @@ -1200,7 +1215,7 @@ String propertyName = propertyNames[i]; if (!getterMap.containsKey(propertyName)) { String msg = - "@ConstructorProperties includes name " + propertyName + + annotationName + " includes name " + propertyName + " which does not correspond to a property"; for (String getterName : getterMap.keySet()) { if (getterName.equalsIgnoreCase(propertyName)) { @@ -1215,7 +1230,7 @@ paramIndexes[getterIndex] = i; if (present.get(getterIndex)) { final String msg = - "@ConstructorProperties contains property " + + annotationName + " contains property " + propertyName + " more than once: " + constr; throw new InvalidObjectException(msg); } @@ -1224,7 +1239,7 @@ Type propertyType = getter.getGenericReturnType(); if (!propertyType.equals(paramTypes[i])) { final String msg = - "@ConstructorProperties gives property " + propertyName + + annotationName + " gives property " + propertyName + " of type " + propertyType + " for parameter " + " of type " + paramTypes[i] + ": " + constr; throw new InvalidObjectException(msg); @@ -1233,7 +1248,8 @@ if (!getterIndexSets.add(present)) { final String msg = - "More than one constructor has a @ConstructorProperties " + + "More than one constructor has " + + "@ConstructorParameters or @ConstructorProperties " + "annotation with this set of names: " + Arrays.toString(propertyNames); throw new InvalidObjectException(msg); @@ -1252,10 +1268,10 @@ * just the bigger constructor. * * The algorithm here is quadratic in the number of constructors - * with a @ConstructorProperties annotation. Typically this corresponds - * to the number of versions of the class there have been. Ten - * would already be a large number, so although it's probably - * possible to have an O(n lg n) algorithm it wouldn't be + * with a @ConstructorParameters or @ConstructructorProperties annotation. + * Typically this corresponds to the number of versions of the class + * there have been. Ten would already be a large number, so although + * it's probably possible to have an O(n lg n) algorithm it wouldn't be * worth the complexity. */ for (BitSet a : getterIndexSets) { @@ -1272,8 +1288,9 @@ i = u.nextSetBit(i+1)) names.add(itemNames[i]); final String msg = - "Constructors with @ConstructorProperties annotation " + - " would be ambiguous for these items: " + + "Constructors with @ConstructorParameters or " + + "@ConstructorProperties annotation " + + "would be ambiguous for these items: " + names; throw new InvalidObjectException(msg); } @@ -1310,7 +1327,8 @@ if (max == null) { final String msg = - "No constructor has a @ConstructorProperties for this set of " + + "No constructor has either @ConstructorParameters " + + "or @ConstructorProperties annotation for this set of " + "items: " + ct.keySet(); throw new InvalidObjectException(msg); } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.management/share/classes/javax/management/ConstructorParameters.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.management/share/classes/javax/management/ConstructorParameters.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2006, 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. + */ + +package javax.management; + +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +/** + *

+ * An annotation on a constructor that shows how the parameters of + * that constructor correspond to the constructed object's getter + * methods. For example: + *

+ *
+ *
+ *         public class MemoryUsage {
+ *             // standard JavaBean conventions with getters
+ *             @ConstructorParameters({"init", "used", "committed", "max"})
+ *             public MemoryUsage(long init, long used,
+ *                                long committed, long max) {...}
+ *             public long getInit() {...}
+ *             public long getUsed() {...}
+ *             public long getCommitted() {...}
+ *             public long getMax() {...}
+ *         }
+ *     
+ *
+ *

+ * The annotation shows that the first parameter of the constructor + * can be retrieved with the {@code getInit()} method, the second one with + * the {@code getUsed()} method, and so on. Since parameter names are not in + * general available at runtime, without the annotation there would be + * no way of knowing which parameter corresponds to which property. + *

+ *

+ * If a constructor is annotated by the both {@code @java.beans.ConstructorProperties} + * and {@code @javax.management.ConstructorParameters} annotations + * the JMX introspection will give an absolute precedence to the latter one. + *

+ * + * @since 1.9 + */ +@Documented @Target(CONSTRUCTOR) @Retention(RUNTIME) +public @interface ConstructorParameters { + /** + *

The getter names.

+ * + * @return the getter names corresponding to the parameters in the + * annotated constructor. + */ + String[] value(); +} diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.management/share/classes/javax/management/MXBean.java --- a/jdk/src/java.management/share/classes/javax/management/MXBean.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.management/share/classes/javax/management/MXBean.java Wed Jul 05 20:58:59 2017 +0200 @@ -153,7 +153,7 @@
 public class MemoryUsage {
     // standard JavaBean conventions with getters
-    @ConstructorProperties({"init", "used", "committed", "max"})
+    @ConstructorParameters({"init", "used", "committed", "max"})
     public MemoryUsage(long init, long used,
                        long committed, long max) {...}
     long getInit() {...}
@@ -168,8 +168,8 @@
     

The definitions are the same in the two cases, except that with the MXBean, MemoryUsage no longer needs to be marked Serializable (though it can be). On - the other hand, we have added a {@code @ConstructorProperties} annotation - to link the constructor parameters to the corresponding getters. + the other hand, we have added a {@link ConstructorParameters @ConstructorParameters} + annotation to link the constructor parameters to the corresponding getters. We will see more about this below.

MemoryUsage is a model-specific class. @@ -850,18 +850,24 @@ J.

  • Otherwise, if J has at least one public - constructor with a {@link java.beans.ConstructorProperties - ConstructorProperties} annotation, then one - of those constructors (not necessarily always the same one) - will be called to reconstruct an instance of J. + constructor with either {@link javax.management.ConstructorParameters + @javax.management.ConstructorParameters} or + {@code @java.beans.ConstructoProperties} annotation, then one of those + constructors (not necessarily always the same one) will be called to + reconstruct an instance of J. + If a constructor is annotated with both + {@code @javax.management.ConstructorParameters} and + {@code @java.beans.ConstructorProperties}, + {@code @javax.management.ConstructorParameters} will be used and + {@code @java.beans.ConstructorProperties} will be ignored. Every such annotation must list as many strings as the constructor has parameters; each string must name a property corresponding to a getter of J; and the type of this getter must be the same as the corresponding constructor parameter. It is not an error for there to be getters that - are not mentioned in the {@code ConstructorProperties} annotation - (these may correspond to information that is not needed to - reconstruct the object).

    + are not mentioned in the {@code @ConstructorParameters} or + {@code @ConstructorProperties} annotations (these may correspond to + information that is not needed to reconstruct the object).

    An instance of J is reconstructed by calling a constructor with the appropriate reconstructed items from the @@ -871,9 +877,10 @@ CompositeData} might come from an earlier version of J where not all the items were present. A constructor is applicable if all the properties named - in its {@code ConstructorProperties} annotation are present as items - in the {@code CompositeData}. If no constructor is - applicable, then the attempt to reconstruct J fails.

    + in its {@code @ConstructorParameters} or {@code @ConstructorProperties} + annotation are present as items in the {@code CompositeData}. + If no constructor is applicable, then the attempt to reconstruct + J fails.

    For any possible combination of properties, it must be the case that either (a) there are no applicable constructors, or @@ -909,8 +916,9 @@

  • Otherwise, J is not reconstructible.

  • -

    Rule 2 is not applicable to subset Profiles of Java SE that do not - include the {@code java.beans} package. When targeting a runtime that does +

    When only {@code @java.beans.ConstructorProperties} is present then + rule 2 is not applicable to subset Profiles of Java SE that do not include + the {@code java.beans} package. When targeting a runtime that does not include the {@code java.beans} package, and where there is a mismatch between the compile-time and runtime environment whereby J is compiled with a public constructor and the {@code ConstructorProperties} @@ -957,14 +965,14 @@ -

  • Public constructor with @ConstructorProperties annotation: +
  • Public constructor with @ConstructorParameters annotation:
     public class NamedNumber {
         public int getNumber() {return number;}
         public String getName() {return name;}
    -    @ConstructorProperties({"number", "name"})
    +    @ConstructorParameters({"number", "name"})
         public NamedNumber(int number, String name) {
             this.number = number;
             this.name = name;
    diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.rmi/unix/bin/java-rmi.cgi.sh
    --- a/jdk/src/java.rmi/unix/bin/java-rmi.cgi.sh	Wed Jul 05 20:58:49 2017 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,74 +0,0 @@
    -#!/bin/sh
    -
    -#
    -# Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
    -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    -#
    -# This code is free software; you can redistribute 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.
    -#
    -
    -#
    -#
    -
    -#
    -# This script executes the Java interpreter, defines properties
    -# that correspond to the CGI 1.0 environment variables, and executes
    -# the class "sun.rmi.transport.proxy.CGIHandler".  It should be
    -# installed in the directory to which the HTTP server maps the
    -# URL path "/cgi-bin".
    -#
    -# (Configuration is necessary as noted below.)
    -#
    -# This class will support a QUERY_STRING of the form "forward="
    -# with a REQUEST_METHOD "POST".  The body of the request will be
    -# forwarded (as another POST request) to the server listening on the
    -# specified port (must be >= 1024).  The response from this forwarded
    -# request will be the response to the original request.
    -#
    -# CONFIGURATION:
    -#
    -# Fill in correct absolute path to Java interpreter below.  For example,
    -# the "PATH=" line might be changed to the follow if the JDK is installed
    -# at the path "/home/peter/java":
    -#
    -# PATH=/home/peter/java/bin:$PATH
    -#
    -PATH=/usr/local/java/bin:$PATH
    -exec java \
    -	-DAUTH_TYPE="$AUTH_TYPE" \
    -	-DCONTENT_LENGTH="$CONTENT_LENGTH" \
    -	-DCONTENT_TYPE="$CONTENT_TYPE" \
    -	-DGATEWAY_INTERFACE="$GATEWAY_INTERFACE" \
    -	-DHTTP_ACCEPT="$HTTP_ACCEPT" \
    -	-DPATH_INFO="$PATH_INFO" \
    -	-DPATH_TRANSLATED="$PATH_TRANSLATED" \
    -	-DQUERY_STRING="$QUERY_STRING" \
    -	-DREMOTE_ADDR="$REMOTE_ADDR" \
    -	-DREMOTE_HOST="$REMOTE_HOST" \
    -	-DREMOTE_IDENT="$REMOTE_IDENT" \
    -	-DREMOTE_USER="$REMOTE_USER" \
    -	-DREQUEST_METHOD="$REQUEST_METHOD" \
    -	-DSCRIPT_NAME="$SCRIPT_NAME" \
    -	-DSERVER_NAME="$SERVER_NAME" \
    -	-DSERVER_PORT="$SERVER_PORT" \
    -	-DSERVER_PROTOCOL="$SERVER_PROTOCOL" \
    -	-DSERVER_SOFTWARE="$SERVER_SOFTWARE" \
    -	sun.rmi.transport.proxy.CGIHandler
    diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.sql/share/classes/java/sql/Connection.java
    --- a/jdk/src/java.sql/share/classes/java/sql/Connection.java	Wed Jul 05 20:58:49 2017 +0200
    +++ b/jdk/src/java.sql/share/classes/java/sql/Connection.java	Wed Jul 05 20:58:59 2017 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1996, 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
    @@ -1482,4 +1482,109 @@
          * @since 1.7
          */
         int getNetworkTimeout() throws SQLException;
    +
    +    // JDBC 4.3
    +
    +     /**
    +     * Hints to the driver that a request, an independent unit of work, is beginning
    +     * on this connection. Each request is independent of all other requests
    +     * with regard to state local to the connection either on the client or the
    +     * server. Work done between {@code beginRequest}, {@code endRequest}
    +     * pairs does not depend on any other work done on the connection either as
    +     * part of another request or outside of any request. A request may include multiple
    +     * transactions. There may be dependencies on committed database state as
    +     * that is not local to the connection.
    +     * 

    + * Local state is defined as any state associated with a Connection that is + * local to the current Connection either in the client or the database that + * is not transparently reproducible. + *

    + * Calls to {@code beginRequest} and {@code endRequest} are not nested. + * Multiple calls to {@code beginRequest} without an intervening call + * to {@code endRequest} is not an error. The first {@code beginRequest} call + * marks the start of the request and subsequent calls are treated as + * a no-op + *

    + * Use of {@code beginRequest} and {@code endRequest} is optional, vendor + * specific and should largely be transparent. In particular + * implementations may detect conditions that indicate dependence on + * other work such as an open transaction. It is recommended though not + * required that implementations throw a {@code SQLException} if there is an active + * transaction and {@code beginRequest} is called. + * Using these methods may improve performance or provide other benefits. + * Consult your vendors documentation for additional information. + *

    + * It is recommended to + * enclose each unit of work in {@code beginRequest}, {@code endRequest} + * pairs such that there is no open transaction at the beginning or end of + * the request and no dependency on local state that crosses request + * boundaries. Committed database state is not local. + * + * @implSpec + * The default implementation is a no-op. + *

    + * @apiNote + * This method is to be used by Connection pooling managers. + *

    + * The pooling manager should call {@code beginRequest} on the underlying connection + * prior to returning a connection to the caller. + *

    + * The pooling manager does not need to call {@code beginRequest} if: + *

      + *
    • The connection pool caches {@code PooledConnection} objects
    • + *
    • Returns a logical connection handle when {@code getConnection} is + * called by the application
    • + *
    • The pool manager calls {@code Connection.close} on the logical connection handle + * prior to returning the {@code PooledConnection} back to the cache
    • + *
    + * @throws SQLException if an error occurs + * @since 1.9 + * @see endRequest + * @see javax.sql.PooledConnection + */ + default void beginRequest() throws SQLException { + // Default method takes no action + } + + /** + * Hints to the driver that a request, an independent unit of work, + * has completed. Calls to {@code beginRequest} + * and {@code endRequest} are not nested. Multiple + * calls to {@code endRequest} without an intervening call to {@code beginRequest} + * is not an error. The first {@code endRequest} call + * marks the request completed and subsequent calls are treated as + * a no-op. If {@code endRequest} is called without an initial call to + * {@code beginRequest} is a no-op. + *

    + * The exact behavior of this method is vendor specific. In particular + * implementations may detect conditions that indicate dependence on + * other work such as an open transaction. It is recommended though not + * required that implementations throw a {@code SQLException} if there is an active + * transaction and {@code endRequest} is called. + * + * @implSpec + * The default implementation is a no-op. + * @apiNote + * + * This method is to be used by Connection pooling managers. + *

    + * The pooling manager should call {@code endRequest} on the underlying connection + * when the applications returns the connection back to the connection pool. + *

    + * The pooling manager does not need to call {@code endRequest} if: + *

      + *
    • The connection pool caches {@code PooledConnection} objects
    • + *
    • Returns a logical connection handle when {@code getConnection} is + * called by the application
    • + *
    • The pool manager calls {@code Connection.close} on the logical connection handle + * prior to returning the {@code PooledConnection} back to the cache
    • + *
    + * @throws SQLException if an error occurs + * @since 1.9 + * @see beginRequest + * @see javax.sql.PooledConnection + */ + default void endRequest() throws SQLException { + // Default method takes no action + } } diff -r 77273343c131 -r d8b2864e0ec4 jdk/src/java.sql/share/classes/javax/sql/PooledConnection.java --- a/jdk/src/java.sql/share/classes/javax/sql/PooledConnection.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/src/java.sql/share/classes/javax/sql/PooledConnection.java Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -66,7 +66,16 @@ * PooledConnection object to the pool of connections so that * it can be used again. Thus, when an application closes its connection, * the underlying physical connection is recycled rather than being closed. - *

    + *

    + * If the connection pool manager wraps or provides a proxy to the logical + * handle returned from a call to {@code PoolConnection.getConnection}, the pool + * manager must do + * one of the following when the application calls {@code Connection.close}: + *

      + *
    • call {@code endRequest} on the logical {@code Connection} handle + *
    • call {@code close} on the logical {@code Connection} handle + *
    + *

    * The physical connection is not closed until the connection pool manager * calls the PooledConnection method close. * This method is generally called to have an orderly shutdown of the server or diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/TEST.groups --- a/jdk/test/TEST.groups Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/TEST.groups Wed Jul 05 20:58:59 2017 +0200 @@ -27,6 +27,7 @@ tier1 = \ :jdk_lang \ + -java/lang/ProcessHandle/TreeTest.java \ :jdk_util \ sun/nio/cs/ISO8859x.java \ java/nio/Buffer \ @@ -34,6 +35,7 @@ :jdk_math tier2 = \ + java/lang/ProcessHandle/TreeTest.java \ :jdk_io \ :jdk_nio \ -sun/nio/cs/ISO8859x.java \ diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/awt/Component/CreateImage/CreateImage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/Component/CreateImage/CreateImage.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GraphicsEnvironment; + +import javax.swing.JButton; + +/** + * @test + * @bug 6815345 + * @run main CreateImage + * @run main/othervm -Djava.awt.headless=true CreateImage + */ +public final class CreateImage { + + public static void main(final String[] args) throws Exception { + EventQueue.invokeAndWait(CreateImage::test); + } + + private static void test() { + final JButton jbutton1 = new JButton(); + final JButton jbutton2 = new JButton(); + + if (GraphicsEnvironment.isHeadless()) { + checkCreateImage(jbutton1, true); + checkCreateImage(jbutton2, true); + return; + } + + final Frame frame = new Frame(); + final Button button1 = new Button(); + final Button button2 = new Button(); + try { + // all components are not displayable + checkCreateImage(frame, true); + checkCreateImage(button1, true); + checkCreateImage(button2, true); + checkCreateImage(jbutton1, true); + checkCreateImage(jbutton2, true); + + // some components added to the non-displayable frame + frame.add(button1); + frame.add(jbutton1); + checkCreateImage(button1, true); + checkCreateImage(jbutton1, true); + frame.pack(); + + // tests previously added components when the frame is displayable + checkCreateImage(frame, false); + checkCreateImage(button1, false); + checkCreateImage(jbutton1, false); + + // some components added to the displayable frame + frame.add(button2); + frame.add(jbutton2); + checkCreateImage(button2, false); + checkCreateImage(jbutton2, false); + + } finally { + frame.dispose(); + } + // tests all components after the frame became non-displayable again + checkCreateImage(frame, true); + checkCreateImage(button1, true); + checkCreateImage(button2, true); + checkCreateImage(jbutton1, true); + checkCreateImage(jbutton2, true); + } + + private static void checkCreateImage(final Component comp, + final boolean isNull) { + if ((comp.createImage(10, 10) != null) == isNull) { + throw new RuntimeException("Image is wrong"); + } + if ((comp.createVolatileImage(10, 10) != null) == isNull) { + throw new RuntimeException("Image is wrong"); + } + try { + if ((comp.createVolatileImage(10, 10, null) != null) == isNull) { + throw new RuntimeException("Image is wrong"); + } + } catch (final AWTException ignored) { + // this check is not applicable + } + } +} diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/awt/Component/TreeLockDeadlock/TreeLockDeadlock.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/Component/TreeLockDeadlock/TreeLockDeadlock.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.GraphicsConfiguration; +import java.awt.Window; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +/** + * @test + * @bug 8138764 + */ +public final class TreeLockDeadlock extends Frame { + + @Override + public synchronized GraphicsConfiguration getGraphicsConfiguration() { + return super.getGraphicsConfiguration(); + } + + @Override + public synchronized void reshape(int x, int y, int width, int height) { + super.reshape(x, y, width, height); + } + + @Override + public synchronized float getOpacity() { + return super.getOpacity(); + } + + public static void main(final String[] args) throws Exception { + final Window window = new TreeLockDeadlock(); + window.setSize(300, 300); + test(window); + } + + private static void test(final Window window) throws Exception { + final long start = System.nanoTime(); + final long end = start + NANOSECONDS.convert(1, MINUTES); + + final Runnable r1 = () -> { + while (System.nanoTime() < end) { + window.setBounds(window.getBounds()); + } + }; + final Runnable r2 = () -> { + while (System.nanoTime() < end) { + window.getGraphicsConfiguration(); + window.getOpacity(); + } + }; + + final Thread t1 = new Thread(r1); + final Thread t2 = new Thread(r1); + final Thread t3 = new Thread(r2); + final Thread t4 = new Thread(r2); + + t1.start(); + t2.start(); + t3.start(); + t4.start(); + t1.join(); + t2.join(); + t3.join(); + t4.join(); + } +} diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/awt/EmbeddedFrame/GraphicsConfigTest/GraphicsConfigTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/EmbeddedFrame/GraphicsConfigTest/GraphicsConfigTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6356322 + * @summary Tests that embedded frame's graphics configuration is updated + * correctly when it is moved to another screen in multiscreen system, + * XToolkit + * @author artem.ananiev@sun.com: area=awt.multiscreen + * @requires (os.family == "linux") | (os.family == "solaris") + * @modules java.desktop/sun.awt + * java.desktop/sun.awt.X11 + * java.desktop/java.awt.peer + * @run main GraphicsConfigTest + */ + +import java.awt.*; +import java.awt.peer.*; +import java.lang.reflect.*; +import java.util.*; +import sun.awt.*; + +public class GraphicsConfigTest { + + private static void init() + throws InterruptedException, AWTException { + if (!isXToolkit()) { + System.err.println("The test should be run only on XToolkit"); + return; + } + + GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gds = ge.getScreenDevices(); + if (gds.length < 2) { + System.err.println("The test should be run only in" + + " multiscreen configuration"); + return; + } + + boolean xinerama = Arrays.stream(gds) + .map((gd) -> gd.getDefaultConfiguration().getBounds()) + .filter((r) -> r.x != 0 || r.y != 0).findFirst().isPresent(); + + if (!xinerama) { + System.err.println("The test should be run only with Xinerama ON"); + return; + } + + Rectangle r0 = gds[0].getDefaultConfiguration().getBounds(); + Rectangle r1 = gds[1].getDefaultConfiguration().getBounds(); + + System.setProperty("sun.awt.xembedserver", "true"); + Frame f = new Frame("F"); + try { + final Robot robot = new Robot(); + + f.setBounds(r0.x + 100, r0.y + 100, 200, 200); + f.setVisible(true); + robot.waitForIdle(); + Thread.sleep(1000); + + Canvas c = new Canvas(); + f.add(c); + AWTAccessor.ComponentAccessor acc = + AWTAccessor.getComponentAccessor(); + WindowIDProvider wip = acc.getPeer(c); + long h = wip.getWindow(); + + EmbeddedFrame e = createEmbeddedFrame(h); + acc.getPeer(e).setBoundsPrivate(0, 0, 100, + 100); // triggers XConfigureEvent + e.registerListeners(); + e.setVisible(true); + robot.waitForIdle(); + Thread.sleep(1000); + + if (!checkGC(f, e)) { + throw new RuntimeException("Failed at checkpoint 1"); + } + + f.setLocation(r1.x + 100, r1.y + 100); + Thread.sleep(100); + acc.getPeer(e).setBoundsPrivate(0, 0, 101, + 101); // triggers XConfigureEvent + robot.waitForIdle(); + Thread.sleep(1000); + + if (!checkGC(f, e)) { + throw new RuntimeException("Failed at checkpoint 2"); + } + + f.setLocation(r0.x + 100, r0.y + 100); + Thread.sleep(100); + acc.getPeer(e).setBoundsPrivate(0, 0, 102, + 102); // triggers XConfigureEvent + robot.waitForIdle(); + Thread.sleep(1000); + + if (!checkGC(f, e)) { + throw new RuntimeException("Failed at checkpoint 3"); + } + + } finally { + f.dispose(); + } + } + + private static boolean isXToolkit() { + return Toolkit.getDefaultToolkit().getClass() + .getName().equals("sun.awt.X11.XToolkit"); + } + + private static EmbeddedFrame createEmbeddedFrame(long window) { + try { + Class cl = Class.forName("sun.awt.X11.XEmbeddedFrame"); + Constructor cons = cl.getConstructor( + new Class[]{Long.TYPE, Boolean.TYPE}); + return (EmbeddedFrame) cons.newInstance(new Object[]{window, true}); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Can't create embedded frame"); + } + } + + private static boolean checkGC(Component c, Component d) { + GraphicsConfiguration g1 = c.getGraphicsConfiguration(); + System.err.println(g1); + GraphicsConfiguration g2 = d.getGraphicsConfiguration(); + System.err.println(g2); + + return g1.equals(g2); + } + + public static void main(String args[]) throws InterruptedException, AWTException { + init(); + } +} diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/awt/List/FocusEmptyListTest/FocusEmptyListTest.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/List/FocusEmptyListTest/FocusEmptyListTest.html Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,47 @@ + + + + + FocusEmptyListTest + + + +

    FocusEmptyListTest
    Bug ID: 6387275

    + +

    This is an AUTOMATIC test, simply wait for completion

    + + + + + diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/awt/List/FocusEmptyListTest/FocusEmptyListTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/List/FocusEmptyListTest/FocusEmptyListTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + test + @bug 6387275 + @summary List: the focus is at the top of the first item, XAWT + @author Dmitry.Cherepanov@SUN.COM area=awt.list + @run applet FocusEmptyListTest.html +*/ + +import java.applet.Applet; +import java.awt.*; +import java.lang.reflect.*; +import java.awt.peer.ListPeer; + +import sun.awt.AWTAccessor; + +public class FocusEmptyListTest extends Applet { + + public void init() { + setLayout(new BorderLayout()); + }//End init() + + public void start() { + boolean isXToolkit = Toolkit.getDefaultToolkit() + .getClass().getName().equals("sun.awt.X11.XToolkit"); + if (!isXToolkit) { + System.out.println("The test is XAWT-only."); + return; + } + + List list = new List(); + Object isIndexDisplayed = null; + setLayout(new FlowLayout()); + + getToolkit().addAWTEventListener(System.out::println, + AWTEvent.FOCUS_EVENT_MASK | AWTEvent.WINDOW_FOCUS_EVENT_MASK); + + add(list); + list.add("item1"); + + setSize(200, 200); + setVisible(true); + validate(); + + list.removeAll(); + + try { + + // peer = List.getPeer() + ListPeer peer = AWTAccessor.getComponentAccessor().getPeer(list); + System.out.println("peer = " + peer); + Class peerClass = peer.getClass(); + System.out.println("peer's class = " + peerClass); + + // isIndexDisplayed = peer.isIndexDisplayed(-1) + Method isIndexDisplayedM + = peerClass.getDeclaredMethod("isIndexDisplayed", Integer.TYPE); + System.out.println("method = " + isIndexDisplayedM); + isIndexDisplayedM.setAccessible(true); + isIndexDisplayed = isIndexDisplayedM.invoke(peer, -1); + System.out.println("isIndexDisplayed=" + isIndexDisplayed); + + } catch (Throwable thr) { + throw new RuntimeException("TEST FAILED: " + thr); + } + + if ((Boolean) isIndexDisplayed) { + throw new RuntimeException("TEST FAILED: -1 should be" + + " invisible index"); + } + + }// start() + +}// class AutomaticAppletTest diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/awt/Window/MultiWindowApp/MultiWindowAppTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/Window/MultiWindowApp/MultiWindowAppTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test @summary After calling frame.toBack() dialog goes to the back on Ubuntu 12.04 + * @bug 8022334 + * @author Semyon Sadetsky + * @run main MultiWindowAppTest + */ + +import java.awt.*; + +public class MultiWindowAppTest { + + public static void main(String[] args) throws Exception { + Window win1 = new Frame(); + Window win2 = new Dialog((Frame) null); + + win1.setBounds(100, 100, 200, 200); + win1.setBackground(Color.RED); + win1.setVisible(true); + + Robot robot = new Robot(); + robot.delay(200); + robot.waitForIdle(); + + win2.setBounds(win1.getBounds()); + win2.setVisible(true); + + robot.delay(200); + robot.waitForIdle(); + + win1.toFront(); + robot.delay(200); + robot.waitForIdle(); + + Point point = win1.getLocationOnScreen(); + Color color = robot.getPixelColor(point.x + 100, point.y + 100); + + if(!color.equals(Color.RED)) { + win1.dispose(); + win2.dispose(); + throw new RuntimeException("Window was not sent to front."); + } + + win1.toBack(); + robot.delay(200); + robot.waitForIdle(); + + color = robot.getPixelColor(point.x + 100, point.y + 100); + + win1.dispose(); + win2.dispose(); + + if(color.equals(Color.RED)) { + throw new RuntimeException("Window was not sent to back."); + } + + System.out.println("ok"); + } +} diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/awt/Window/ScreenLocation/ScreenLocationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/Window/ScreenLocation/ScreenLocationTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 8011616 + @summary JWindow.getLocation and JWindow.getLocationOnScreen return different + values on Unity + @author Semyon Sadetsky + */ + +import java.awt.*; + +public class ScreenLocationTest { + + + public static void main(String[] args) throws Exception { + testLocation(); + testSize(); + System.out.println("ok"); + } + + public static void testLocation() throws Exception { + Window window = new Window((Frame) null); + window.setSize(100, 100); + window.setLocation(0, 0); + window.setVisible(true); + + Robot robot = new Robot(); + robot.delay(200); + robot.waitForIdle(); + + Point location1 = window.getLocation(); + Point location2 = window.getLocationOnScreen(); + window.setLocation(10000, 10000); + + if (!location1.equals(location2)) { + window.dispose(); + throw new RuntimeException("getLocation is different"); + } + + robot.delay(200); + robot.waitForIdle(); + location1 = window.getLocation(); + location2 = window.getLocationOnScreen(); + + if (!location1.equals(location2)) { + window.dispose(); + throw new RuntimeException("getLocation is different"); + } + + window.dispose(); + } + + public static void testSize() throws Exception { + Window window = new Window((Frame) null); + window.setSize(Integer.MAX_VALUE, Integer.MAX_VALUE); + window.setVisible(true); + + Robot robot = new Robot(); + robot.delay(200); + robot.waitForIdle(); + + Dimension size = window.getSize(); + if (size.width == Integer.MAX_VALUE || + size.height == Integer.MAX_VALUE) { + window.dispose(); + throw new RuntimeException("size is wrong"); + } + + window.dispose(); + } +} diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/awt/datatransfer/DataFlavor/MacOsXFileAndMultipleFileCopingTest/MacOsXFileAndMultipleFileCopingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/datatransfer/DataFlavor/MacOsXFileAndMultipleFileCopingTest/MacOsXFileAndMultipleFileCopingTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 8081787 8136763 + @author Mikhail Cherkasov + @run main/manual MacOsXFileAndMultipleFileCopingTest +*/ + +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.net.URL; + +public class MacOsXFileAndMultipleFileCopingTest { + private static void init() { + String[] instructions = + {"Test for MacOS X only:", + "1. The aim is to test that java works fine with \"application/" + + "x-java-url;class=java.net.URL\"falvor and support coping of multiple files", + "2. Open finder and select any file.", + "3. Press CMD+C or press \"Copy\" in context menu", + "4. Focus window with \"Test URL\" Button.", + "5. If you see URL for selected file, then test PASSED,", + "otherwise test FAILED.", + + "6. Open finder again and select several files.", + "7. Press CMD+C or press \"Copy\" in context menu", + "8. Focus window with \"Test multiple files coping\" Button.", + "9. If you see list of selected files, then test PASSED,", + "otherwise test FAILED.", + + }; + + Sysout.createDialog(); + Sysout.printInstructions(instructions); + + final Frame frame = new Frame(); + Panel panel = new Panel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); + + frame.add(panel); + Button testUrlBtn = new Button("Test URL"); + final TextArea textArea = new TextArea(5, 80); + testUrlBtn.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent ae) { + try { + Clipboard board = Toolkit.getDefaultToolkit().getSystemClipboard(); + URL url = (URL) board.getData(new DataFlavor("application/x-java-url;class=java.net.URL")); + textArea.setText(url.toString()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + panel.add(testUrlBtn); + Button testUriList = new Button("Test multiple files coping"); + testUriList.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent ae) { + try { + Clipboard board = Toolkit.getDefaultToolkit().getSystemClipboard(); + String files = (String) board.getData(new DataFlavor("text/uri-list;class=java.lang.String")); + textArea.setText(files); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + panel.add(testUriList); + panel.add(textArea); + frame.setBounds(200, 200, 400, 400); + frame.setVisible(true); + + }//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-defined + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main(String args[]) throws InterruptedException { + if (!System.getProperty("os.name").startsWith("Mac")) { + return; + } + mainThread = Thread.currentThread(); + try { + init(); + } catch (TestPassedException e) { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try { + Thread.sleep(sleepTime); + //Timed out, so fail the test + throw new RuntimeException("Timed out after " + sleepTime / 1000 + " seconds"); + } catch (InterruptedException e) { + if (!testGeneratedInterrupt) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if (theTestPassed == false) { + throw new RuntimeException(failureMessage); + } + } + + }//main + + public static synchronized void setTimeoutTo(int seconds) { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() { + Sysout.println("The test passed."); + Sysout.println("The test is over, hit Ctl-C to stop Java VM"); + //first check if this is executing in main thread + if (mainThread == Thread.currentThread()) { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + if (mainThread != null) { + 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 ManualMainTest + +//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 ********** + + +/**************************************************** + * 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; + private static boolean numbering = false; + private static int messageNumber = 0; + + 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."); + } + + + /* Enables message counting for the tester. */ + public static void enableNumbering(boolean enable) { + numbering = enable; + } + + public static void printInstructions(String[] instructions) { + dialog.printInstructions(instructions); + } + + + public static void println(String messageIn) { + if (numbering) { + messageIn = "" + messageNumber + " " + messageIn; + messageNumber++; + } + dialog.displayMessage(messageIn); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button("pass"); + Button failB = new Button("fail"); + + //DO NOT call this directly, go through Sysout + public TestDialog(Frame frame, String name) { + super(frame, name); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); + add("North", instructionsText); + + messageText = new TextArea("", 5, maxStringLength, scrollBoth); + add("Center", messageText); + + passB = new Button("pass"); + passB.setActionCommand("pass"); + passB.addActionListener(this); + buttonP.add("East", passB); + + failB = new Button("fail"); + failB.setActionCommand("fail"); + failB.addActionListener(this); + buttonP.add("West", failB); + + add("South", buttonP); + pack(); + + 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); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand() == "pass") { + MacOsXFileAndMultipleFileCopingTest.pass(); + } else { + MacOsXFileAndMultipleFileCopingTest.fail(); + } + } + +}// TestDialog class \ No newline at end of file diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/awt/datatransfer/DataFlavor/XJavaUrlDataFlavorTest/XJavaUrlDataFlavorTest.java --- a/jdk/test/java/awt/datatransfer/DataFlavor/XJavaUrlDataFlavorTest/XJavaUrlDataFlavorTest.java Wed Jul 05 20:58:49 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 8081787 - @summary MalformedURLException is thrown during reading data for application/x-java-url;class=java.net.URL flavor - @author Mikhail Cherkasov - @run main/manual XJavaUrlDataFlavorTest -*/ - -import javax.swing.*; -import java.awt.*; -import java.awt.datatransfer.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.net.URL; - -public class XJavaUrlDataFlavorTest { - private static void init() { - String[] instructions = - {"Test for MacOS X only:", - "1. The aim is to test that java works fine with \"application/" + - "x-java-url;class=java.net.URL\"falvor.", - "2. Open finder and select any file.", - "3. Press CMD+C or press \"Copy\" in context menu", - "4. Focus window with \"Test\" Button.", - "5. If you see URL for selected file, then test PASSED,", - "otherwise test FAILED." - }; - - Sysout.createDialog(); - Sysout.printInstructions(instructions); - - final Frame frame = new Frame(); - Panel panel = new Panel(); - panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); - - frame.add(panel); - Button testButton = new Button("Test"); - final TextField textField = new TextField(40); - testButton.addActionListener(new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ae) { - try { - Clipboard board = Toolkit.getDefaultToolkit().getSystemClipboard(); - URL url = (URL)board.getData(new DataFlavor("application/x-java-url;class=java.net.URL")); - textField.setText(url.toString()); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - panel.add(testButton); - panel.add(textField); - frame.setBounds(200, 200, 400, 400); - frame.setVisible(true); - - }//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-defined - * classes - ******************************************************/ - private static boolean theTestPassed = false; - private static boolean testGeneratedInterrupt = false; - private static String failureMessage = ""; - - private static Thread mainThread = null; - - private static int sleepTime = 300000; - - public static void main(String args[]) throws 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 passed nor test failed has been - // called -- either would have thrown an exception and ended the - // test, so we know we have multiple threads. - - //Test involves other threads, so sleep and wait for them to - // called pass() or fail() - try { - Thread.sleep(sleepTime); - //Timed out, so fail the test - throw new RuntimeException("Timed out after " + sleepTime / 1000 + " seconds"); - } catch (InterruptedException e) { - if (!testGeneratedInterrupt) throw e; - - //reset flag in case hit this code more than once for some reason (just safety) - testGeneratedInterrupt = false; - if (theTestPassed == false) { - throw new RuntimeException(failureMessage); - } - } - - }//main - - public static synchronized void setTimeoutTo(int seconds) { - sleepTime = seconds * 1000; - } - - public static synchronized void pass() { - Sysout.println("The test passed."); - Sysout.println("The test is over, hit Ctl-C to stop Java VM"); - //first check if this is executing in main thread - if (mainThread == Thread.currentThread()) { - //Still in the main thread, so set the flag just for kicks, - // and throw a test passed exception which will be caught - // and end the test. - theTestPassed = true; - throw new TestPassedException(); - } - //pass was called from a different thread, so set the flag and interrupt - // the main thead. - theTestPassed = true; - testGeneratedInterrupt = true; - if (mainThread != null) { - 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 ManualMainTest - -//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 ********** - - -/**************************************************** - * 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; - private static boolean numbering = false; - private static int messageNumber = 0; - - 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."); - } - - - /* Enables message counting for the tester. */ - public static void enableNumbering(boolean enable) { - numbering = enable; - } - - public static void printInstructions(String[] instructions) { - dialog.printInstructions(instructions); - } - - - public static void println(String messageIn) { - if (numbering) { - messageIn = "" + messageNumber + " " + messageIn; - messageNumber++; - } - dialog.displayMessage(messageIn); - } - -}// Sysout class - -/** - This is part of the standard test machinery. It provides a place for the - test instructions to be displayed, and a place for interactive messages - to the user to be displayed. - To have the test instructions displayed, see Sysout. - To have a message to the user be displayed, see Sysout. - Do not call anything in this dialog directly. - */ -class TestDialog extends Dialog implements ActionListener { - - TextArea instructionsText; - TextArea messageText; - int maxStringLength = 80; - Panel buttonP = new Panel(); - Button passB = new Button("pass"); - Button failB = new Button("fail"); - - //DO NOT call this directly, go through Sysout - public TestDialog(Frame frame, String name) { - super(frame, name); - int scrollBoth = TextArea.SCROLLBARS_BOTH; - instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); - add("North", instructionsText); - - messageText = new TextArea("", 5, maxStringLength, scrollBoth); - add("Center", messageText); - - passB = new Button("pass"); - passB.setActionCommand("pass"); - passB.addActionListener(this); - buttonP.add("East", passB); - - failB = new Button("fail"); - failB.setActionCommand("fail"); - failB.addActionListener(this); - buttonP.add("West", failB); - - add("South", buttonP); - pack(); - - 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); - } - - //catch presses of the passed and failed buttons. - //simply call the standard pass() or fail() static methods of - //ManualMainTest - public void actionPerformed(ActionEvent e) { - if (e.getActionCommand() == "pass") { - XJavaUrlDataFlavorTest.pass(); - } else { - XJavaUrlDataFlavorTest.fail(); - } - } - -}// TestDialog class diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/awt/print/PrinterJob/PrintTextTest.java --- a/jdk/test/java/awt/print/PrinterJob/PrintTextTest.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/java/awt/print/PrinterJob/PrintTextTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -23,7 +23,7 @@ /** * @test - * @bug 6425068 7157659 + * @bug 6425068 7157659 8132890 * @summary Confirm that text prints where we expect to the length we expect. * @run main/manual=yesno PrintTextTest */ @@ -113,6 +113,32 @@ book.append(ptt, portrait); book.append(ptt, landscape); + font = new Font("Dialog", Font.PLAIN, 18); + AffineTransform scaleTx = AffineTransform.getScaleInstance(1.25, 1.25); + name = "Page " + new Integer(page++); + ptt = new PrintTextTest(name, font, scaleTx, false); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + + font = new Font("Dialog", Font.PLAIN, 18); + scaleTx = AffineTransform.getScaleInstance(-1.25, 1.25); + scaleTx.translate(-preferredSize/1.25, 0); + name = "Page " + new Integer(page++); + ptt = new PrintTextTest(name, font, scaleTx, false); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + + font = new Font("Dialog", Font.PLAIN, 18); + scaleTx = AffineTransform.getScaleInstance(1.25, -1.25); + scaleTx.translate(0, -preferredSize/1.25); + name = "Page " + new Integer(page++); + ptt = new PrintTextTest(name, font, scaleTx, false); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + font = font.deriveFont(rotTx); name = "Page " + new Integer(page++); ptt = new PrintTextTest(name, font, null, false); @@ -121,6 +147,30 @@ book.append(ptt, portrait); book.append(ptt, landscape); + font = new Font("Monospaced", Font.PLAIN, 12); + name = "Page " + new Integer(page++); + ptt = new PrintTextTest(name, font, null, false); + p.add(ptt, BorderLayout.CENTER); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + + Font xfont = font.deriveFont(AffineTransform.getScaleInstance(1.5, 1)); + name = "Page " + new Integer(page++); + ptt = new PrintTextTest(name, xfont, null, false); + p.add(ptt, BorderLayout.CENTER); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + + Font yfont = font.deriveFont(AffineTransform.getScaleInstance(1, 1.5)); + name = "Page " + new Integer(page++); + ptt = new PrintTextTest(name, yfont, null, false); + p.add(ptt, BorderLayout.CENTER); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + if (System.getProperty("os.name").startsWith("Windows")) { font = new Font("MS Gothic", Font.PLAIN, 12); name = "Page " + new Integer(page++); diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/lang/Class/IsEnum.java --- a/jdk/test/java/lang/Class/IsEnum.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/java/lang/Class/IsEnum.java Wed Jul 05 20:58:59 2017 +0200 @@ -32,8 +32,8 @@ public class IsEnum { - static int test(Class clazz, boolean expected) { - int status = (clazz.isEnum() == expected)?0:1; + static int test(Class clazz, boolean expected) { + int status = (clazz.isEnum() == expected) ? 0 : 1; if (status == 1) { System.err.println("Unexpected enum status for " + clazz); @@ -41,23 +41,23 @@ return status; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += test(IsEnum.class, false); failures += test(String.class, false); failures += test(Enum.class, false); + failures += test(EnumPoseur.class, false); failures += test(java.math.RoundingMode.class, true); - // Classes in java.lang.annoation + // Classes in java.lang.annotation failures += test(Annotation.class, false); failures += test(ElementType.class, true); failures += test(Retention.class, false); failures += test(RetentionPolicy.class, true); failures += test(Target.class, false); - failures += test(EnumPoseur.class, false); - // Classes for specialized enum constants aren't enum's + // A class for a specialized enum constant isn't itself an enum failures += test(SpecialEnum.class, true); failures += test(SpecialEnum.RED.getClass(), false); failures += test(SpecialEnum.GREEN.getClass(), true); diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/lang/ProcessHandle/TreeTest.java --- a/jdk/test/java/lang/ProcessHandle/TreeTest.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/java/lang/ProcessHandle/TreeTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -27,9 +27,11 @@ import java.time.Duration; import java.time.Instant; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -44,6 +46,7 @@ * @library /lib/testlibrary * Test counting and JavaChild.spawning and counting of Processes. * @run testng/othervm InfoTest + * @key intermittent * @author Roger Riggs */ public class TreeTest extends ProcessUtil { @@ -195,7 +198,7 @@ allChildren.stream().map(p -> p.getPid()) .collect(Collectors.toList())); - // Verify that all spawned children show up in the allChildrenList + // Verify that all spawned children show up in the allChildren List processes.forEach((p, parent) -> { Assert.assertEquals(p.isAlive(), true, "Child should be alive: " + p); Assert.assertTrue(allChildren.contains(p), "Spawned child should be listed in allChildren: " + p); @@ -241,6 +244,7 @@ printf(" p1: %s%n", p1.getPid()); int newChildren = 3; + CountDownLatch spawnCount = new CountDownLatch(newChildren); // Spawn children and have them wait p1.sendAction("spawn", newChildren, "stdin"); @@ -251,11 +255,26 @@ Long child = Long.valueOf(split[2]); Long parent = Long.valueOf(split[0].split(":")[0]); processes.put(ProcessHandle.of(child).get(), ProcessHandle.of(parent).get()); + spawnCount.countDown(); } }); - // Wait for the new processes and save the list - List allChildren = waitForAllChildren(p1Handle, newChildren); + // Wait for all the subprocesses to be listed as started + Assert.assertTrue(spawnCount.await(Utils.adjustTimeout(30L), TimeUnit.SECONDS), + "Timeout waiting for processes to start"); + + // Debugging; list allChildren that are not expected in processes + List allChildren = ProcessUtil.getAllChildren(p1Handle); + long count = allChildren.stream() + .filter(ph -> !processes.containsKey(ph)) + .count(); + if (count > 0) { + allChildren.stream() + .filter(ph -> !processes.containsKey(ph)) + .forEach(ph1 -> ProcessUtil.printProcess(ph1, "Extra process: ")); + ProcessUtil.logTaskList(); + Assert.assertEquals(0, count, "Extra processes in allChildren"); + } // Verify that all spawned children are alive, show up in the allChildren list // then destroy them @@ -266,6 +285,7 @@ }); Assert.assertEquals(processes.size(), newChildren, "Wrong number of children"); + // Wait for each of the processes to exit processes.forEach((p, parent) -> { for (long retries = Utils.adjustTimeout(100L); retries > 0 ; retries--) { if (!p.isAlive()) { @@ -285,8 +305,10 @@ p1.destroyForcibly(); p1.waitFor(); + // Verify that none of the spawned children are still listed by allChildren List remaining = getAllChildren(self); - remaining = remaining.stream().filter(processes::contains).collect(Collectors.toList()); + Assert.assertFalse(remaining.remove(p1Handle), "Child p1 should have exited"); + remaining = remaining.stream().filter(processes::containsKey).collect(Collectors.toList()); Assert.assertEquals(remaining.size(), 0, "Subprocess(es) should have exited: " + remaining); } catch (IOException ioe) { @@ -354,6 +376,8 @@ */ @Test public static void test5() { + ConcurrentHashMap processes = new ConcurrentHashMap<>(); + int factor = 2; JavaChild p1 = null; Instant start = Instant.now(); @@ -374,11 +398,39 @@ p1.sendAction("child", "child", "spawn", factor, "stdin"); int newChildren = factor * (1 + factor * (1 + factor)); - List children = ProcessUtil.waitForAllChildren(p1Handle, newChildren); + CountDownLatch spawnCount = new CountDownLatch(newChildren); + + // Gather the PIDs from the output of the spawning process + p1.forEachOutputLine((s) -> { + String[] split = s.trim().split(" "); + if (split.length == 3 && split[1].equals("spawn")) { + Long child = Long.valueOf(split[2]); + Long parent = Long.valueOf(split[0].split(":")[0]); + processes.put(ProcessHandle.of(child).get(), ProcessHandle.of(parent).get()); + spawnCount.countDown(); + } + }); + + // Wait for all the subprocesses to be listed as started + Assert.assertTrue(spawnCount.await(Utils.adjustTimeout(30L), TimeUnit.SECONDS), + "Timeout waiting for processes to start"); + + // Debugging; list allChildren that are not expected in processes + List allChildren = ProcessUtil.getAllChildren(p1Handle); + long count = allChildren.stream() + .filter(ph -> !processes.containsKey(ph)) + .count(); + if (count > 0) { + allChildren.stream() + .filter(ph -> !processes.containsKey(ph)) + .forEach(ph1 -> ProcessUtil.printProcess(ph1, "Extra process: ")); + ProcessUtil.logTaskList(); + Assert.assertEquals(0, count, "Extra processes in allChildren"); + } Assert.assertEquals(getChildren(p1Handle).size(), factor, "expected direct children"); - long count = getAllChildren(p1Handle).size(); + count = getAllChildren(p1Handle).size(); long totalChildren = factor * factor * factor + factor * factor + factor; Assert.assertTrue(count >= totalChildren, "expected at least " + totalChildren + ", actual: " + count); @@ -397,6 +449,12 @@ if (p1 != null) { p1.destroyForcibly(); } + processes.forEach((p, parent) -> { + if (p.isAlive()) { + ProcessUtil.printProcess(p, "Process Cleanup: "); + p.destroyForcibly(); + } + }); } } diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java --- a/jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -23,6 +23,7 @@ /* * @test LFSingleThreadCachingTest + * @ignore 8129523 * @bug 8046703 * @key randomness * @summary Test verifies that lambda forms are cached when run with single thread diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/util/Arrays/ArraysEqCmpTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/Arrays/ArraysEqCmpTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,1083 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8033148 + * @summary tests for array equals and compare + * @run testng ArraysEqCmpTest +*/ + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.BiFunction; +import java.util.function.LongFunction; +import java.util.stream.IntStream; + +public class ArraysEqCmpTest { + + // Maximum width in bits + static final int MAX_WIDTH = 512; + + static final Map typeToWidth; + + static { + typeToWidth = new HashMap<>(); + typeToWidth.put(boolean.class, Byte.SIZE); + typeToWidth.put(byte.class, Byte.SIZE); + typeToWidth.put(short.class, Short.SIZE); + typeToWidth.put(char.class, Character.SIZE); + typeToWidth.put(int.class, Integer.SIZE); + typeToWidth.put(long.class, Long.SIZE); + typeToWidth.put(float.class, Float.SIZE); + typeToWidth.put(double.class, Double.SIZE); + typeToWidth.put(Object.class, Integer.SIZE); // @@@ 32 or 64? + } + + static int arraySizeFor(Class type) { + type = type.isPrimitive() ? type : Object.class; + return 4 * MAX_WIDTH / typeToWidth.get(type); + } + + static abstract class ArrayType { + final Class arrayType; + final Class componentType; + final boolean unsigned; + + final MethodHandle cpy; + + final MethodHandle eq; + final MethodHandle eqr; + final MethodHandle cmp; + final MethodHandle cmpr; + final MethodHandle mm; + final MethodHandle mmr; + + final MethodHandle getter; + + final MethodHandle toString; + + public ArrayType(Class arrayType) { + this(arrayType, false); + } + + public ArrayType(Class arrayType, boolean unsigned) { + this.arrayType = arrayType; + this.componentType = arrayType.getComponentType(); + this.unsigned = unsigned; + + try { + MethodHandles.Lookup l = MethodHandles.lookup(); + + getter = MethodHandles.arrayElementGetter(arrayType); + + if (componentType.isPrimitive()) { + cpy = l.findStatic(Arrays.class, "copyOfRange", + MethodType.methodType(arrayType, arrayType, int.class, int.class)); + + MethodType eqt = MethodType.methodType( + boolean.class, arrayType, arrayType); + MethodType eqrt = MethodType.methodType( + boolean.class, arrayType, int.class, int.class, arrayType, int.class, int.class); + + eq = l.findStatic(Arrays.class, "equals", eqt); + eqr = l.findStatic(Arrays.class, "equals", eqrt); + + String compareName = unsigned ? "compareUnsigned" : "compare"; + cmp = l.findStatic(Arrays.class, compareName, + eqt.changeReturnType(int.class)); + cmpr = l.findStatic(Arrays.class, compareName, + eqrt.changeReturnType(int.class)); + + mm = l.findStatic(Arrays.class, "mismatch", + eqt.changeReturnType(int.class)); + mmr = l.findStatic(Arrays.class, "mismatch", + eqrt.changeReturnType(int.class)); + + toString = l.findStatic(Arrays.class, "toString", + MethodType.methodType(String.class, arrayType)); + } + else { + cpy = l.findStatic(Arrays.class, "copyOfRange", + MethodType.methodType(Object[].class, Object[].class, int.class, int.class)); + + MethodType eqt = MethodType.methodType( + boolean.class, Object[].class, Object[].class); + MethodType eqrt = MethodType.methodType( + boolean.class, Object[].class, int.class, int.class, Object[].class, int.class, int.class); + + eq = l.findStatic(Arrays.class, "equals", eqt); + eqr = l.findStatic(Arrays.class, "equals", eqrt); + + MethodType cmpt = MethodType.methodType( + int.class, Comparable[].class, Comparable[].class); + MethodType cmprt = MethodType.methodType( + int.class, Comparable[].class, int.class, int.class, Comparable[].class, int.class, int.class); + + cmp = l.findStatic(Arrays.class, "compare", cmpt); + cmpr = l.findStatic(Arrays.class, "compare", cmprt); + + mm = l.findStatic(Arrays.class, "mismatch", + eqt.changeReturnType(int.class)); + mmr = l.findStatic(Arrays.class, "mismatch", + eqrt.changeReturnType(int.class)); + + toString = l.findStatic(Arrays.class, "toString", + MethodType.methodType(String.class, Object[].class)); + } + + } + catch (Exception e) { + throw new Error(e); + } + } + + @Override + public String toString() { + String s = arrayType.getCanonicalName(); + return unsigned ? "unsigned " + s : s; + } + + Object construct(int length) { + return Array.newInstance(componentType, length); + } + + Object copyOf(Object a) { + return copyOf(a, 0, Array.getLength(a)); + } + + Object copyOf(Object a, int from, int to) { + try { + return (Object) cpy.invoke(a, from, to); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + Object get(Object a, int i) { + try { + return (Object) getter.invoke(a, i); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + abstract void set(Object a, int i, Object v); + + boolean equals(Object a, Object b) { + try { + return (boolean) eq.invoke(a, b); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + boolean equals(Object a, int aFromIndex, int aToIndex, + Object b, int bFromIndex, int bToIndex) { + try { + return (boolean) eqr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + int compare(Object a, Object b) { + try { + return (int) cmp.invoke(a, b); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + int compare(Object a, int aFromIndex, int aToIndex, + Object b, int bFromIndex, int bToIndex) { + try { + return (int) cmpr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + int mismatch(Object a, Object b) { + try { + return (int) mm.invoke(a, b); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + int mismatch(Object a, int aFromIndex, int aToIndex, + Object b, int bFromIndex, int bToIndex) { + try { + return (int) mmr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + String toString(Object a) { + try { + return (String) toString.invoke(a); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + static class BoxedIntegers extends ArrayType { + public BoxedIntegers() { + super(Integer[].class); + } + + @Override + void set(Object a, int i, Object v) { + // Ensure unique reference + ((Integer[]) a)[i] = v != null ? new Integer((Integer) v) : null; + } + } + + static class BoxedIntegersWithReverseComparator extends BoxedIntegers { + final Comparator c = (a, b) -> { + // Nulls sort after non-nulls + if (a == null || b == null) + return a == null ? b == null ? 0 : 1 : -1; + + return Integer.compare(b, a); + }; + + final MethodHandle cmpc; + final MethodHandle cmpcr; + final MethodHandle mismatchc; + final MethodHandle mismatchcr; + + public BoxedIntegersWithReverseComparator() { + try { + MethodHandles.Lookup l = MethodHandles.lookup(); + + MethodType cmpt = MethodType.methodType( + int.class, Object[].class, Object[].class, Comparator.class); + MethodType cmprt = MethodType.methodType( + int.class, Object[].class, int.class, int.class, + Object[].class, int.class, int.class, Comparator.class); + + cmpc = l.findStatic(Arrays.class, "compare", cmpt); + cmpcr = l.findStatic(Arrays.class, "compare", cmprt); + mismatchc = l.findStatic(Arrays.class, "mismatch", cmpt); + mismatchcr = l.findStatic(Arrays.class, "mismatch", cmprt); + } + catch (Exception e) { + throw new Error(e); + } + } + + @Override + int compare(Object a, Object b) { + try { + return (int) cmpc.invoke(a, b, c); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + @Override + int compare(Object a, int aFromIndex, int aToIndex, + Object b, int bFromIndex, int bToIndex) { + try { + return (int) cmpcr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex, c); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + @Override + int mismatch(Object a, Object b) { + try { + return (int) mismatchc.invoke(a, b, c); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + @Override + int mismatch(Object a, int aFromIndex, int aToIndex, + Object b, int bFromIndex, int bToIndex) { + try { + return (int) mismatchcr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex, c); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + + @Override + public String toString() { + return arrayType.getCanonicalName() + " with Comparator"; + } + } + + static class Booleans extends ArrayType { + public Booleans() { + super(boolean[].class); + } + + @Override + void set(Object a, int i, Object v) { + boolean pv; + if (v instanceof Boolean) { + pv = (Boolean) v; + } + else if (v instanceof Integer) { + pv = ((Integer) v) >= 0; + } + else throw new IllegalStateException(); + + ((boolean[]) a)[i] = pv; + } + } + + static class Bytes extends ArrayType { + public Bytes(boolean unsigned) { + super(byte[].class, unsigned); + } + + @Override + void set(Object a, int i, Object v) { + byte pv; + if (v instanceof Byte) { + pv = (Byte) v; + } + else if (v instanceof Integer) { + pv = ((Integer) v).byteValue(); + } + else throw new IllegalStateException(); + + ((byte[]) a)[i] = pv; + } + } + + static class Characters extends ArrayType { + public Characters() { + super(char[].class); + } + + @Override + void set(Object a, int i, Object v) { + char pv; + if (v instanceof Character) { + pv = (Character) v; + } + else if (v instanceof Integer) { + pv = (char) ((Integer) v).intValue(); + } + else throw new IllegalStateException(); + + ((char[]) a)[i] = pv; + } + } + + static class Shorts extends ArrayType { + public Shorts(boolean unsigned) { + super(short[].class, unsigned); + } + + @Override + void set(Object a, int i, Object v) { + short pv; + if (v instanceof Short) { + pv = (Short) v; + } + else if (v instanceof Integer) { + pv = ((Integer) v).shortValue(); + } + else throw new IllegalStateException(); + + ((short[]) a)[i] = pv; + } + } + + static class Integers extends ArrayType { + public Integers(boolean unsigned) { + super(int[].class, unsigned); + } + + @Override + void set(Object a, int i, Object v) { + int pv; + if (v instanceof Integer) { + pv = ((Integer) v).shortValue(); + } + else throw new IllegalStateException(); + + ((int[]) a)[i] = pv; + } + } + + static class Longs extends ArrayType { + public Longs(boolean unsigned) { + super(long[].class, unsigned); + } + + @Override + void set(Object a, int i, Object v) { + long pv; + if (v instanceof Long) { + pv = (Long) v; + } + else if (v instanceof Integer) { + pv = ((Integer) v).longValue(); + } + else throw new IllegalStateException(); + + ((long[]) a)[i] = pv; + } + } + + static class Floats extends ArrayType { + public Floats() { + super(float[].class); + } + + @Override + void set(Object a, int i, Object v) { + float pv; + if (v instanceof Float) { + pv = (Float) v; + } + else if (v instanceof Integer) { + pv = ((Integer) v).floatValue(); + } + else throw new IllegalStateException(); + + ((float[]) a)[i] = pv; + } + } + + static class Doubles extends ArrayType { + public Doubles() { + super(double[].class); + } + + @Override + void set(Object a, int i, Object v) { + double pv; + if (v instanceof Double) { + pv = (Double) v; + } + else if (v instanceof Integer) { + pv = ((Integer) v).doubleValue(); + } + else throw new IllegalStateException(); + + ((double[]) a)[i] = pv; + } + } + } + + static Object[][] arrayTypes; + + @DataProvider + public static Object[][] arrayTypesProvider() { + if (arrayTypes == null) { + arrayTypes = new Object[][]{ + new Object[]{new ArrayType.BoxedIntegers()}, + new Object[]{new ArrayType.BoxedIntegersWithReverseComparator()}, + new Object[]{new ArrayType.Booleans()}, + new Object[]{new ArrayType.Bytes(false)}, + new Object[]{new ArrayType.Bytes(true)}, + new Object[]{new ArrayType.Characters()}, + new Object[]{new ArrayType.Shorts(false)}, + new Object[]{new ArrayType.Shorts(true)}, + new Object[]{new ArrayType.Integers(false)}, + new Object[]{new ArrayType.Integers(true)}, + new Object[]{new ArrayType.Longs(false)}, + new Object[]{new ArrayType.Longs(true)}, + new Object[]{new ArrayType.Floats()}, + new Object[]{new ArrayType.Doubles()}, + }; + } + return arrayTypes; + } + + static Object[][] floatArrayTypes; + + @DataProvider + public static Object[][] floatArrayTypesProvider() { + if (floatArrayTypes == null) { + LongFunction bTof = rb -> Float.intBitsToFloat((int) rb); + LongFunction bToD = Double::longBitsToDouble; + + floatArrayTypes = new Object[][]{ + new Object[]{new ArrayType.Floats(), 0x7fc00000L, 0x7f800001L, bTof}, + new Object[]{new ArrayType.Doubles(), 0x7ff8000000000000L, 0x7ff0000000000001L, bToD}, + }; + } + return floatArrayTypes; + } + + static Object[][] objectArrayTypes; + + @DataProvider + public static Object[][] objectArrayTypesProvider() { + if (objectArrayTypes == null) { + LongFunction bTof = rb -> Float.intBitsToFloat((int) rb); + LongFunction bToD = Double::longBitsToDouble; + + objectArrayTypes = new Object[][]{ + new Object[]{new ArrayType.BoxedIntegers()}, + new Object[]{new ArrayType.BoxedIntegersWithReverseComparator()}, + }; + } + return objectArrayTypes; + } + + + static Object[][] signedUnsignedArrayTypes; + + @DataProvider + public static Object[][] signedUnsignedArrayTypes() { + if (signedUnsignedArrayTypes == null) { + signedUnsignedArrayTypes = new Object[][]{ + new Object[]{new ArrayType.Bytes(false), new ArrayType.Bytes(true)}, + new Object[]{new ArrayType.Shorts(false), new ArrayType.Shorts(true)}, + new Object[]{new ArrayType.Integers(false), new ArrayType.Integers(true)}, + new Object[]{new ArrayType.Longs(false), new ArrayType.Longs(true)}, + }; + } + return signedUnsignedArrayTypes; + } + + // Equality and comparison tests + + @Test(dataProvider = "arrayTypesProvider") + public void testArray(ArrayType arrayType) { + BiFunction, Integer, Object> constructor = (at, s) -> { + Object a = at.construct(s); + for (int x = 0; x < s; x++) { + at.set(a, x, x % 8); + } + return a; + }; + + BiFunction, Object, Object> cloner = (at, a) -> + constructor.apply(at, Array.getLength(a)); + + testArrayType(arrayType, constructor, cloner); + } + + @Test(dataProvider = "floatArrayTypesProvider") + public void testPrimitiveFloatArray( + ArrayType arrayType, + long canonicalNanRawBits, long nonCanonicalNanRawBits, + LongFunction bitsToFloat) { + Object canonicalNan = bitsToFloat.apply(canonicalNanRawBits); + // If conversion is a signalling NaN it may be subject to conversion to a + // quiet NaN on some processors, even if a copy is performed + // The tests assume that if conversion occurs it does not convert to the + // canonical NaN + Object nonCanonicalNan = bitsToFloat.apply(nonCanonicalNanRawBits); + + BiFunction, Integer, Object> canonicalNaNs = (at, s) -> { + Object a = at.construct(s); + for (int x = 0; x < s; x++) { + at.set(a, x, canonicalNan); + } + return a; + }; + + BiFunction, Object, Object> nonCanonicalNaNs = (at, a) -> { + int s = Array.getLength(a); + Object ac = at.construct(s); + for (int x = 0; x < s; x++) { + at.set(ac, x, nonCanonicalNan); + } + return ac; + }; + + BiFunction, Object, Object> halfNonCanonicalNaNs = (at, a) -> { + int s = Array.getLength(a); + Object ac = at.construct(s); + for (int x = 0; x < s / 2; x++) { + at.set(ac, x, nonCanonicalNan); + } + for (int x = s / 2; x < s; x++) { + at.set(ac, x, 1); + } + return ac; + }; + + testArrayType(arrayType, canonicalNaNs, nonCanonicalNaNs); + testArrayType(arrayType, canonicalNaNs, halfNonCanonicalNaNs); + } + + @Test(dataProvider = "objectArrayTypesProvider") + public void testNullElementsInObjectArray(ArrayType arrayType) { + BiFunction, Object, Object> cloner = ArrayType::copyOf; + + // All nulls + testArrayType(arrayType, + (at, s) -> { + Object a = at.construct(s); + for (int x = 0; x < s; x++) { + at.set(a, x, null); + } + return a; + }, + cloner); + + + // Some nulls + testArrayType(arrayType, + (at, s) -> { + Object a = at.construct(s); + for (int x = 0; x < s; x++) { + int v = x % 8; + at.set(a, x, v == 0 ? null : v); + } + return a; + }, + cloner); + + Integer[] a = new Integer[]{null, 0}; + Integer[] b = new Integer[]{0, 0}; + Assert.assertTrue(Arrays.compare(a, b) < 0); + Assert.assertTrue(Arrays.compare(b, a) > 0); + } + + @Test(dataProvider = "objectArrayTypesProvider") + public void testSameRefElementsInObjectArray(ArrayType arrayType) { + BiFunction, Object, Object> cloner = ArrayType::copyOf; + + // One ref + Integer one = 1; + testArrayType(arrayType, + (at, s) -> { + Integer[] a = (Integer[]) at.construct(s); + for (int x = 0; x < s; x++) { + a[x] = one; + } + return a; + }, + cloner); + + // All ref + testArrayType(arrayType, + (at, s) -> { + Integer[] a = (Integer[]) at.construct(s); + for (int x = 0; x < s; x++) { + a[x] = Integer.valueOf(s); + } + return a; + }, + cloner); + + // Some same ref + testArrayType(arrayType, + (at, s) -> { + Integer[] a = (Integer[]) at.construct(s); + for (int x = 0; x < s; x++) { + int v = x % 8; + a[x] = v == 1 ? one : new Integer(v); + } + return a; + }, + cloner); + } + + @Test(dataProvider = "signedUnsignedArrayTypes") + public void testSignedUnsignedArray(ArrayType sat, ArrayType uat) { + BiFunction, Integer, Object> constructor = (at, s) -> { + Object a = at.construct(s); + for (int x = 0; x < s; x++) { + at.set(a, x, 1); + } + return a; + }; + + int n = arraySizeFor(sat.componentType); + + for (int s : ranges(0, n)) { + Object a = constructor.apply(sat, s); + + for (int aFrom : ranges(0, s)) { + for (int aTo : ranges(aFrom, s)) { + int aLength = aTo - aFrom; + + if (aLength > 0) { + for (int i = aFrom; i < aTo; i++) { + Object ac = sat.copyOf(a); + // Create common prefix with a length of i - aFrom + sat.set(ac, i, -1); + + int sc = sat.compare(ac, aFrom, aTo, a, aFrom, aTo); + int uc = uat.compare(ac, aFrom, aTo, a, aFrom, aTo); + + Assert.assertTrue(sc < 0); + Assert.assertTrue(uc > 0); + } + } + } + } + } + } + + void testArrayType(ArrayType at, + BiFunction, Integer, Object> constructor, + BiFunction, Object, Object> cloner) { + int n = arraySizeFor(at.componentType); + + for (int s : ranges(0, n)) { + Object a = constructor.apply(at, s); + Object b = cloner.apply(at, a); + + for (int aFrom : ranges(0, s)) { + for (int aTo : ranges(aFrom, s)) { + int aLength = aTo - aFrom; + + for (int bFrom : ranges(0, s)) { + for (int bTo : ranges(bFrom, s)) { + int bLength = bTo - bFrom; + + Object anr = at.copyOf(a, aFrom, aTo); + Object bnr = at.copyOf(b, bFrom, bTo); + + boolean eq = isEqual(at, a, aFrom, aTo, b, bFrom, bTo); + Assert.assertEquals(at.equals(a, aFrom, aTo, b, bFrom, bTo), eq); + Assert.assertEquals(at.equals(b, bFrom, bTo, a, aFrom, aTo), eq); + Assert.assertEquals(at.equals(anr, bnr), eq); + Assert.assertEquals(at.equals(bnr, anr), eq); + if (eq) { + Assert.assertEquals(at.compare(a, aFrom, aTo, b, bFrom, bTo), 0); + Assert.assertEquals(at.compare(b, bFrom, bTo, a, aFrom, aTo), 0); + Assert.assertEquals(at.compare(anr, bnr), 0); + Assert.assertEquals(at.compare(bnr, anr), 0); + + Assert.assertEquals(at.mismatch(a, aFrom, aTo, b, bFrom, bTo), -1); + Assert.assertEquals(at.mismatch(b, bFrom, bTo, a, aFrom, aTo), -1); + Assert.assertEquals(at.mismatch(anr, bnr), -1); + Assert.assertEquals(at.mismatch(bnr, anr), -1); + } + else { + int aCb = at.compare(a, aFrom, aTo, b, bFrom, bTo); + int bCa = at.compare(b, bFrom, bTo, a, aFrom, aTo); + int v = Integer.signum(aCb) * Integer.signum(bCa); + Assert.assertTrue(v == -1); + + int anrCbnr = at.compare(anr, bnr); + int bnrCanr = at.compare(bnr, anr); + Assert.assertEquals(anrCbnr, aCb); + Assert.assertEquals(bnrCanr, bCa); + + + int aMb = at.mismatch(a, aFrom, aTo, b, bFrom, bTo); + int bMa = at.mismatch(b, bFrom, bTo, a, aFrom, aTo); + int anrMbnr = at.mismatch(anr, bnr); + int bnrManr = at.mismatch(bnr, anr); + + Assert.assertNotEquals(aMb, -1); + Assert.assertEquals(aMb, bMa); + Assert.assertNotEquals(anrMbnr, -1); + Assert.assertEquals(anrMbnr, bnrManr); + Assert.assertEquals(aMb, anrMbnr); + Assert.assertEquals(bMa, bnrManr); + + // Common or proper prefix + Assert.assertTrue(at.equals(a, aFrom, aFrom + aMb, b, bFrom, bFrom + aMb)); + if (aMb < Math.min(aLength, bLength)) { + // Common prefix + Assert.assertFalse(isEqual(at, a, aFrom + aMb, b, bFrom + aMb)); + } + } + } + } + + if (aLength > 0) { + for (int i = aFrom; i < aTo; i++) { + Object ac = at.copyOf(a); + // Create common prefix with a length of i - aFrom + at.set(ac, i, -1); + + Object acnr = at.copyOf(ac, aFrom, aTo); + Object anr = at.copyOf(a, aFrom, aTo); + + Assert.assertFalse(at.equals(ac, aFrom, aTo, a, aFrom, aTo)); + Assert.assertFalse(at.equals(acnr, anr)); + + int acCa = at.compare(ac, aFrom, aTo, a, aFrom, aTo); + int aCac = at.compare(a, aFrom, aTo, ac, aFrom, aTo); + int v = Integer.signum(acCa) * Integer.signum(aCac); + Assert.assertTrue(v == -1); + + int acnrCanr = at.compare(acnr, anr); + int anrCacnr = at.compare(anr, acnr); + Assert.assertEquals(acnrCanr, acCa); + Assert.assertEquals(anrCacnr, aCac); + + + int acMa = at.mismatch(ac, aFrom, aTo, a, aFrom, aTo); + int aMac = at.mismatch(a, aFrom, aTo, ac, aFrom, aTo); + Assert.assertEquals(acMa, aMac); + Assert.assertEquals(acMa, i - aFrom); + + int acnrManr = at.mismatch(acnr, anr); + int anrMacnr = at.mismatch(anr, acnr); + Assert.assertEquals(acnrManr, anrMacnr); + Assert.assertEquals(acnrManr, i - aFrom); + } + } + } + } + } + } + + static boolean isEqual(ArrayType at, Object a, int aFromIndex, int aToIndex, + Object b, int bFromIndex, int bToIndex) { + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; i++) { + Object av = at.get(a, aFromIndex++); + Object bv = at.get(b, bFromIndex++); + if (!Objects.equals(av, bv)) return false; + } + + return true; + } + + static boolean isEqual(ArrayType at, Object a, int aFrom, Object b, int bFrom) { + Object av = at.get(a, aFrom); + Object bv = at.get(b, bFrom); + + return Objects.equals(av, bv); + } + + static int[] ranges(int from, int to) { + int width = to - from; + switch (width) { + case 0: + return new int[]{}; + case 1: + return new int[]{from, to}; + case 2: + return new int[]{from, from + 1, to}; + case 3: + return new int[]{from, from + 1, from + 2, to}; + default: + return IntStream.of(from, from + 1, from + 2, to / 2 - 1, to / 2, to / 2 + 1, to - 2, to - 1, to) + .filter(i -> i >= from && i <= to) + .distinct().toArray(); + } + } + + + // Null array reference tests + + @Test(dataProvider = "arrayTypesProvider") + public void testNullArrayRefs(ArrayType arrayType) { + Object n = null; + Object a = arrayType.construct(0); + + Assert.assertTrue(arrayType.equals(n, n)); + Assert.assertFalse(arrayType.equals(n, a)); + Assert.assertFalse(arrayType.equals(a, n)); + + Assert.assertEquals(arrayType.compare(n, n), 0); + Assert.assertTrue(arrayType.compare(n, a) < 0); + Assert.assertTrue(arrayType.compare(a, n) > 0); + } + + + // Exception throwing tests + + @Test(dataProvider = "arrayTypesProvider") + public void testNPEs(ArrayType arrayType) { + Object[] values = new Object[]{null, arrayType.construct(0)}; + + for (Object o1 : values) { + for (Object o2 : values) { + if (o1 != null && o2 != null) + continue; + + testNPE(() -> arrayType.equals(o1, 0, 0, o2, 0, 0)); + testNPE(() -> arrayType.compare(o1, 0, 0, o2, 0, 0)); + testNPE(() -> arrayType.mismatch(o1, o2)); + testNPE(() -> arrayType.mismatch(o1, 0, 0, o2, 0, 0)); + } + } + } + + @Test + public void testObjectNPEs() { + String[][] values = new String[][]{null, new String[0]}; + Comparator c = String::compareTo; + Comparator[] cs = new Comparator[]{null, c}; + + for (String[] o1 : values) { + for (String[] o2 : values) { + for (Comparator o3 : cs) { + if (o1 != null && o2 != null && o3 != null) + continue; + + if (o3 == null) { + testNPE(() -> Arrays.compare(o1, o2, o3)); + testNPE(() -> Arrays.mismatch(o1, o2, o3)); + } + + testNPE(() -> Arrays.compare(o1, 0, 0, o2, 0, 0, o3)); + testNPE(() -> Arrays.mismatch(o1, 0, 0, o2, 0, 0, o3)); + } + } + } + } + + @Test(dataProvider = "arrayTypesProvider") + public void testIAEs(ArrayType arrayType) { + List values = Arrays.asList(0, 1); + + for (int s : values) { + Object a = arrayType.construct(s); + + for (int o1 : values) { + for (int o2 : values) { + if (o1 <= o2) continue; + + testIAE(() -> arrayType.equals(a, o1, 0, a, o2, 0)); + testIAE(() -> arrayType.compare(a, o1, 0, a, o2, 0)); + testIAE(() -> arrayType.mismatch(a, o1, 0, a, o2, 0)); + } + } + } + } + + @Test(dataProvider = "arrayTypesProvider") + public void testAIOBEs(ArrayType arrayType) { + List froms = Arrays.asList(-1, 0); + + for (int s : Arrays.asList(0, 1)) { + List tos = Arrays.asList(s, s + 1); + Object a = arrayType.construct(s); + + for (int aFrom : froms) { + for (int aTo : tos) { + for (int bFrom : froms) { + for (int bTo : tos) { + if (aFrom >= 0 && aTo <= s && + bFrom >= 0 && bTo <= s) continue; + + testAIOBE(() -> arrayType.equals(a, aFrom, aTo, a, bFrom, bTo)); + testAIOBE(() -> arrayType.compare(a, aFrom, aTo, a, bFrom, bTo)); + testAIOBE(() -> arrayType.mismatch(a, aFrom, aTo, a, bFrom, bTo)); + } + } + } + } + } + } + + static void testNPE(Runnable r) { + testThrowable(r, NullPointerException.class); + } + + static void testIAE(Runnable r) { + testThrowable(r, IllegalArgumentException.class); + } + + static void testAIOBE(Runnable r) { + testThrowable(r, ArrayIndexOutOfBoundsException.class); + } + + static void testThrowable(Runnable r, Class expected) { + Throwable caught = null; + try { + r.run(); + } + catch (Throwable t) { + caught = t; + } + Assert.assertNotNull(caught); + Assert.assertTrue(expected.isInstance(caught)); + } +} \ No newline at end of file diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/java/util/Locale/LocaleProviders.sh --- a/jdk/test/java/util/Locale/LocaleProviders.sh Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/java/util/Locale/LocaleProviders.sh Wed Jul 05 20:58:59 2017 +0200 @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 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 @@ -24,7 +24,7 @@ # # @test # @bug 6336885 7196799 7197573 7198834 8000245 8000615 8001440 8008577 -# 8010666 8013086 8013233 8013903 8015960 8028771 +# 8010666 8013086 8013233 8013903 8015960 8028771 8062006 # @summary tests for "java.locale.providers" system property # @compile -XDignore.symbol.file LocaleProviders.java # @run shell/timeout=600 LocaleProviders.sh @@ -182,7 +182,7 @@ if [ "${DEFLANG}" != "en" ] && [ "${DEFFMTLANG}" != "en" ]; then PARAM2=en PARAM3=US -elif [ "${DEFLANG}" != "ja" ] && [ "${DEFFMTLANG}" != "ja" ]; then +elif [ "${DEFLANG}" != "ja" ] && [ "${DEFFMTLANG}" != "ja" ]; then PARAM2=ja PARAM3=JP else @@ -200,6 +200,8 @@ PARAM3=US SPICLASSES= runTest +PREFLIST=SPI,COMPAT +runTest # testing the order, variaton #1. This assumes en_GB DateFormat data are available both in JRE & CLDR METHODNAME=adapterTest @@ -209,6 +211,8 @@ PARAM3=GB SPICLASSES= runTest +PREFLIST=CLDR,COMPAT +runTest # testing the order, variaton #2. This assumes en_GB DateFormat data are available both in JRE & CLDR METHODNAME=adapterTest @@ -218,6 +222,8 @@ PARAM3=GB SPICLASSES= runTest +PREFLIST=COMPAT,CLDR +runTest # testing the order, variaton #3 for non-existent locale in JRE assuming "haw" is not in JRE. METHODNAME=adapterTest @@ -227,6 +233,8 @@ PARAM3= SPICLASSES= runTest +PREFLIST=COMPAT,CLDR +runTest # testing the order, variaton #4 for the bug 7196799. CLDR's "zh" data should be used in "zh_CN" METHODNAME=adapterTest @@ -275,6 +283,8 @@ PARAM3= SPICLASSES=${SPIDIR} runTest +PREFLIST=COMPAT +runTest # testing 8000615 fix. METHODNAME=tzNameTest @@ -284,6 +294,8 @@ PARAM3= SPICLASSES=${SPIDIR} runTest +PREFLIST=COMPAT +runTest # testing 8001440 fix. METHODNAME=bug8001440Test @@ -314,6 +326,8 @@ PARAM3= SPICLASSES=${SPIDIR} runTest +PREFLIST=COMPAT,SPI +runTest # testing 8013903 fix. (Windows only) METHODNAME=bug8013903Test @@ -323,12 +337,9 @@ PARAM3= SPICLASSES= runTest -METHODNAME=bug8013903Test PREFLIST=HOST -PARAM1= -PARAM2= -PARAM3= -SPICLASSES= +runTest +PREFLIST=HOST,COMPAT runTest # testing 8027289 fix, if the platform format default is zh_CN @@ -342,12 +353,10 @@ PARAM3= SPICLASSES= runTest - METHODNAME=bug8027289Test + PREFLIST=COMPAT,HOST + runTest PREFLIST=HOST PARAM1=00A5 - PARAM2= - PARAM3= - SPICLASSES= runTest fi diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/imageio/plugins/bmp/BMPPixelSpacingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/plugins/bmp/BMPPixelSpacingTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 7182758 + * @summary Test verifies whether we are getting correct Horizontal + * & Vertical Physical pixel spacing for active BMP image + * through stored metadata or not. + * @run main BMPPixelSpacingTest + */ + +import java.io.ByteArrayInputStream; +import java.util.Iterator; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.stream.ImageInputStream; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class BMPPixelSpacingTest { + + public static void main(String[] args) throws Exception { + // Header contaning X & Y pixels-per-meter more than value 1 + byte[] bmpHeaderData = { (byte) 0x42, (byte) 0x4d, (byte) 0x7e, + (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x3e, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x28, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x64, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x64, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff }; + + ImageInputStream imageInput = ImageIO. + createImageInputStream(new ByteArrayInputStream(bmpHeaderData)); + + for (Iterator it = ImageIO.getImageReaders(imageInput); + it.hasNext(); ) { + ImageReader reader = it.next(); + reader.setInput(imageInput); + IIOMetadata metadata = reader.getImageMetadata(0); + + Node rootNode = metadata.getAsTree("javax_imageio_1.0"); + NodeList nl = rootNode.getChildNodes(); + + //Parse until you get Dimension child node + for (int i = 0; i < nl.getLength(); i++) { + Node node = nl.item(i); + if ((node.getNodeName()).equals("Dimension")) { + //get childnode list under Dimension node + NodeList cl = node.getChildNodes(); + //Corresponding node indices under Dimension node + int horizontalNodeIndex = 1; + int verticalNodeIndex = 2; + Node horizontalNode = cl.item(horizontalNodeIndex); + Node verticalNode = cl.item(verticalNodeIndex); + + //get attributes for horizontal and vertical nodes + NamedNodeMap horizontalAttr = horizontalNode. + getAttributes(); + NamedNodeMap verticalAttr = verticalNode.getAttributes(); + + //since they have only one attribute index is 0 + int attributeIndex = 0; + Node horizontalValue = horizontalAttr.item(attributeIndex); + Node verticalValue = verticalAttr.item(attributeIndex); + float horizontalNodeValue = Float. + parseFloat((horizontalValue.getNodeValue())); + float verticalNodeValue = Float. + parseFloat((verticalValue.getNodeValue())); + + float expectedHorizontalValue, expectedVerticalValue; + // in test metadata xPixelsPerMeter & yPixelsPerMeter is 2 + expectedHorizontalValue = expectedVerticalValue = + 1000.0F / 2; + //expected and returned values should be same + if ((Float.compare(horizontalNodeValue, + expectedHorizontalValue) != 0) || + (Float.compare(verticalNodeValue, + expectedVerticalValue) != 0)) { + throw new RuntimeException("Invalid pixel spacing"); + } + } + } + } + } +} diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/management/Introspector/AnnotationSecurityTest.java --- a/jdk/test/javax/management/Introspector/AnnotationSecurityTest.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/javax/management/Introspector/AnnotationSecurityTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -27,8 +27,7 @@ * @summary Test that having a security manager doesn't trigger a * NotCompliantMBeanException * @author Daniel Fuchs, Yves Joan - * @modules java.desktop - * java.management + * @modules java.management * @run clean AnnotationSecurityTest Described UnDescribed DescribedMBean * UnDescribedMBean SqeDescriptorKey DescribedMX DescribedMXBean * @run build AnnotationSecurityTest Described UnDescribed DescribedMBean @@ -40,13 +39,8 @@ import java.io.File; import java.io.IOException; -import java.lang.annotation.Annotation; import java.lang.management.ManagementFactory; -import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; -import java.lang.reflect.UndeclaredThrowableException; - -import javax.management.JMException; import javax.management.MBeanServer; import javax.management.ObjectName; /** diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/management/Introspector/Described.java --- a/jdk/test/javax/management/Introspector/Described.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/javax/management/Introspector/Described.java Wed Jul 05 20:58:59 2017 +0200 @@ -25,7 +25,7 @@ * * Used by AnnotationSecurityTest.java **/ -import java.beans.ConstructorProperties; +import javax.management.ConstructorParameters; /** * An MBean used by AnnotationSecurityTest.java @@ -37,7 +37,7 @@ public Described() {} @SqeDescriptorKey("ONE PARAMETER CONSTRUCTOR Described") - @ConstructorProperties({"name", "unused"}) + @ConstructorParameters({"name", "unused"}) public Described(@SqeDescriptorKey("CONSTRUCTOR PARAMETER name")String name, @SqeDescriptorKey("CONSTRUCTOR PARAMETER unused")String unused) { this.name = name ; diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/management/Introspector/DescribedMX.java --- a/jdk/test/javax/management/Introspector/DescribedMX.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/javax/management/Introspector/DescribedMX.java Wed Jul 05 20:58:59 2017 +0200 @@ -25,7 +25,7 @@ * * Used by AnnotationSecurityTest.java **/ -import java.beans.ConstructorProperties; +import javax.management.ConstructorParameters; /** * An MXBean used by AnnotationSecurityTest.java @@ -37,7 +37,7 @@ public DescribedMX() {} @SqeDescriptorKey("ONE PARAMETER CONSTRUCTOR DescribedMX") - @ConstructorProperties({"name", "unused"}) + @ConstructorParameters({"name", "unused"}) public DescribedMX(@SqeDescriptorKey("CONSTRUCTOR PARAMETER name")String name, @SqeDescriptorKey("CONSTRUCTOR PARAMETER unused")String unused) { this.name = name ; diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/management/Introspector/LegacyConstructorPropertiesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/management/Introspector/LegacyConstructorPropertiesTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -0,0 +1,106 @@ + +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.beans.ConstructorProperties; +import javax.management.ConstructorParameters; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.ObjectName; + +/* + * @test + * @bug 7199353 + * @summary Asserts that 'java.beans.ConstructorProperties' annotation is still + * recognized and properly handled for custom types mapped to open types. + * Also, makes sure that if the same constructor is annotated by both + * j.b.ConstructorProperties and j.m.ConstructorProperties annotations + * only j.m.ConstructorProperties annotation is considered. + * @author Jaroslav Bachorik + * @modules java.management + * java.desktop + * @run main LegacyConstructorPropertiesTest + */ + +public class LegacyConstructorPropertiesTest { + public static class CustomType { + private String name; + private int value; + @ConstructorProperties({"name", "value"}) + public CustomType(String name, int value) { + this.name = name; + this.value = value; + } + + // if @java.beans.ConstructorProperties would be used + // the introspector would choke on this + @ConstructorProperties("noname") + @ConstructorParameters("name") + public CustomType(String name) { + this.name = name; + this.value = -1; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + } + + public static interface CustomMXBean { + public CustomType getProp(); + public void setProp(CustomType prop); + } + + public static final class Custom implements CustomMXBean { + private CustomType prop; + + @Override + public CustomType getProp() { + return prop; + } + + @Override + public void setProp(CustomType prop) { + this.prop = prop; + } + } + + public static void main(String[] args) throws Exception { + MBeanServer mbs = MBeanServerFactory.createMBeanServer(); + CustomMXBean mbean = new Custom(); + + mbs.registerMBean(mbean, ObjectName.getInstance("test:type=Custom")); + } +} diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/management/mxbean/AmbiguousConstructorTest.java --- a/jdk/test/javax/management/mxbean/AmbiguousConstructorTest.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/javax/management/mxbean/AmbiguousConstructorTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -26,15 +26,13 @@ * @bug 6175517 6278707 * @summary Test that ambiguous ConstructorProperties annotations are detected. * @author Eamonn McManus - * @modules java.desktop - * java.management + * @modules java.management * @run clean AmbiguousConstructorTest * @run build AmbiguousConstructorTest * @run main AmbiguousConstructorTest */ -import java.beans.ConstructorProperties; -import java.io.InvalidObjectException; +import javax.management.ConstructorParameters; import javax.management.*; public class AmbiguousConstructorTest { @@ -76,13 +74,13 @@ public int getC() {return 0;} public long getD() {return 0;} - @ConstructorProperties({"a", "b"}) + @ConstructorParameters({"a", "b"}) public Unambiguous(byte a, short b) {} - @ConstructorProperties({"b", "c"}) + @ConstructorParameters({"b", "c"}) public Unambiguous(short b, int c) {} - @ConstructorProperties({"a", "b", "c"}) + @ConstructorParameters({"a", "b", "c"}) public Unambiguous(byte a, short b, int c) {} } @@ -92,13 +90,13 @@ public int getC() {return 0;} public long getD() {return 0;} - @ConstructorProperties({"a", "b"}) + @ConstructorParameters({"a", "b"}) public Ambiguous(byte a, short b) {} - @ConstructorProperties({"b", "c"}) + @ConstructorParameters({"b", "c"}) public Ambiguous(short b, int c) {} - @ConstructorProperties({"a", "b", "c", "d"}) + @ConstructorParameters({"a", "b", "c", "d"}) public Ambiguous(byte a, short b, int c, long d) {} } diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/management/mxbean/ExceptionDiagnosisTest.java --- a/jdk/test/javax/management/mxbean/ExceptionDiagnosisTest.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/javax/management/mxbean/ExceptionDiagnosisTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -26,11 +26,10 @@ * @bug 6713777 * @summary Test that exception messages include all relevant information * @author Eamonn McManus - * @modules java.desktop - * java.management + * @modules java.management */ -import java.beans.ConstructorProperties; +import javax.management.ConstructorParameters; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -131,7 +130,7 @@ } public static class CaseProb { - @ConstructorProperties({"urlPath"}) + @ConstructorParameters({"urlPath"}) public CaseProb(String urlPath) {} public String getURLPath() {return null;} diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/management/mxbean/LeakTest.java --- a/jdk/test/javax/management/mxbean/LeakTest.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/javax/management/mxbean/LeakTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -25,8 +25,7 @@ * @bug 6482247 * @summary Test that creating MXBeans does not introduce memory leaks. * @author Eamonn McManus - * @modules java.desktop - * java.management + * @modules java.management * @run build LeakTest RandomMXBeanTest MerlinMXBean TigerMXBean * @run main LeakTest */ diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/management/mxbean/MXBeanTest.java --- a/jdk/test/javax/management/mxbean/MXBeanTest.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/javax/management/mxbean/MXBeanTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -27,8 +27,7 @@ * @summary General MXBean test. * @author Eamonn McManus * @author Jaroslav Bachorik - * @modules java.desktop - * java.management + * @modules java.management * @run clean MXBeanTest MerlinMXBean TigerMXBean * @run build MXBeanTest MerlinMXBean TigerMXBean * @run main MXBeanTest diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/management/mxbean/PropertyNamesTest.java --- a/jdk/test/javax/management/mxbean/PropertyNamesTest.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/javax/management/mxbean/PropertyNamesTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -26,14 +26,13 @@ * @bug 6175517 * @summary Test the PropertyNames annotation with MXBeans * @author Eamonn McManus - * @modules java.desktop - * java.management + * @modules java.management * @run clean PropertyNamesTest * @run build PropertyNamesTest * @run main PropertyNamesTest */ -import java.beans.ConstructorProperties; +import javax.management.ConstructorParameters; import java.util.Collections; import java.util.List; import javax.management.JMX; @@ -95,7 +94,7 @@ } public static class Point { - @ConstructorProperties({"x", "y"}) + @ConstructorParameters({"x", "y"}) public Point(int x, int y) { this.x = x; this.y = y; @@ -123,17 +122,17 @@ } public static class Evolve { - @ConstructorProperties({"oldInt"}) + @ConstructorParameters({"oldInt"}) public Evolve(int oldInt) { this(oldInt, "defaultString"); } - @ConstructorProperties({"oldInt", "newString"}) + @ConstructorParameters({"oldInt", "newString"}) public Evolve(int oldInt, String newString) { this(oldInt, newString, Collections.emptyList()); } - @ConstructorProperties({"oldInt", "newString", "newerList"}) + @ConstructorParameters({"oldInt", "newString", "newerList"}) public Evolve(int oldInt, String newString, List newerList) { this.oldInt = oldInt; this.newString = newString; diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/javax/management/mxbean/TigerMXBean.java --- a/jdk/test/javax/management/mxbean/TigerMXBean.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/javax/management/mxbean/TigerMXBean.java Wed Jul 05 20:58:59 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -21,7 +21,7 @@ * questions. */ -import java.beans.ConstructorProperties; +import javax.management.ConstructorParameters; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -42,7 +42,7 @@ public interface TigerMXBean { class Point { - @ConstructorProperties({"x", "y"}) + @ConstructorParameters({"x", "y"}) public Point(double x, double y) { this.x = x; this.y = y; diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/jdk/internal/jimage/JImageReadTest.java --- a/jdk/test/jdk/internal/jimage/JImageReadTest.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/jdk/internal/jimage/JImageReadTest.java Wed Jul 05 20:58:59 2017 +0200 @@ -22,7 +22,9 @@ */ /* + * @test * @modules java.base/jdk.internal.jimage + * @run testng JImageReadTest * @summary Unit test for libjimage JIMAGE_Open/Read/Close */ @@ -57,8 +59,7 @@ {"java.base", "java/lang/String.class"}, {"java.base", "java/lang/Object.class"}, {"java.base", "sun/reflect/generics/tree/TypeArgument.class"}, - {"jdk.jdeps", "com/sun/tools/javap/StackMapWriter$StackMapBuilder.class"}, - {"jdk.hotspot.agent", "sa.properties"}, + {"java.base", "sun/net/www/content-types.properties"}, {"java.logging", "java/util/logging/Logger.class"}, {"java.base", "java/NOSUCHCLASS/yyy.class"}, // non-existent {"NOSUCHMODULE", "java/lang/Class.class"}, // non-existent @@ -165,8 +166,10 @@ int count = ImageNativeSubstrate.JIMAGE_Resources(jimageHandle, names); System.out.printf(" count: %d, a class: %s\n", count, names[0]); - Assert.assertTrue(max > 31000, - "missing entries, should be more than 31000, reported: " + count); + int minEntryCount = 16000; + Assert.assertTrue(max > minEntryCount, + "missing entries, should be more than " + minEntryCount + + ", reported: " + count); Assert.assertTrue(count == max, "unexpected count of entries, count: " + count + ", max: " + max); @@ -310,6 +313,7 @@ static boolean isMetaName(String name) { return name.startsWith("/modules") || name.startsWith("/packages") + || name.startsWith("META-INF/services") || name.equals("bootmodules.jdata"); } @@ -362,6 +366,24 @@ System.out.printf(" %s: %d names%n", fname, names.length); } + @Test + static void test5_nameTooLong() throws IOException { + long[] size = new long[1]; + String moduleName = "FictiousModuleName"; + String className = String.format("A%09999d", 1); + + long jimageHandle = ImageNativeSubstrate.JIMAGE_Open(imageFile); + Assert.assertTrue(jimageHandle != 0, "JIMAGE_Open failed: id: " + jimageHandle); + + long locationHandle = + ImageNativeSubstrate.JIMAGE_FindResource(jimageHandle, + moduleName, "9.0", className, size); + + Assert.assertEquals(0, locationHandle, "Too long name should have failed"); + + ImageNativeSubstrate.JIMAGE_Close(jimageHandle); + } + // main method to run standalone from jtreg @Test(enabled=false) diff -r 77273343c131 -r d8b2864e0ec4 jdk/test/sun/security/pkcs11/PKCS11Test.java --- a/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Jul 05 20:58:49 2017 +0200 +++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Jul 05 20:58:59 2017 +0200 @@ -539,6 +539,7 @@ osMap.put("Linux-amd64-64", new String[]{ "/usr/lib/x86_64-linux-gnu/", "/usr/lib/x86_64-linux-gnu/nss/", "/usr/lib64/"}); + osMap.put("Linux-ppc64-64", new String[]{"/usr/lib64/"}); osMap.put("Windows-x86-32", new String[]{ PKCS11_BASE + "/nss/lib/windows-i586/".replace('/', SEP)}); osMap.put("Windows-amd64-64", new String[]{