diff --git a/jdk/make/Makefile b/jdk/make/Makefile index 61dbf82719484941c8c8a83b2be77a5869bbd9ff..63e7803ffe344ab0b49a3c3563956c9e81ec00a0 100644 --- a/jdk/make/Makefile +++ b/jdk/make/Makefile @@ -75,7 +75,6 @@ import_product -- copy in the product components \n\ import_fastdebug -- copy in the fastdebug components \n\ import_debug -- copy in the debug components \n\ modules -- build the jdk and jre module images (experimental) \n\ -sccs_get -- make sure all SCCS files are up-to-date (need SCCS) \n\ create_links -- create softlinks in Solaris 32bit build to 64bit dirs \n\ " @@ -278,21 +277,6 @@ include $(BUILDDIR)/common/Sanity.gmk $(OUTPUTDIR) $(TEMPDIR): $(MKDIR) -p $@ -# cleanup everything. If the workspace is not being built by the control -# workspace, and if it is a Teamware workspace, then see if there are -# any files which are not under SCCS control. -clean clobber:: -ifndef EXTERNALSANITYCONTROL - @if [ -d $(TOPDIR)/Codemgr_wsdata ]; then \ - $(ECHO) '\nPerforming workspace scan for remnant files.\n' \ - ' Any files listed below are not under SCCS control in the workspace\n' \ - ' and you should review them and possibly remove them manually:' ; \ - $(FIND) $(TOPDIR)/make $(TOPDIR)/src -type f | \ - $(SED) 's+SCCS/[ps]\.++' | $(SORT) | $(UNIQ) -c | $(NAWK) '$$1<2 {print $$2;}' ; \ - $(ECHO) 'End of workspace scan.' ; \ - fi -endif - # this should be the last rule in this file: all:: @if [ -r $(WARNING_FILE) ]; then \ @@ -341,16 +325,70 @@ endif include $(BUILDDIR)/common/internal/BinaryPlugs.gmk # -# Get top level sccs_get rule +# Test rule # -include $(BUILDDIR)/common/Rules-SCCS.gmk +.NOTPARALLEL: test_run + +test: + $(MAKE) test_run + +test_run: test_clean test_start test_summary + +test_start: + @$(ECHO) "Tests started at `$(DATE)`" + +test_clean: + $(RM) $(OUTPUTDIR)/test_failures.txt $(OUTPUTDIR)/test_log.txt + +test_summary: $(OUTPUTDIR)/test_failures.txt + @$(ECHO) "#################################################" + @$(ECHO) "Tests completed at `$(DATE)`" + @( $(EGREP) '^TEST STATS:' $(OUTPUTDIR)/test_log.txt \ + || $(ECHO) "No TEST STATS seen in log" ) + @$(ECHO) "For complete details see: $(OUTPUTDIR)/test_log.txt" + @$(ECHO) "#################################################" + @if [ -s $< ] ; then \ + $(ECHO) "ERROR: Test failure count: `$(CAT) $< | $(WC) -l`"; \ + $(CAT) $<; \ + exit 1; \ + else \ + $(ECHO) "Success! No failures detected"; \ + fi + +# Get failure list from log +$(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt + @$(RM) $@ + @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@ + +# Get log file of all tests run +JDK_TO_TEST := $(shell \ + if [ -d "$(ABS_OUTPUTDIR)/j2sdk-image" ] ; then \ + $(ECHO) "$(ABS_OUTPUTDIR)/j2sdk-image"; \ + elif [ -d "$(ABS_OUTPUTDIR)/bin" ] ; then \ + $(ECHO) "$(ABS_OUTPUTDIR)"; \ + elif [ "$(PRODUCT_HOME)" != "" -a -d "$(PRODUCT_HOME)/bin" ] ; then \ + $(ECHO) "$(PRODUCT_HOME)"; \ + fi \ +) + +TEST_TARGETS=jdk_all +$(OUTPUTDIR)/test_log.txt: + $(RM) $@ + ( $(CD) ../test && \ + $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \ + ) | tee $@ + +# # JPRT rules +# + include jprt.gmk # # Phonies to avoid accidents. # .PHONY: all build clean clobber optimized debug fastdebug create_links \ - import import_product import_fastdebug import_debug + import import_product import_fastdebug import_debug \ + test test_run test_start test_clean test_summary diff --git a/jdk/make/common/Cscope.gmk b/jdk/make/common/Cscope.gmk index 7ec94fd12764731e32bef8fe9d6bb0b5304ebc85..79da2fc9e3027d79c36d6f44a7908b6a77bc6ea0 100644 --- a/jdk/make/common/Cscope.gmk +++ b/jdk/make/common/Cscope.gmk @@ -76,7 +76,7 @@ cscope.out: cscope.files FRC # What files should we include? A simple rule might be just those files under # SCM control, however this would miss files we create like the opcodes and # CClassHeaders. The following attempts to find everything that is *useful*. -# (.del files are created by sccsrm, demo directories contain many .java files +# (demo directories contain many .java files # that probably aren't useful for development, and the pkgarchive may contain # duplicates of files within the source hierarchy). The ordering of the .raw # file is an attempt to make cscope display the most relevant files first. diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk index 8d3e0fd32c89ba9a7624c864093ffa673ae3b9c4..31e3a4a8f65c03213ad3f51e9e1a7942aa2a1856 100644 --- a/jdk/make/common/Defs.gmk +++ b/jdk/make/common/Defs.gmk @@ -334,7 +334,7 @@ DOCSDIR = $(OUTPUTDIR)/docs$(DOCSDIRSUFFIX) DOCSDIRSUFFIX = # The MESSAGE, WARNING and ERROR files are used to store sanityck and -# SCCS check messages, warnings and errors. +# warnings and errors. ifndef ERROR_FILE ERROR_FILE = $(OUTPUTDIR)/sanityCheckErrors.txt endif @@ -634,38 +634,6 @@ LINTFLAGS = $(LINTFLAGS_$(VARIANT)) $(LINTFLAGS_COMMON) \ VERSION_DEFINES = -DRELEASE='"$(RELEASE)"' -# Note: As a rule, GNU Make rules should not appear in any of the -# Defs*.gmk files. These were added for Kestrel-Solaris and do address -# a TeamWare bug. They should be moved elsewhere for Merlin. -# -# Override gnumake built-in rules which do sccs get operations badly. -# (They put the checked out code in the current directory, not in the -# directory of the original file.) -# Since this is a symptom of a teamware failure, complain and die on the spot. - -# This message immediately goes to stdout and the build terminates. -define SCCS-trouble -$(error \ -"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \ - is out of date with respect to its SCCS file $<. \ - This can happen from an unresolved Teamware conflict, a file movement, or \ - a failure in which SCCS files are updated but the 'sccs get' was not done. \ - You should double check for other out of date files in your workspace. \ - Or run: cd $(TOPDIR) && $(MAKE) sccs_get") -endef - -%:: s.% - @$(SCCS-trouble) -%:: SCCS/s.% - @$(SCCS-trouble) - @$(ECHO) " is out of date with respect to its SCCS file." >> $(WARNING_FILE) - @$(ECHO) " This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE) - @$(ECHO) " This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE) - @$(ECHO) " in which SCCS files are updated but not checked out." >> $(WARNING_FILE) - @$(ECHO) " Check for other out of date files in your workspace." >> $(WARNING_FILE) - @$(ECHO) "" >> $(WARNING_FILE) - @#exit 666 - ifdef INSANE export INSANE endif diff --git a/jdk/make/common/Rules-SCCS.gmk b/jdk/make/common/Rules-SCCS.gmk deleted file mode 100644 index 7f75aca15b733574372b53ce29f8120fa53ca555..0000000000000000000000000000000000000000 --- a/jdk/make/common/Rules-SCCS.gmk +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute 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. -# - -# -# Only get these rules if SCCS is available -# - -ifdef SCCS - -# SCCS command to extract out latest source -SCCS_GET=$(SCCS) get -s - -# -# Make sure all files in workspace are fresh -# -TEMP_ALL_FILES=$(JDK_TOPDIR)/temp_filelist -$(TEMP_ALL_FILES): $(JDK_TOPDIR)/Codemgr_wsdata/nametable - $(prep-target) - @$(CUT) -d' ' -f1 $< \ - | $(GREP) -v '^VERSION' \ - | $(GREP) -v '^deleted_files' \ - | $(GREP) -v '^Codemgr_wsdata' > $@ - -sccs_get: $(TEMP_ALL_FILES) - @$(PRINTF) "Workspace has %d files\n" `$(CAT) $< | $(WC) -l` - @count=0; \ - for i in `$(CAT) $<` ; do \ - f=$(JDK_TOPDIR)/$$i; \ - count=`$(EXPR) $$count '+' 1`; \ - if [ `$(EXPR) $$count '%' 100` = 0 ] ; then \ - $(PRINTF) "\rChecked $$count files"; \ - fi; \ - if [ ! -f $$f ] ; then \ - $(PRINTF) "\r$(SCCS_GET) $$f\n"; \ - (cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \ - elif /usr/bin/test $$f -ot `$(DIRNAME) $$f`/SCCS/s.`$(BASENAME) $$f` ; then \ - $(PRINTF) "\r$(SCCS_GET) $$f\n"; \ - (cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \ - fi; \ - done; \ - $(PRINTF) "\rChecked $$count files\n" - -# -# Phonies to avoid accidents. -# -.PHONY: sccs_get - -endif diff --git a/jdk/make/common/shared/Defs-utils.gmk b/jdk/make/common/shared/Defs-utils.gmk index d7660c34878385694b75d105b0cae7b639df2fc0..10bad59bdf3b54195dd0fe8bbd971b6c77392693 100644 --- a/jdk/make/common/shared/Defs-utils.gmk +++ b/jdk/make/common/shared/Defs-utils.gmk @@ -33,7 +33,7 @@ # UTILS_COMMAND_PATH # /usr/bin/ # UTILS_USR_BIN_PATH -# /usr/ccs/bin/ (sccs, m4, lex, yacc, as, ar, strip, mcs) +# /usr/ccs/bin/ (m4, lex, yacc, as, ar, strip, mcs) # UTILS_CCS_BIN_PATH # Dev Tools: zip, unzip, etc that we may have special versions of # UTILS_DEVTOOL_PATH @@ -117,7 +117,6 @@ RC = $(UTILS_COMMAND_PATH)rc RMDIR = $(UTILS_COMMAND_PATH)rmdir RPM = $(UTILS_COMMAND_PATH)rpm RPMBUILD = $(UTILS_COMMAND_PATH)rpmbuild -SCCS = $(UTILS_CCS_BIN_PATH)sccs SED = $(UTILS_COMMAND_PATH)sed SH = $(UTILS_COMMAND_PATH)sh SHOWREV = $(UTILS_USR_BIN_PATH)showrev @@ -183,7 +182,7 @@ ifeq ($(PLATFORM),linux) NAWK = $(USRBIN_PATH)gawk # Intrinsic unix command, with backslash-escaped character interpretation ECHO = /bin/echo -e - # These are really in UTILS_USR_BIN_PATH on Linux (only sccs is not) + # These are really in UTILS_USR_BIN_PATH on Linux AR = $(UTILS_USR_BIN_PATH)ar AS = $(UTILS_USR_BIN_PATH)as LD = $(UTILS_USR_BIN_PATH)ld diff --git a/jdk/make/common/shared/Defs.gmk b/jdk/make/common/shared/Defs.gmk index ed32779c8c219c3f93ef1e49032fbab221f412e2..dbb0e666965c54f03116ee4eee2790888e02969c 100644 --- a/jdk/make/common/shared/Defs.gmk +++ b/jdk/make/common/shared/Defs.gmk @@ -219,7 +219,7 @@ else PRODUCT_NAME = Java(TM) PRODUCT_SUFFIX = SE Runtime Environment JDK_RC_PLATFORM_NAME = Platform SE - COMPANY_NAME = Oracle + COMPANY_NAME = Oracle Corporation endif RUNTIME_NAME = $(PRODUCT_NAME) $(PRODUCT_SUFFIX) diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk index d9af3c10fda1d8c0baba5a0297768a1eb1e07be5..fcb61e1beb6aebb94de43cf883b482531294d2d3 100644 --- a/jdk/make/java/java/FILES_java.gmk +++ b/jdk/make/java/java/FILES_java.gmk @@ -284,6 +284,7 @@ JAVA_JAVA_java = \ java/util/concurrent/CancellationException.java \ java/util/concurrent/CompletionService.java \ java/util/concurrent/ConcurrentHashMap.java \ + java/util/concurrent/ConcurrentLinkedDeque.java \ java/util/concurrent/ConcurrentLinkedQueue.java \ java/util/concurrent/ConcurrentMap.java \ java/util/concurrent/ConcurrentNavigableMap.java \ diff --git a/jdk/make/jprt.properties b/jdk/make/jprt.properties index 4ae844da4a286a38c9fb0fadc63c4b21b06e2a87..6c725c399308766aba5c89f3482e020d6c659296 100644 --- a/jdk/make/jprt.properties +++ b/jdk/make/jprt.properties @@ -25,43 +25,265 @@ # Properties for jprt -# Use whatever release that the submitted job requests +# At submit time, the release supplied will be in jprt.submit.release +# and will be one of the official release names defined in jprt. +# jprt supports property value expansion using ${property.name} syntax. + +# This tells jprt what default release we want to build jprt.tools.default.release=${jprt.submit.release} # The different build flavors we want, we override here so we just get these 2 jprt.build.flavors=product,fastdebug -# Standard test target for everybody -jprt.test.targets=*-*-*-jvm98 +# Define the Windows we want (temporary) +jprt.my.windows.i586.jdk7b107=windows_i586_5.0 +jprt.my.windows.i586.jdk7temp=windows_i586_5.0 +jprt.my.windows.i586.jdk7=windows_i586_5.1 +jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}} + +# Standard list of jprt build targets for this source tree +jprt.build.targets= \ + solaris_sparc_5.10-{product|fastdebug}, \ + solaris_sparcv9_5.10-{product|fastdebug}, \ + solaris_i586_5.10-{product|fastdebug}, \ + solaris_x64_5.10-{product|fastdebug}, \ + linux_i586_2.6-{product|fastdebug}, \ + linux_x64_2.6-{product|fastdebug}, \ + ${jprt.my.windows.i586}-{product|fastdebug}, \ + windows_x64_5.2-{product|fastdebug} + +# Standard vm test target +jprt.test.targets= \ + solaris_sparc_5.10-product-c1-jvm98, \ + solaris_sparcv9_5.10-product-c2-jvm98, \ + solaris_i586_5.10-product-c1-jvm98, \ + solaris_x64_5.10-product-c2-jvm98, \ + linux_i586_2.6-product-{c1|c2}-jvm98, \ + linux_x64_2.6-product-c2-jvm98, \ + ${jprt.my.windows.i586}-product-c1-jvm98, \ + windows_x64_5.2-product-c2-jvm98 + +# User can select the test set with jprt submit "-testset name" option +jprt.my.test.set=${jprt.test.set} + +# Default jdk test targets in test/Makefile (no fastdebug & limited c2) +jprt.make.rule.default.test.targets= \ + \ + solaris_sparc_5.10-product-c1-jdk_beans1, \ + solaris_sparcv9_5.10-product-c2-jdk_beans1, \ + solaris_i586_5.10-product-c1-jdk_beans1, \ + solaris_x64_5.10-product-c2-jdk_beans1, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans1, \ + linux_x64_2.6-product-c2-jdk_beans1, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans1, \ + windows_x64_5.2-product-c2-jdk_beans1, \ + \ + solaris_sparc_5.10-product-c1-jdk_io, \ + solaris_sparcv9_5.10-product-c2-jdk_io, \ + solaris_i586_5.10-product-c1-jdk_io, \ + solaris_x64_5.10-product-c2-jdk_io, \ + linux_i586_2.6-product-{c1|c2}-jdk_io, \ + linux_x64_2.6-product-c2-jdk_io, \ + ${jprt.my.windows.i586}-product-c1-jdk_io, \ + windows_x64_5.2-product-c2-jdk_io, \ + \ + solaris_sparc_5.10-product-c1-jdk_lang, \ + solaris_sparcv9_5.10-product-c2-jdk_lang, \ + solaris_i586_5.10-product-c1-jdk_lang, \ + solaris_x64_5.10-product-c2-jdk_lang, \ + linux_i586_2.6-product-{c1|c2}-jdk_lang, \ + linux_x64_2.6-product-c2-jdk_lang, \ + ${jprt.my.windows.i586}-product-c1-jdk_lang, \ + windows_x64_5.2-product-c2-jdk_lang, \ + \ + solaris_sparc_5.10-product-c1-jdk_math, \ + solaris_sparcv9_5.10-product-c2-jdk_math, \ + solaris_i586_5.10-product-c1-jdk_math, \ + solaris_x64_5.10-product-c2-jdk_math, \ + linux_i586_2.6-product-{c1|c2}-jdk_math, \ + linux_x64_2.6-product-c2-jdk_math, \ + ${jprt.my.windows.i586}-product-c1-jdk_math, \ + windows_x64_5.2-product-c2-jdk_math, \ + \ + solaris_sparc_5.10-product-c1-jdk_misc, \ + solaris_sparcv9_5.10-product-c2-jdk_misc, \ + solaris_i586_5.10-product-c1-jdk_misc, \ + solaris_x64_5.10-product-c2-jdk_misc, \ + linux_i586_2.6-product-{c1|c2}-jdk_misc, \ + linux_x64_2.6-product-c2-jdk_misc, \ + ${jprt.my.windows.i586}-product-c1-jdk_misc, \ + windows_x64_5.2-product-c2-jdk_misc, \ + \ + solaris_sparc_5.10-product-c1-jdk_net, \ + solaris_sparcv9_5.10-product-c2-jdk_net, \ + solaris_i586_5.10-product-c1-jdk_net, \ + solaris_x64_5.10-product-c2-jdk_net, \ + linux_i586_2.6-product-{c1|c2}-jdk_net, \ + linux_x64_2.6-product-c2-jdk_net, \ + ${jprt.my.windows.i586}-product-c1-jdk_net, \ + windows_x64_5.2-product-c2-jdk_net, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio1, \ + solaris_sparcv9_5.10-product-c2-jdk_nio1, \ + solaris_i586_5.10-product-c1-jdk_nio1, \ + solaris_x64_5.10-product-c2-jdk_nio1, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio1, \ + linux_x64_2.6-product-c2-jdk_nio1, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio1, \ + windows_x64_5.2-product-c2-jdk_nio1, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio2, \ + solaris_sparcv9_5.10-product-c2-jdk_nio2, \ + solaris_i586_5.10-product-c1-jdk_nio2, \ + solaris_x64_5.10-product-c2-jdk_nio2, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio2, \ + linux_x64_2.6-product-c2-jdk_nio2, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio2, \ + windows_x64_5.2-product-c2-jdk_nio2, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio3, \ + solaris_sparcv9_5.10-product-c2-jdk_nio3, \ + solaris_i586_5.10-product-c1-jdk_nio3, \ + solaris_x64_5.10-product-c2-jdk_nio3, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio3, \ + linux_x64_2.6-product-c2-jdk_nio3, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio3, \ + windows_x64_5.2-product-c2-jdk_nio3, \ + \ + solaris_sparc_5.10-product-c1-jdk_security1, \ + solaris_sparcv9_5.10-product-c2-jdk_security1, \ + solaris_i586_5.10-product-c1-jdk_security1, \ + solaris_x64_5.10-product-c2-jdk_security1, \ + linux_i586_2.6-product-{c1|c2}-jdk_security1, \ + linux_x64_2.6-product-c2-jdk_security1, \ + ${jprt.my.windows.i586}-product-c1-jdk_security1, \ + windows_x64_5.2-product-c2-jdk_security1, \ + \ + solaris_sparc_5.10-product-c1-jdk_text, \ + solaris_sparcv9_5.10-product-c2-jdk_text, \ + solaris_i586_5.10-product-c1-jdk_text, \ + solaris_x64_5.10-product-c2-jdk_text, \ + linux_i586_2.6-product-{c1|c2}-jdk_text, \ + linux_x64_2.6-product-c2-jdk_text, \ + ${jprt.my.windows.i586}-product-c1-jdk_text, \ + windows_x64_5.2-product-c2-jdk_text, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools1, \ + solaris_sparcv9_5.10-product-c2-jdk_tools1, \ + solaris_i586_5.10-product-c1-jdk_tools1, \ + solaris_x64_5.10-product-c2-jdk_tools1, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools1, \ + linux_x64_2.6-product-c2-jdk_tools1, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools1, \ + windows_x64_5.2-product-c2-jdk_tools1, \ + \ + solaris_sparc_5.10-product-c1-jdk_util, \ + solaris_sparcv9_5.10-product-c2-jdk_util, \ + solaris_i586_5.10-product-c1-jdk_util, \ + solaris_x64_5.10-product-c2-jdk_util, \ + linux_i586_2.6-product-{c1|c2}-jdk_util, \ + linux_x64_2.6-product-c2-jdk_util, \ + ${jprt.my.windows.i586}-product-c1-jdk_util, \ + windows_x64_5.2-product-c2-jdk_util -# Test targets in test/Makefile (some longer running tests only test c2) -jprt.make.rule.test.targets= \ - *-product-*-jdk_beans1, \ - *-product-*-jdk_beans2, \ - *-product-*-jdk_beans3, \ - *-product-*-jdk_io, \ - *-product-*-jdk_lang, \ - *-product-*-jdk_management1, \ - *-product-*-jdk_management2, \ - *-product-*-jdk_math, \ - *-product-*-jdk_misc, \ - *-product-*-jdk_net, \ - *-product-*-jdk_nio1, \ - *-product-*-jdk_nio2, \ - *-product-*-jdk_nio3, \ - *-product-*-jdk_security1, \ - *-product-*-jdk_security2, \ - *-product-*-jdk_security3, \ - *-product-*-jdk_text, \ - *-product-*-jdk_tools1, \ - *-product-*-jdk_tools2, \ - *-product-*-jdk_util +# All jdk test targets in test/Makefile (still no fastdebug & limited c2) +jprt.make.rule.all.test.targets= \ + \ + ${jprt.make.rule.default.test.targets}, \ + \ + solaris_sparc_5.10-product-c1-jdk_awt, \ + solaris_sparcv9_5.10-product-c2-jdk_awt, \ + solaris_i586_5.10-product-c1-jdk_awt, \ + solaris_x64_5.10-product-c2-jdk_awt, \ + linux_i586_2.6-product-{c1|c2}-jdk_awt, \ + linux_x64_2.6-product-c2-jdk_awt, \ + ${jprt.my.windows.i586}-product-c1-jdk_awt, \ + windows_x64_5.2-product-c2-jdk_awt, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans2, \ + solaris_sparcv9_5.10-product-c2-jdk_beans2, \ + solaris_i586_5.10-product-c1-jdk_beans2, \ + solaris_x64_5.10-product-c2-jdk_beans2, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans2, \ + linux_x64_2.6-product-c2-jdk_beans2, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans2, \ + windows_x64_5.2-product-c2-jdk_beans2, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans3, \ + solaris_sparcv9_5.10-product-c2-jdk_beans3, \ + solaris_i586_5.10-product-c1-jdk_beans3, \ + solaris_x64_5.10-product-c2-jdk_beans3, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans3, \ + linux_x64_2.6-product-c2-jdk_beans3, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans3, \ + windows_x64_5.2-product-c2-jdk_beans3, \ + \ + solaris_sparc_5.10-product-c1-jdk_management1, \ + solaris_sparcv9_5.10-product-c2-jdk_management1, \ + solaris_i586_5.10-product-c1-jdk_management1, \ + solaris_x64_5.10-product-c2-jdk_management1, \ + linux_i586_2.6-product-{c1|c2}-jdk_management1, \ + linux_x64_2.6-product-c2-jdk_management1, \ + ${jprt.my.windows.i586}-product-c1-jdk_management1, \ + windows_x64_5.2-product-c2-jdk_management1, \ + \ + solaris_sparc_5.10-product-c1-jdk_management2, \ + solaris_sparcv9_5.10-product-c2-jdk_management2, \ + solaris_i586_5.10-product-c1-jdk_management2, \ + solaris_x64_5.10-product-c2-jdk_management2, \ + linux_i586_2.6-product-{c1|c2}-jdk_management2, \ + linux_x64_2.6-product-c2-jdk_management2, \ + ${jprt.my.windows.i586}-product-c1-jdk_management2, \ + windows_x64_5.2-product-c2-jdk_management2, \ + \ + solaris_sparc_5.10-product-c1-jdk_rmi, \ + solaris_sparcv9_5.10-product-c2-jdk_rmi, \ + solaris_i586_5.10-product-c1-jdk_rmi, \ + solaris_x64_5.10-product-c2-jdk_rmi, \ + linux_i586_2.6-product-{c1|c2}-jdk_rmi, \ + linux_x64_2.6-product-c2-jdk_rmi, \ + ${jprt.my.windows.i586}-product-c1-jdk_rmi, \ + windows_x64_5.2-product-c2-jdk_rmi, \ + \ + solaris_sparc_5.10-product-c1-jdk_security2, \ + solaris_sparcv9_5.10-product-c2-jdk_security2, \ + solaris_i586_5.10-product-c1-jdk_security2, \ + solaris_x64_5.10-product-c2-jdk_security2, \ + linux_i586_2.6-product-{c1|c2}-jdk_security2, \ + linux_x64_2.6-product-c2-jdk_security2, \ + ${jprt.my.windows.i586}-product-c1-jdk_security2, \ + windows_x64_5.2-product-c2-jdk_security2, \ + \ + solaris_sparc_5.10-product-c1-jdk_security3, \ + solaris_sparcv9_5.10-product-c2-jdk_security3, \ + solaris_i586_5.10-product-c1-jdk_security3, \ + solaris_x64_5.10-product-c2-jdk_security3, \ + linux_i586_2.6-product-{c1|c2}-jdk_security3, \ + linux_x64_2.6-product-c2-jdk_security3, \ + ${jprt.my.windows.i586}-product-c1-jdk_security3, \ + windows_x64_5.2-product-c2-jdk_security3, \ + \ + solaris_sparc_5.10-product-c1-jdk_swing, \ + solaris_sparcv9_5.10-product-c2-jdk_swing, \ + solaris_i586_5.10-product-c1-jdk_swing, \ + solaris_x64_5.10-product-c2-jdk_swing, \ + linux_i586_2.6-product-{c1|c2}-jdk_swing, \ + linux_x64_2.6-product-c2-jdk_swing, \ + ${jprt.my.windows.i586}-product-c1-jdk_swing, \ + windows_x64_5.2-product-c2-jdk_swing, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools2, \ + solaris_sparcv9_5.10-product-c2-jdk_tools2, \ + solaris_i586_5.10-product-c1-jdk_tools2, \ + solaris_x64_5.10-product-c2-jdk_tools2, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools2, \ + linux_x64_2.6-product-c2-jdk_tools2, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools2, \ + windows_x64_5.2-product-c2-jdk_tools2 -# Some of these are crashing Xvfb or windows manager, need dedicated DISPLAY per test batch -jprt2.make.rule.test.targets= \ - *-product-*-jdk_awt, \ - *-product-*-jdk_rmi, \ - *-product-*-jdk_swing, \ +# Select list to use (allow for testset to be empty too) +jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets} +jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets} # Directories to be excluded from the source bundles jprt.bundle.exclude.src.dirs=build dist webrev diff --git a/jdk/make/mkdemo/Makefile b/jdk/make/mkdemo/Makefile index cda377f83f2027805a22c9bd6a0c0b250cf8411c..5a54d2795cd9775a49c17aef576de6a9f036bbd3 100644 --- a/jdk/make/mkdemo/Makefile +++ b/jdk/make/mkdemo/Makefile @@ -31,7 +31,7 @@ BUILDDIR = .. PRODUCT = demos include $(BUILDDIR)/common/Defs.gmk -SUBDIRS = jni +SUBDIRS = jni nio SUBDIRS_desktop = applets jfc SUBDIRS_management = management SUBDIRS_misc = scripting diff --git a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh b/jdk/make/mkdemo/nio/Makefile similarity index 53% rename from jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh rename to jdk/make/mkdemo/nio/Makefile index 927e951bea0c4de85f11cd80383afb05d173cb53..26dc772b21387473d365e523390ce6975820bd50 100644 --- a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh +++ b/jdk/make/mkdemo/nio/Makefile @@ -1,10 +1,12 @@ # -# Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. +# 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 @@ -21,42 +23,17 @@ # questions. # - # @test - # @bug 6502503 - # @run shell/timeout=140 ChunkedCharEncoding.sh - # @summary Http URL connection don't work when default encoding is Cp037: HTTP Transfer-Encoding:chunked - -OS=`uname -s` -case "$OS" in - SunOS | Linux ) - PS=":" - FS="/" - ;; - CYGWIN* ) - PS=";" - FS="/" - ;; - Windows* ) - PS=";" - FS="\\" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -# compile -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}TestAvailable.java +# +# Makefile for building the jfc demos +# -# run with CP037 encoding specified. -${TESTJAVA}${FS}bin${FS}java -Dfile.encoding=Cp037 TestAvailable 2>&1 +BUILDDIR = ../.. +PRODUCT = demos +include $(BUILDDIR)/common/Defs.gmk -result=$? -if [ "$result" -ne "0" ]; then - exit 1 -fi +SUBDIRS = zipfs +include $(BUILDDIR)/common/Subdirs.gmk -# no failures, exit. -exit 0 +all build clean clobber:: + $(SUBDIRS-loop) diff --git a/jdk/make/mkdemo/nio/zipfs/Makefile b/jdk/make/mkdemo/nio/zipfs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..16e71a9ba45d7372db23f76b8857a43d8812a9a4 --- /dev/null +++ b/jdk/make/mkdemo/nio/zipfs/Makefile @@ -0,0 +1,44 @@ +# +# Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute 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. +# + +# +# Makefile to build the ZipFileSystem demo. +# + +BUILDDIR = ../../.. +PRODUCT = demo/zipfs +DEMONAME = zipfs +include $(BUILDDIR)/common/Defs.gmk + +DEMO_ROOT = $(SHARE_SRC)/demo/nio/$(DEMONAME) +DEMO_TOPFILES = ./README.txt +DEMO_SRCDIR = $(DEMO_ROOT) +DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME) + +# +# Demo jar building rules. +# +include $(BUILDDIR)/common/Demo.gmk + diff --git a/jdk/make/sun/cmm/lcms/Makefile b/jdk/make/sun/cmm/lcms/Makefile index 1072c2fac7bf7c1bd74b7cccc10b29f98fa7b139..702c32680c8a1932225dec3460e08f7fca1ad23e 100644 --- a/jdk/make/sun/cmm/lcms/Makefile +++ b/jdk/make/sun/cmm/lcms/Makefile @@ -80,7 +80,12 @@ vpath %.c $(SHARE_SRC)/native/$(PKGDIR) vpath %.c $(SHARE_SRC)/native/sun/java2d ifeq ($(PLATFORM), windows) -OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt +OTHER_CFLAGS += -DCMS_IS_WINDOWS_ + +ifeq ($(COMPILER_VERSION), VS2003) +OTHER_CFLAGS += -Dsqrtf=sqrt +endif + OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \ -I$(SHARE_SRC)/native/sun/awt/debug diff --git a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java index cc3ebbfc21b4d5b104a21d986ec84bad1df5c01f..cce2997202b31a9357f46d9a319329cee5b56d23 100644 --- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java +++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java @@ -525,7 +525,7 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern iMatchColumns = new Vector(10); for(int i = 0; i < 10 ; i++) { - iMatchColumns.add(i,new Integer(-1)); + iMatchColumns.add(i,Integer.valueOf(-1)); } strMatchColumns = new Vector(10); @@ -889,7 +889,12 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern success = false; } else { tWriter = (TransactionalWriter)rowSetWriter; - ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert); + if (tWriter instanceof CachedRowSetWriter) { + ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert); + } else { + tWriter.commit(); + } + success = true; } } @@ -1294,7 +1299,7 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern tMap = new TreeMap(); for (int i = 0; iJoinRowSet @@ -550,7 +552,7 @@ public class JoinRowSetImpl extends WebRowSetImpl implements JoinRowSet { // This 'if' will be removed after all joins are implemented. throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString()); } else { - Integer Intgr = new Integer(JoinRowSet.INNER_JOIN); + Integer Intgr = Integer.valueOf(JoinRowSet.INNER_JOIN); vecJoinType.add(Intgr); } } else { @@ -874,8 +876,8 @@ public class JoinRowSetImpl extends WebRowSetImpl implements JoinRowSet { String strWhereClause = "Select "; String whereClause; - String tabName= null; - String strTabName = null; + String tabName= ""; + String strTabName = ""; int sz,cols; int j; CachedRowSetImpl crs; @@ -889,8 +891,6 @@ public class JoinRowSetImpl extends WebRowSetImpl implements JoinRowSet { // tableNameX.(rowsetX.getMatchColumnName()) == // tableNameZ.(rowsetZ.getMatchColumnName())); - tabName = new String(); - strTabName = new String(); sz = vecRowSetsInJOIN.size(); for(int i=0;iString detailing the vendor name of this * SyncProvider diff --git a/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java b/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java index bbe2bdc543649445abdf60fe2a5ad012618800fc..3736001cca25210274bda2de3e235cc25bb14554 100644 --- a/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java +++ b/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,7 +85,7 @@ public final class RIXMLProvider extends SyncProvider { /** * The vendor name of this SyncProvider implementation. */ - private String vendorName = "Sun Microsystems Inc."; + private String vendorName = "Oracle Corporation"; /** * The version number of this SyncProvider implementation. diff --git a/jdk/src/share/classes/com/sun/servicetag/Installer.java b/jdk/src/share/classes/com/sun/servicetag/Installer.java index 2c8476e71f88ed134fd2a409b7eec1367cdf1b1e..ae5ed4bc4fb3f150fc148b2c79369be248cd45fc 100644 --- a/jdk/src/share/classes/com/sun/servicetag/Installer.java +++ b/jdk/src/share/classes/com/sun/servicetag/Installer.java @@ -43,7 +43,8 @@ public class Installer { "servicetag.dir.path"; private static String SVCTAG_ENABLE_REGISTRATION = "servicetag.registration.enabled"; - private final static String SUN_VENDOR = "Sun Microsystems"; + private final static String ORACLE = "Oracle"; + private final static String SUN = "Sun Microsystems"; private final static String REGISTRATION_XML = "registration.xml"; private final static String SERVICE_TAG_FILE = "servicetag"; private final static String REGISTRATION_HTML_NAME = "register"; @@ -84,9 +85,10 @@ public class Installer { // Implementation of ServiceTag.getJavaServiceTag(String) method static ServiceTag getJavaServiceTag(String source) throws IOException { - if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) { + String vendor = System.getProperty("java.vendor", ""); + if (!vendor.startsWith(SUN) && !vendor.startsWith(ORACLE)) { // Products bundling this implementation may run on - // Mac OS which is not a Sun JDK + // Mac OS which is not a Sun/Oracle JDK return null; } boolean cleanup = false; @@ -365,7 +367,7 @@ public class Installer { props.getProperty("servicetag.parent.name"), props.getProperty("servicetag.parent.urn"), getProductDefinedId(), - SUN_VENDOR, + System.getProperty("java.vendor"), System.getProperty("os.arch"), getZoneName(), svcTagSource); diff --git a/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java b/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java index 99f5623d14597a585ddee94507bdb24220814038..1c203f4126c516f212467b0545df28819bd79cff 100644 --- a/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java +++ b/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java @@ -80,12 +80,12 @@ import static com.sun.servicetag.RegistrationDocument.*; * * systemManufacturer * System manufacturer - * e.g. Sun Microsystems + * e.g. Oracle Corporation * * * cpuManufacturer * CPU manufacturer - * e.g. Sun Microsystems + * e.g. Oracle Corporation * * * serialNumber diff --git a/jdk/src/share/classes/com/sun/servicetag/Registry.java b/jdk/src/share/classes/com/sun/servicetag/Registry.java index 14ad2fd623d590e31431e3195104966830b4f9f3..505ac64c6297835e36f525ca964b62054d209a89 100644 --- a/jdk/src/share/classes/com/sun/servicetag/Registry.java +++ b/jdk/src/share/classes/com/sun/servicetag/Registry.java @@ -90,7 +90,7 @@ public class Registry { stclient = getWindowsStClientFile(); } else { if (isVerbose()) { - System.out.println("Running on non-Sun JDK"); + System.out.println("Running on unsupported platform"); } } initialized = true; diff --git a/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java b/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java index 3cfd556a1fd4413dc2bdb091820be4398502bf4b..19cbae0b4a1b39b442c4dd7fa173f181668da2a8 100644 --- a/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java +++ b/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java @@ -44,6 +44,7 @@ import java.io.*; * Solaris implementation of the SystemEnvironment class. */ class SolarisSystemEnvironment extends SystemEnvironment { + private static final String ORACLE = "Oracle Corporation"; SolarisSystemEnvironment() { setHostId(getCommandOutput("/usr/bin/hostid")); setSystemModel(getCommandOutput("/usr/bin/uname", "-i")); @@ -59,7 +60,7 @@ class SolarisSystemEnvironment extends SystemEnvironment { private String getSolarisCpuManufacturer() { // not fully accurate, this could be another manufacturer (fujitsu for example) if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) { - return "Sun Microsystems, Inc"; + return ORACLE; } // if we're here, then we'll try smbios (type 4) @@ -73,7 +74,7 @@ class SolarisSystemEnvironment extends SystemEnvironment { private String getSolarisSystemManufacturer() { // not fully accurate, this could be another manufacturer (fujitsu for example) if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) { - return "Sun Microsystems, Inc"; + return ORACLE; } // if we're here, then we'll try smbios (type 1) @@ -117,7 +118,7 @@ class SolarisSystemEnvironment extends SystemEnvironment { // ID SIZE TYPE // 1 150 SMB_TYPE_SYSTEM (system information) // - // Manufacturer: Sun Microsystems + // Manufacturer: Oracle Corporation // Product: Sun Fire X4600 // Version: To Be Filled By O.E.M. // Serial Number: 00:14:4F:45:0C:2A diff --git a/jdk/src/share/classes/java/awt/Dialog.java b/jdk/src/share/classes/java/awt/Dialog.java index 3e2effd1dc059733f7af891f5a03547bc517b1d2..36a3502e3ba16e9863f67b265cf55dc526e23dfd 100644 --- a/jdk/src/share/classes/java/awt/Dialog.java +++ b/jdk/src/share/classes/java/awt/Dialog.java @@ -1068,7 +1068,7 @@ public class Dialog extends Window { modalityPushed(); try { EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); - secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000); + secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0); if (!secondaryLoop.enter()) { secondaryLoop = null; } diff --git a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java index 0c272763508eac53e87e9e6c2ce9bbb5d10cee01..07ecefe1def49c3c734df9feadd9f80710990c37 100644 --- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java @@ -142,6 +142,9 @@ public abstract class KeyboardFocusManager public void removeLastFocusRequest(Component heavyweight) { KeyboardFocusManager.removeLastFocusRequest(heavyweight); } + public void setMostRecentFocusOwner(Window window, Component component) { + KeyboardFocusManager.setMostRecentFocusOwner(window, component); + } } ); } diff --git a/jdk/src/share/classes/java/awt/event/ActionEvent.java b/jdk/src/share/classes/java/awt/event/ActionEvent.java index ec29e6d09f5c98d41c4fee2805e197ecd9c9d69b..3d5280aa65812ee926b388c517f3026bd4b23bfa 100644 --- a/jdk/src/share/classes/java/awt/event/ActionEvent.java +++ b/jdk/src/share/classes/java/awt/event/ActionEvent.java @@ -51,7 +51,7 @@ import java.awt.Event; * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}. * * @see ActionListener - * @see Tutorial: Java 1.1 Event Model + * @see Tutorial: How to Write an Action Listener * * @author Carl Quinn * @since 1.1 diff --git a/jdk/src/share/classes/java/awt/image/SampleModel.java b/jdk/src/share/classes/java/awt/image/SampleModel.java index cb7bd8a491f5eb8372ee532312d85217124d6a32..a2b02c44a6252a6e9f5ef5cc8326de71832bb6b7 100644 --- a/jdk/src/share/classes/java/awt/image/SampleModel.java +++ b/jdk/src/share/classes/java/awt/image/SampleModel.java @@ -937,14 +937,22 @@ public abstract class SampleModel int iArray[], DataBuffer data) { int pixels[]; int Offset=0; + int x1 = x + w; + int y1 = y + h; + + if (x < 0 || x1 < x || x1 > width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates."); + } if (iArray != null) pixels = iArray; else pixels = new int[w * h]; - for(int i=y; i<(h+y); i++) { - for (int j=x; j<(w+x); j++) { + for(int i=y; i width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates"); + } if (fArray != null) pixels = fArray; else pixels = new float[w * h]; - for (int i=y; i<(h+y); i++) { - for (int j=x; j<(w+x); j++) { + for (int i=y; i width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates"); + } if (dArray != null) pixels = dArray; else pixels = new double[w * h]; - for (int i=y; i<(y+h); i++) { - for (int j=x; j<(x+w); j++) { + for (int i=y; i type, String name, int args) { - for (Method method : type.getMethods()) { - if (method.getName().equals(name) && (args == method.getParameterTypes().length)) { - try { - return MethodFinder.findAccessibleMethod(method); + /** + * Internal support for finding a target methodName with a given + * parameter list on a given class. + */ + private static Method internalFindMethod(Class start, String methodName, + int argCount, Class args[]) { + // For overriden methods we need to find the most derived version. + // So we start with the given class and walk up the superclass chain. + + Method method = null; + + for (Class cl = start; cl != null; cl = cl.getSuperclass()) { + Method methods[] = getPublicDeclaredMethods(cl); + for (int i = 0; i < methods.length; i++) { + method = methods[i]; + if (method == null) { + continue; } - catch (NoSuchMethodException exception) { - // continue search for a method with the specified count of parameters + + // make sure method signature matches. + Class params[] = FeatureDescriptor.getParameterTypes(start, method); + if (method.getName().equals(methodName) && + params.length == argCount) { + if (args != null) { + boolean different = false; + if (argCount > 0) { + for (int j = 0; j < argCount; j++) { + if (params[j] != args[j]) { + different = true; + continue; + } + } + if (different) { + continue; + } + } + } + return method; } } } - return null; + method = null; + + // Now check any inherited interfaces. This is necessary both when + // the argument class is itself an interface, and when the argument + // class is an abstract class. + Class ifcs[] = start.getInterfaces(); + for (int i = 0 ; i < ifcs.length; i++) { + // Note: The original implementation had both methods calling + // the 3 arg method. This is preserved but perhaps it should + // pass the args array instead of null. + method = internalFindMethod(ifcs[i], methodName, argCount, null); + if (method != null) { + break; + } + } + return method; } - static Method findInstanceMethod(Class type, String name, Class... args) { - try { - return MethodFinder.findInstanceMethod(type, name, args); - } - catch (NoSuchMethodException exception) { + /** + * Find a target methodName on a given class. + */ + static Method findMethod(Class cls, String methodName, int argCount) { + return findMethod(cls, methodName, argCount, null); + } + + /** + * Find a target methodName with specific parameter list on a given class. + *

+ * Used in the contructors of the EventSetDescriptor, + * PropertyDescriptor and the IndexedPropertyDescriptor. + *

+ * @param cls The Class object on which to retrieve the method. + * @param methodName Name of the method. + * @param argCount Number of arguments for the desired method. + * @param args Array of argument types for the method. + * @return the method or null if not found + */ + static Method findMethod(Class cls, String methodName, int argCount, + Class args[]) { + if (methodName == null) { return null; } + return internalFindMethod(cls, methodName, argCount, args); } /** diff --git a/jdk/src/share/classes/java/beans/MethodDescriptor.java b/jdk/src/share/classes/java/beans/MethodDescriptor.java index 74a7a16782d704a73246ae1b667971eaf0082a45..d9e78be516f80be7fd5bb67048d2c7f8b1c31e1a 100644 --- a/jdk/src/share/classes/java/beans/MethodDescriptor.java +++ b/jdk/src/share/classes/java/beans/MethodDescriptor.java @@ -90,13 +90,13 @@ public class MethodDescriptor extends FeatureDescriptor { // Find methods for up to 2 params. We are guessing here. // This block should never execute unless the classloader // that loaded the argument classes disappears. - method = Introspector.findMethod(cls, name, i); + method = Introspector.findMethod(cls, name, i, null); if (method != null) { break; } } } else { - method = Statement.getMethod(cls, name, params); + method = Introspector.findMethod(cls, name, params.length, params); } setMethod(method); } diff --git a/jdk/src/share/classes/java/beans/PropertyDescriptor.java b/jdk/src/share/classes/java/beans/PropertyDescriptor.java index c7524e3026fcdf354c3278b85aca30d27782fbb1..429d2b4079b3d1d933a9fff10d90fe279acf36fd 100644 --- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java +++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java @@ -112,7 +112,8 @@ public class PropertyDescriptor extends FeatureDescriptor { // If this class or one of its base classes allow PropertyChangeListener, // then we assume that any properties we discover are "bound". // See Introspector.getTargetPropertyInfo() method. - this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class); + Class[] args = { PropertyChangeListener.class }; + this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args); } /** @@ -223,10 +224,10 @@ public class PropertyDescriptor extends FeatureDescriptor { // property type is. For booleans, there can be "is" and "get" // methods. If an "is" method exists, this is the official // reader method so look for this one first. - readMethod = Introspector.findInstanceMethod(cls, readMethodName); + readMethod = Introspector.findMethod(cls, readMethodName, 0); if (readMethod == null) { readMethodName = Introspector.GET_PREFIX + getBaseName(); - readMethod = Introspector.findInstanceMethod(cls, readMethodName); + readMethod = Introspector.findMethod(cls, readMethodName, 0); } try { setReadMethod(readMethod); @@ -291,7 +292,8 @@ public class PropertyDescriptor extends FeatureDescriptor { writeMethodName = Introspector.SET_PREFIX + getBaseName(); } - writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type); + Class[] args = (type == null) ? null : new Class[] { type }; + writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args); if (writeMethod != null) { if (!writeMethod.getReturnType().equals(void.class)) { writeMethod = null; diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java index 39c6a5888d16912f0814b6a705f0f14b81b0f6eb..42431865f255584552b584efcff567bd5b851616 100644 --- a/jdk/src/share/classes/java/lang/System.java +++ b/jdk/src/share/classes/java/lang/System.java @@ -1101,22 +1101,12 @@ public final class System { lineSeparator = props.getProperty("line.separator"); sun.misc.Version.init(); - // Workaround until DownloadManager initialization is revisited. - // Make JavaLangAccess available early enough for internal - // Shutdown hooks to be registered - setJavaLangAccess(); - // Gets and removes system properties that configure the Integer // cache used to support the object identity semantics of autoboxing. // At this time, the size of the cache may be controlled by the // vm option -XX:AutoBoxCacheMax=. Integer.getAndRemoveCacheProperties(); - // Load the zip library now in order to keep java.util.zip.ZipFile - // from trying to use itself to load this library later. - loadLibrary("zip"); - - FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); @@ -1124,6 +1114,10 @@ public final class System { setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); + // Load the zip library now in order to keep java.util.zip.ZipFile + // from trying to use itself to load this library later. + loadLibrary("zip"); + // Setup Java signal handlers for HUP, TERM, and INT (where available). Terminator.setup(); @@ -1153,6 +1147,9 @@ public final class System { // way as other threads; we must do it ourselves here. Thread current = Thread.currentThread(); current.getThreadGroup().add(current); + + // register shared secrets + setJavaLangAccess(); } private static void setJavaLangAccess() { diff --git a/jdk/src/share/classes/java/net/InetAddress.java b/jdk/src/share/classes/java/net/InetAddress.java index 96a17482d8ff9afff5cd8afa1aec36aee48f5d02..c4ace57995f96943f1b096a1d1c7c8fc1b77d6c3 100644 --- a/jdk/src/share/classes/java/net/InetAddress.java +++ b/jdk/src/share/classes/java/net/InetAddress.java @@ -677,19 +677,20 @@ class InetAddress implements java.io.Serializable { static InetAddressImpl impl; - private static HashMap lookupTable = new HashMap(); + private static HashMap lookupTable + = new HashMap(); /** * Represents a cache entry */ static final class CacheEntry { - CacheEntry(Object address, long expiration) { - this.address = address; + CacheEntry(InetAddress[] addresses, long expiration) { + this.addresses = addresses; this.expiration = expiration; } - Object address; + InetAddress[] addresses; long expiration; } @@ -698,7 +699,7 @@ class InetAddress implements java.io.Serializable { * at creation time. */ static final class Cache { - private LinkedHashMap cache; + private LinkedHashMap cache; private Type type; enum Type {Positive, Negative}; @@ -708,7 +709,7 @@ class InetAddress implements java.io.Serializable { */ public Cache(Type type) { this.type = type; - cache = new LinkedHashMap(); + cache = new LinkedHashMap(); } private int getPolicy() { @@ -724,7 +725,7 @@ class InetAddress implements java.io.Serializable { * entry then for this host then the entry will be * replaced. */ - public Cache put(String host, Object address) { + public Cache put(String host, InetAddress[] addresses) { int policy = getPolicy(); if (policy == InetAddressCachePolicy.NEVER) { return this; @@ -736,12 +737,10 @@ class InetAddress implements java.io.Serializable { // As we iterate in insertion order we can // terminate when a non-expired entry is found. - LinkedList expired = new LinkedList(); - Iterator i = cache.keySet().iterator(); + LinkedList expired = new LinkedList(); long now = System.currentTimeMillis(); - while (i.hasNext()) { - String key = (String)i.next(); - CacheEntry entry = (CacheEntry)cache.get(key); + for (String key : cache.keySet()) { + CacheEntry entry = cache.get(key); if (entry.expiration >= 0 && entry.expiration < now) { expired.add(key); @@ -750,9 +749,8 @@ class InetAddress implements java.io.Serializable { } } - i = expired.iterator(); - while (i.hasNext()) { - cache.remove(i.next()); + for (String key : expired) { + cache.remove(key); } } @@ -766,7 +764,7 @@ class InetAddress implements java.io.Serializable { } else { expiration = System.currentTimeMillis() + (policy * 1000); } - CacheEntry entry = new CacheEntry(address, expiration); + CacheEntry entry = new CacheEntry(addresses, expiration); cache.put(host, entry); return this; } @@ -780,7 +778,7 @@ class InetAddress implements java.io.Serializable { if (policy == InetAddressCachePolicy.NEVER) { return null; } - CacheEntry entry = (CacheEntry)cache.get(host); + CacheEntry entry = cache.get(host); // check if entry has expired if (entry != null && policy != InetAddressCachePolicy.FOREVER) { @@ -814,42 +812,41 @@ class InetAddress implements java.io.Serializable { } /* - * Cache the given hostname and address. + * Cache the given hostname and addresses. */ - private static void cacheAddress(String hostname, Object address, - boolean success) { + private static void cacheAddresses(String hostname, + InetAddress[] addresses, + boolean success) { hostname = hostname.toLowerCase(); synchronized (addressCache) { cacheInitIfNeeded(); if (success) { - addressCache.put(hostname, address); + addressCache.put(hostname, addresses); } else { - negativeCache.put(hostname, address); + negativeCache.put(hostname, addresses); } } } /* * Lookup hostname in cache (positive & negative cache). If - * found return address, null if not found. + * found return addresses, null if not found. */ - private static Object getCachedAddress(String hostname) { + private static InetAddress[] getCachedAddresses(String hostname) { hostname = hostname.toLowerCase(); // search both positive & negative caches synchronized (addressCache) { - CacheEntry entry; - cacheInitIfNeeded(); - entry = addressCache.get(hostname); + CacheEntry entry = addressCache.get(hostname); if (entry == null) { entry = negativeCache.get(hostname); } if (entry != null) { - return entry.address; + return entry.addresses; } } @@ -911,7 +908,7 @@ class InetAddress implements java.io.Serializable { static { // create the impl - impl = (new InetAddressImplFactory()).create(); + impl = InetAddressImplFactory.create(); // get name service if provided and requested String provider = null;; @@ -931,7 +928,7 @@ class InetAddress implements java.io.Serializable { } // if not designate any name services provider, - // creat a default one + // create a default one if (nameServices.size() == 0) { NameService ns = createNSProvider("default"); nameServices.add(ns); @@ -939,7 +936,7 @@ class InetAddress implements java.io.Serializable { } /** - * Create an InetAddress based on the provided host name and IP address + * Creates an InetAddress based on the provided host name and IP address. * No name service is checked for the validity of the address. * *

The host name can either be a machine name, such as @@ -1067,13 +1064,13 @@ class InetAddress implements java.io.Serializable { boolean ipv6Expected = false; if (host.charAt(0) == '[') { - // This is supposed to be an IPv6 litteral + // This is supposed to be an IPv6 literal if (host.length() > 2 && host.charAt(host.length()-1) == ']') { host = host.substring(1, host.length() -1); ipv6Expected = true; } else { // This was supposed to be a IPv6 address, but it's not! - throw new UnknownHostException(host); + throw new UnknownHostException(host + ": invalid IPv6 address"); } } @@ -1180,8 +1177,6 @@ class InetAddress implements java.io.Serializable { throws UnknownHostException { /* If it gets here it is presumed to be a hostname */ /* Cache.get can return: null, unknownAddress, or InetAddress[] */ - Object obj = null; - Object objcopy = null; /* make sure the connection to the host is allowed, before we * give out a hostname @@ -1193,26 +1188,23 @@ class InetAddress implements java.io.Serializable { } } - obj = getCachedAddress(host); + InetAddress[] addresses = getCachedAddresses(host); /* If no entry in cache, then do the host lookup */ - if (obj == null) { - obj = getAddressFromNameService(host); + if (addresses == null) { + addresses = getAddressesFromNameService(host); } - if (obj == unknown_array) + if (addresses == unknown_array) throw new UnknownHostException(host); - /* Make a copy of the InetAddress array */ - objcopy = ((InetAddress [])obj).clone(); - - return (InetAddress [])objcopy; + return addresses.clone(); } - private static Object getAddressFromNameService(String host) + private static InetAddress[] getAddressesFromNameService(String host) throws UnknownHostException { - Object obj = null; + InetAddress[] addresses = null; boolean success = false; UnknownHostException ex = null; @@ -1226,16 +1218,16 @@ class InetAddress implements java.io.Serializable { // would be blocked until the host is removed // from the lookupTable. Then this thread // should try to look up the addressCache. - // i) if it found the address in the + // i) if it found the addresses in the // addressCache, checkLookupTable() would - // return the address. - // ii) if it didn't find the address in the + // return the addresses. + // ii) if it didn't find the addresses in the // addressCache for any reason, // it should add the host in the // lookupTable and return null so the // following code would do a lookup itself. - if ((obj = checkLookupTable(host)) == null) { - // This is the first thread which looks up the address + if ((addresses = checkLookupTable(host)) == null) { + // This is the first thread which looks up the addresses // this host or the cache entry for this host has been // expired so this thread should do the lookup. for (NameService nameService : nameServices) { @@ -1246,26 +1238,26 @@ class InetAddress implements java.io.Serializable { * allocating space when the lookup fails. */ - obj = nameService.lookupAllHostAddr(host); + addresses = nameService.lookupAllHostAddr(host); success = true; break; } catch (UnknownHostException uhe) { if (host.equalsIgnoreCase("localhost")) { InetAddress[] local = new InetAddress[] { impl.loopbackAddress() }; - obj = local; + addresses = local; success = true; break; } else { - obj = unknown_array; + addresses = unknown_array; success = false; ex = uhe; } } } - // Cache the address. - cacheAddress(host, obj, success); + // Cache the addresses. + cacheAddresses(host, addresses, success); // Delete the host from the lookupTable, and // notify all threads waiting for the monitor // for lookupTable. @@ -1274,13 +1266,13 @@ class InetAddress implements java.io.Serializable { throw ex; } - return obj; + return addresses; } - private static Object checkLookupTable(String host) { - // make sure obj is null. - Object obj = null; + private static InetAddress[] checkLookupTable(String host) { + // make sure addresses is null. + InetAddress[] addresses = null; synchronized (lookupTable) { // If the host isn't in the lookupTable, add it in the @@ -1288,11 +1280,11 @@ class InetAddress implements java.io.Serializable { // the lookup. if (lookupTable.containsKey(host) == false) { lookupTable.put(host, null); - return obj; + return addresses; } // If the host is in the lookupTable, it means that another - // thread is trying to look up the address of this host. + // thread is trying to look up the addresses of this host. // This thread should wait. while (lookupTable.containsKey(host)) { try { @@ -1302,18 +1294,18 @@ class InetAddress implements java.io.Serializable { } } - // The other thread has finished looking up the address of - // the host. This thread should retry to get the address - // from the addressCache. If it doesn't get the address from - // the cache, it will try to look up the address itself. - obj = getCachedAddress(host); - if (obj == null) { + // The other thread has finished looking up the addresses of + // the host. This thread should retry to get the addresses + // from the addressCache. If it doesn't get the addresses from + // the cache, it will try to look up the addresses itself. + addresses = getCachedAddresses(host); + if (addresses == null) { synchronized (lookupTable) { lookupTable.put(host, null); } } - return obj; + return addresses; } private static void updateLookupTable(String host) { @@ -1396,15 +1388,20 @@ class InetAddress implements java.io.Serializable { cachedLocalHost = null; } - // we are calling getAddressFromNameService directly + // we are calling getAddressesFromNameService directly // to avoid getting localHost from cache if (ret == null) { InetAddress[] localAddrs; try { localAddrs = - (InetAddress[]) InetAddress.getAddressFromNameService(local); + InetAddress.getAddressesFromNameService(local); } catch (UnknownHostException uhe) { - throw new UnknownHostException(local + ": " + uhe.getMessage()); + // Rethrow with a more informative error message. + UnknownHostException uhe2 = + new UnknownHostException(local + ": " + + uhe.getMessage()); + uhe2.initCause(uhe); + throw uhe2; } cachedLocalHost = localAddrs[0]; cacheTime = now; @@ -1434,8 +1431,8 @@ class InetAddress implements java.io.Serializable { /* * Load and instantiate an underlying impl class */ - static Object loadImpl(String implName) { - Object impl; + static InetAddressImpl loadImpl(String implName) { + Object impl = null; /* * Property "impl.prefix" will be prepended to the classname @@ -1446,7 +1443,6 @@ class InetAddress implements java.io.Serializable { */ String prefix = AccessController.doPrivileged( new GetPropertyAction("impl.prefix", "")); - impl = null; try { impl = Class.forName("java.net." + prefix + implName).newInstance(); } catch (ClassNotFoundException e) { @@ -1471,7 +1467,7 @@ class InetAddress implements java.io.Serializable { } } - return impl; + return (InetAddressImpl) impl; } private void readObjectNoData (ObjectInputStream s) throws @@ -1498,13 +1494,8 @@ class InetAddress implements java.io.Serializable { class InetAddressImplFactory { static InetAddressImpl create() { - Object o; - if (isIPv6Supported()) { - o = InetAddress.loadImpl("Inet6AddressImpl"); - } else { - o = InetAddress.loadImpl("Inet4AddressImpl"); - } - return (InetAddressImpl)o; + return InetAddress.loadImpl(isIPv6Supported() ? + "Inet6AddressImpl" : "Inet4AddressImpl"); } static native boolean isIPv6Supported(); diff --git a/jdk/src/share/classes/java/nio/file/FileSystemLoopException.java b/jdk/src/share/classes/java/nio/file/FileSystemLoopException.java new file mode 100644 index 0000000000000000000000000000000000000000..fe6beb5ad099d64f5f197098bde97781adf26b9a --- /dev/null +++ b/jdk/src/share/classes/java/nio/file/FileSystemLoopException.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.nio.file; + +/** + * Checked exception thrown when a file system loop, or cycle, is encountered. + * + * @since 1.7 + * @see Files#walkFileTree + */ + +public class FileSystemLoopException + extends FileSystemException +{ + private static final long serialVersionUID = 4843039591949217617L; + + /** + * Constructs an instance of this class. + * + * @param file + * a string identifying the file causing the cycle or {@code null} if + * not known + */ + public FileSystemLoopException(String file) { + super(file); + } +} diff --git a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java index 8086012a9f5c1f3286b9be1b6395d3f48b42fca4..cd45d765290f2f87130acbee6c13a82d0cd6db48 100644 --- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java +++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java @@ -38,7 +38,6 @@ import sun.nio.fs.BasicFileAttributesHolder; class FileTreeWalker { private final boolean followLinks; - private final boolean detectCycles; private final LinkOption[] linkOptions; private final FileVisitor visitor; private final int maxDepth; @@ -48,17 +47,15 @@ class FileTreeWalker { int maxDepth) { boolean fl = false; - boolean dc = false; for (FileVisitOption option: options) { + // will throw NPE if options contains null switch (option) { - case FOLLOW_LINKS : fl = true; break; - case DETECT_CYCLES : dc = true; break; + case FOLLOW_LINKS : fl = true; break; default: throw new AssertionError("Should not get here"); } } this.followLinks = fl; - this.detectCycles = fl | dc; this.linkOptions = (fl) ? new LinkOption[0] : new LinkOption[] { LinkOption.NOFOLLOW_LINKS }; this.visitor = visitor; @@ -68,13 +65,11 @@ class FileTreeWalker { /** * Walk file tree starting at the given file */ - void walk(Path start) { + void walk(Path start) throws IOException { FileVisitResult result = walk(start, 0, new ArrayList()); - if (result == null) { - throw new NullPointerException("Visitor returned 'null'"); - } + Objects.nonNull(result, "FileVisitor returned null"); } /** @@ -88,11 +83,8 @@ class FileTreeWalker { private FileVisitResult walk(Path file, int depth, List ancestors) + throws IOException { - // depth check - if (depth > maxDepth) - return FileVisitResult.CONTINUE; - // if attributes are cached then use them if possible BasicFileAttributes attrs = null; if ((depth > 0) && @@ -137,13 +129,13 @@ class FileTreeWalker { return visitor.visitFileFailed(file, exc); } - // file is not a directory so invoke visitFile method - if (!attrs.isDirectory()) { + // at maximum depth or file is not a directory + if (depth >= maxDepth || !attrs.isDirectory()) { return visitor.visitFile(file, attrs); } - // check for cycles - if (detectCycles) { + // check for cycles when following links + if (followLinks) { Object key = attrs.fileKey(); // if this directory and ancestor has a file key then we compare @@ -153,19 +145,23 @@ class FileTreeWalker { if (key != null && ancestorKey != null) { if (key.equals(ancestorKey)) { // cycle detected - return visitor.visitFile(file, attrs); + return visitor.visitFileFailed(file, + new FileSystemLoopException(file.toString())); } } else { + boolean isSameFile = false; try { - if (file.isSameFile(ancestor.file())) { - // cycle detected - return visitor.visitFile(file, attrs); - } + isSameFile = file.isSameFile(ancestor.file()); } catch (IOException x) { // ignore } catch (SecurityException x) { // ignore } + if (isSameFile) { + // cycle detected + return visitor.visitFileFailed(file, + new FileSystemLoopException(file.toString())); + } } } @@ -181,7 +177,7 @@ class FileTreeWalker { try { stream = file.newDirectoryStream(); } catch (IOException x) { - return visitor.preVisitDirectoryFailed(file, x); + return visitor.visitFileFailed(file, x); } catch (SecurityException x) { // ignore, as per spec return FileVisitResult.CONTINUE; @@ -192,20 +188,14 @@ class FileTreeWalker { // invoke preVisitDirectory and then visit each entry try { - result = visitor.preVisitDirectory(file); + result = visitor.preVisitDirectory(file, attrs); if (result != FileVisitResult.CONTINUE) { return result; } - // if an I/O occurs during iteration then a CME is thrown. We - // need to distinguish this from a CME thrown by the visitor. - boolean inAction = false; - try { for (Path entry: stream) { - inAction = true; result = walk(entry, depth+1, ancestors); - inAction = false; // returning null will cause NPE to be thrown if (result == null || result == FileVisitResult.TERMINATE) @@ -215,17 +205,9 @@ class FileTreeWalker { if (result == FileVisitResult.SKIP_SIBLINGS) break; } - } catch (ConcurrentModificationException x) { - // if CME thrown because the iteration failed then remember - // the IOException so that it is notified to postVisitDirectory - if (!inAction) { - // iteration failed - Throwable t = x.getCause(); - if (t instanceof IOException) - ioe = (IOException)t; - } - if (ioe == null) - throw x; + } catch (DirectoryIteratorException e) { + // IOException will be notified to postVisitDirectory + ioe = e.getCause(); } } finally { try { @@ -238,7 +220,7 @@ class FileTreeWalker { } finally { // remove key from trail if doing cycle detection - if (detectCycles) { + if (followLinks) { ancestors.remove(ancestors.size()-1); } } diff --git a/jdk/src/share/classes/java/nio/file/FileVisitOption.java b/jdk/src/share/classes/java/nio/file/FileVisitOption.java index 7f1f14013dfb09056fd5ad300e3577aa7434372d..8941bd6911a23d5123a02684d6eaa6264db8f70f 100644 --- a/jdk/src/share/classes/java/nio/file/FileVisitOption.java +++ b/jdk/src/share/classes/java/nio/file/FileVisitOption.java @@ -37,9 +37,5 @@ public enum FileVisitOption { /** * Follow symbolic links. */ - FOLLOW_LINKS, - /** - * Detect cycles in the file tree. - */ - DETECT_CYCLES; + FOLLOW_LINKS; } diff --git a/jdk/src/share/classes/java/nio/file/FileVisitor.java b/jdk/src/share/classes/java/nio/file/FileVisitor.java index aefc6a8c2d1444cd2bdca5ee34448b1014e8d5b2..06ac0b870fbff559805f70570dac4ba5ccaf77f9 100644 --- a/jdk/src/share/classes/java/nio/file/FileVisitor.java +++ b/jdk/src/share/classes/java/nio/file/FileVisitor.java @@ -40,33 +40,28 @@ import java.io.IOException; * Path start = ... * Files.walkFileTree(start, new SimpleFileVisitor<Path>() { * @Override - * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { - * try { - * file.delete(); - * } catch (IOException exc) { - * // failed to delete, do error handling here - * } + * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + * throws IOException + * { + * file.delete(); * return FileVisitResult.CONTINUE; * } * @Override - * public FileVisitResult postVisitDirectory(Path dir, IOException e) { - * if (e == null) { - * try { - * dir.delete(); - * } catch (IOException exc) { - * // failed to delete, do error handling here - * } - * } else { + * public FileVisitResult postVisitDirectory(Path dir, IOException e) + * throws IOException + * { + * if (e != null) { * // directory iteration failed + * throw e; * } + * dir.delete(); * return FileVisitResult.CONTINUE; * } * }); * - *

Furthermore, suppose we want to copy a file tree rooted at a source - * directory to a target location. In that case, symbolic links should be - * followed and the target directory should be created before the entries in - * the directory are copied. + *

Furthermore, suppose we want to copy a file tree to a target location. + * In that case, symbolic links should be followed and the target directory + * should be created before the entries in the directory are copied. *

  *     final Path source = ...
  *     final Path target = ...
@@ -74,25 +69,21 @@ import java.io.IOException;
  *     Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
  *         new SimpleFileVisitor<Path>() {
  *             @Override
- *             public FileVisitResult preVisitDirectory(Path dir) {
+ *             public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+ *                 throws IOException
+ *             {
  *                 try {
  *                     dir.copyTo(target.resolve(source.relativize(dir)));
  *                 } catch (FileAlreadyExistsException e) {
  *                      // ignore
- *                 } catch (IOException e) {
- *                     // copy failed, do error handling here
- *                     // skip rest of directory and descendants
- *                     return SKIP_SUBTREE;
  *                 }
  *                 return CONTINUE;
  *             }
  *             @Override
- *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- *                 try {
- *                     file.copyTo(target.resolve(source.relativize(file)));
- *                 } catch (IOException e) {
- *                     // copy failed, do error handling here
- *                 }
+ *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ *                 throws IOException
+ *             {
+ *                 file.copyTo(target.resolve(source.relativize(file)));
  *                 return CONTINUE;
  *             }
  *         });
@@ -114,22 +105,16 @@ public interface FileVisitor {
      *
      * @param   dir
      *          a reference to the directory
+     * @param   attrs
+     *          the directory's basic attributes
      *
      * @return  the visit result
-     */
-    FileVisitResult preVisitDirectory(T dir);
-
-    /**
-     * Invoked for a directory that could not be opened.
      *
-     * @param   dir
-     *          a reference to the directory
-     * @param   exc
-     *          the I/O exception thrown from the attempt to open the directory
-     *
-     * @return  the visit result
+     * @throws  IOException
+     *          if an I/O error occurs
      */
-    FileVisitResult preVisitDirectoryFailed(T dir, IOException exc);
+    FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
+        throws IOException;
 
     /**
      * Invoked for a file in a directory.
@@ -140,21 +125,30 @@ public interface FileVisitor {
      *          the file's basic attributes
      *
      * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
      */
-    FileVisitResult visitFile(T file, BasicFileAttributes attrs);
+    FileVisitResult visitFile(T file, BasicFileAttributes attrs)
+        throws IOException;
 
     /**
-     * Invoked for a file when its basic file attributes could not be read.
+     * Invoked for a file that could not be visited. This method is invoked
+     * if the file's attributes could not be read, the file is a directory
+     * that could not be opened, and other reasons.
      *
      * @param   file
      *          a reference to the file
      * @param   exc
-     *          the I/O exception thrown from the attempt to read the file
-     *          attributes
+     *          the I/O exception that prevented the file from being visited
      *
      * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
      */
-    FileVisitResult visitFileFailed(T file, IOException exc);
+    FileVisitResult visitFileFailed(T file, IOException exc)
+        throws IOException;
 
     /**
      * Invoked for a directory after entries in the directory, and all of their
@@ -171,6 +165,10 @@ public interface FileVisitor {
      *          of the directory to complete prematurely
      *
      * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
      */
-    FileVisitResult postVisitDirectory(T dir, IOException exc);
+    FileVisitResult postVisitDirectory(T dir, IOException exc)
+        throws IOException;
 }
diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java
index 703a2a82c583927b8baf64713f1fff9ba0373e6e..7322016b4c7f4a19c98f0732738f5432b3845881 100644
--- a/jdk/src/share/classes/java/nio/file/Files.java
+++ b/jdk/src/share/classes/java/nio/file/Files.java
@@ -135,9 +135,9 @@ public final class Files {
      * FileVisitor} invoked for each file encountered. File tree traversal
      * completes when all accessible files in the tree have been visited, or a
      * visit method returns a result of {@link FileVisitResult#TERMINATE
-     * TERMINATE}. Where a visit method terminates due an uncaught error or
-     * runtime exception then the traversal is terminated and the error or
-     * exception is propagated to the caller of this method.
+     * TERMINATE}. Where a visit method terminates due an {@code IOException},
+     * an uncaught error, or runtime exception, then the traversal is terminated
+     * and the error or exception is propagated to the caller of this method.
      *
      * 

For each file encountered this method attempts to gets its {@link * java.nio.file.attribute.BasicFileAttributes}. If the file is not a @@ -146,12 +146,10 @@ public final class Files { * due to an I/O exception, then the {@link FileVisitor#visitFileFailed * visitFileFailed} method is invoked with the I/O exception. * - *

Where the file is a directory, this method attempts to open it by - * invoking its {@link Path#newDirectoryStream newDirectoryStream} method. - * Where the directory could not be opened, due to an {@code IOException}, - * then the {@link FileVisitor#preVisitDirectoryFailed preVisitDirectoryFailed} - * method is invoked with the I/O exception, after which, the file tree walk - * continues, by default, at the next sibling of the directory. + *

Where the file is a directory, and the directory could not be opened, + * then the {@code visitFileFailed} method is invoked with the I/O exception, + * after which, the file tree walk continues, by default, at the next + * sibling of the directory. * *

Where the directory is opened successfully, then the entries in the * directory, and their descendants are visited. When all entries @@ -171,26 +169,25 @@ public final class Files { * method is invoked as specified above). * *

If the {@code options} parameter contains the {@link - * FileVisitOption#DETECT_CYCLES DETECT_CYCLES} or {@link - * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} options then this method keeps + * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps * track of directories visited so that cycles can be detected. A cycle * arises when there is an entry in a directory that is an ancestor of the * directory. Cycle detection is done by recording the {@link * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories, * or if file keys are not available, by invoking the {@link Path#isSameFile * isSameFile} method to test if a directory is the same file as an - * ancestor. When a cycle is detected the {@link FileVisitor#visitFile - * visitFile} is invoked with the attributes of the directory. The {@link - * java.nio.file.attribute.BasicFileAttributes#isDirectory isDirectory} - * method may be used to test if the file is a directory and that a cycle is - * detected. The {@code preVisitDirectory} and {@code postVisitDirectory} - * methods are not invoked. + * ancestor. When a cycle is detected it is treated as an I/O error, and the + * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with + * an instance of {@link FileSystemLoopException}. * *

The {@code maxDepth} parameter is the maximum number of levels of * directories to visit. A value of {@code 0} means that only the starting * file is visited, unless denied by the security manager. A value of * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all - * levels should be visited. + * levels should be visited. The {@code visitFile} method is invoked for all + * files, including directories, encountered at {@code maxDepth}, unless the + * basic file attributes cannot be read, in which case the {@code + * visitFileFailed} method is invoked. * *

If a visitor returns a result of {@code null} then {@code * NullPointerException} is thrown. @@ -215,11 +212,14 @@ public final class Files { * In the case of the default provider, the {@link * SecurityManager#checkRead(String) checkRead} method is invoked * to check read access to the directory. + * @throws IOException + * If an I/O error is thrown by a visitor method */ public static void walkFileTree(Path start, Set options, int maxDepth, FileVisitor visitor) + throws IOException { if (maxDepth < 0) throw new IllegalArgumentException("'maxDepth' is negative"); @@ -245,8 +245,12 @@ public final class Files { * In the case of the default provider, the {@link * SecurityManager#checkRead(String) checkRead} method is invoked * to check read access to the directory. + * @throws IOException + * If an I/O error is thrown by a visitor method */ - public static void walkFileTree(Path start, FileVisitor visitor) { + public static void walkFileTree(Path start, FileVisitor visitor) + throws IOException + { walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, diff --git a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java index 66a2a74f2558c83f4e065b952be99ef466a3c271..77fb516b172ffb69bdd8cdbd17e7f6898dad1e92 100644 --- a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java +++ b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java @@ -27,7 +27,7 @@ package java.nio.file; import java.nio.file.attribute.BasicFileAttributes; import java.io.IOException; -import java.io.IOError; +import java.util.Objects; /** * A simple visitor of files with default behavior to visit all files and to @@ -47,14 +47,6 @@ public class SimpleFileVisitor implements FileVisitor { protected SimpleFileVisitor() { } - /** - * Throws NullPointerException if obj is null. - */ - private static void checkNotNull(Object obj) { - if (obj == null) - throw new NullPointerException(); - } - /** * Invoked for a directory before entries in the directory are visited. * @@ -62,28 +54,14 @@ public class SimpleFileVisitor implements FileVisitor { * CONTINUE}. */ @Override - public FileVisitResult preVisitDirectory(T dir) { - checkNotNull(dir); + public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) + throws IOException + { + Objects.nonNull(dir); + Objects.nonNull(attrs); return FileVisitResult.CONTINUE; } - /** - * Invoked for a directory that could not be opened. - * - *

Unless overridden, this method throws {@link IOError} with the I/O - * exception as cause. - * - * @throws IOError - * with the I/O exception thrown when the attempt to open the - * directory failed - */ - @Override - public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) { - checkNotNull(dir); - checkNotNull(exc); - throw new IOError(exc); - } - /** * Invoked for a file in a directory. * @@ -91,27 +69,26 @@ public class SimpleFileVisitor implements FileVisitor { * CONTINUE}. */ @Override - public FileVisitResult visitFile(T file, BasicFileAttributes attrs) { - checkNotNull(file); - checkNotNull(attrs); + public FileVisitResult visitFile(T file, BasicFileAttributes attrs) + throws IOException + { + Objects.nonNull(file); + Objects.nonNull(attrs); return FileVisitResult.CONTINUE; } /** - * Invoked for a file when its basic file attributes could not be read. - * - *

Unless overridden, this method throws {@link IOError} with the I/O - * exception as cause. + * Invoked for a file that could not be visited. * - * @throws IOError - * with the I/O exception thrown when the attempt to read the file - * attributes failed + *

Unless overridden, this method re-throws the I/O exception that prevented + * the file from being visited. */ @Override - public FileVisitResult visitFileFailed(T file, IOException exc) { - checkNotNull(file); - checkNotNull(exc); - throw new IOError(exc); + public FileVisitResult visitFileFailed(T file, IOException exc) + throws IOException + { + Objects.nonNull(file); + throw exc; } /** @@ -120,18 +97,16 @@ public class SimpleFileVisitor implements FileVisitor { * *

Unless overridden, this method returns {@link FileVisitResult#CONTINUE * CONTINUE} if the directory iteration completes without an I/O exception; - * otherwise this method throws {@link IOError} with the I/O exception as - * cause. - * - * @throws IOError - * with the I/O exception thrown when iteration of the directory - * completed prematurely due to an I/O error + * otherwise this method re-throws the I/O exception that caused the iteration + * of the directory to terminate prematurely. */ @Override - public FileVisitResult postVisitDirectory(T dir, IOException exc) { - checkNotNull(dir); + public FileVisitResult postVisitDirectory(T dir, IOException exc) + throws IOException + { + Objects.nonNull(dir); if (exc != null) - throw new IOError(exc); + throw exc; return FileVisitResult.CONTINUE; } } diff --git a/jdk/src/share/classes/java/sql/DatabaseMetaData.java b/jdk/src/share/classes/java/sql/DatabaseMetaData.java index d867986c6bf0ac72bf587ee25c75b6f908551df4..1ad5ea173584bc6e5ed0a80a9dffd01c87c84a12 100644 --- a/jdk/src/share/classes/java/sql/DatabaseMetaData.java +++ b/jdk/src/share/classes/java/sql/DatabaseMetaData.java @@ -3643,7 +3643,7 @@ public interface DatabaseMetaData extends Wrapper { /** * Retrieves whether a generated key will always be returned if the column - * name(s) or indexe(s) specified for the auto generated key column(s) + * name(s) or index(es) specified for the auto generated key column(s) * are valid and the statement succeeds. The key that is returned may or * may not be based on the column(s) for the auto generated key. * Consult your JDBC driver documentation for additional details. diff --git a/jdk/src/share/classes/java/sql/Statement.java b/jdk/src/share/classes/java/sql/Statement.java index 88684a79a57ca385a80ac23081df02ce2bed8695..d7f5bcfe19bcaafff2be75453d29c509f4e3c124 100644 --- a/jdk/src/share/classes/java/sql/Statement.java +++ b/jdk/src/share/classes/java/sql/Statement.java @@ -1051,9 +1051,9 @@ public interface Statement extends Wrapper, AutoCloseable { /** * Returns a value indicating whether this {@code Statement} will be - * closed when all dependent objects such as resultsets are closed. + * closed when all its dependent result sets are closed. * @return {@code true} if the {@code Statement} will be closed when all - * of its dependent objects are closed; {@code false} otherwise + * of its dependent result sets are closed; {@code false} otherwise * @throws SQLException if this method is called on a closed * {@code Statement} * @since 1.7 diff --git a/jdk/src/share/classes/java/util/Locale.java b/jdk/src/share/classes/java/util/Locale.java index 49b85866ed32dedec295cf541c5b467d24998ef8..1043c8792c426bd292f1939b988051344c602ca0 100644 --- a/jdk/src/share/classes/java/util/Locale.java +++ b/jdk/src/share/classes/java/util/Locale.java @@ -569,6 +569,9 @@ public final class Locale implements Cloneable, Serializable { * @exception NullPointerException thrown if any argument is null. */ public Locale(String language, String country, String variant) { + if (language== null || country == null || variant == null) { + throw new NullPointerException(); + } _baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant); _extensions = getCompatibilityExtensions(language, "", country, variant); } diff --git a/jdk/src/share/classes/java/util/ResourceBundle.java b/jdk/src/share/classes/java/util/ResourceBundle.java index e645fe91439aefd4bcdeb38afc59488e2d5e9b22..9fbdbe1626d2d7df3763ef266c1b748716c8ccfe 100644 --- a/jdk/src/share/classes/java/util/ResourceBundle.java +++ b/jdk/src/share/classes/java/util/ResourceBundle.java @@ -292,16 +292,6 @@ public abstract class ResourceBundle { private static final ConcurrentMap cacheList = new ConcurrentHashMap(INITIAL_CACHE_SIZE); - /** - * This ConcurrentMap is used to keep multiple threads from loading the - * same bundle concurrently. The table entries are - * where CacheKey is the key for the bundle that is under construction - * and Thread is the thread that is constructing the bundle. - * This list is manipulated in findBundleInCache and putBundleInCache. - */ - private static final ConcurrentMap underConstruction - = new ConcurrentHashMap(); - /** * Queue for reference objects referring to class loaders or bundles. */ @@ -1381,7 +1371,7 @@ public abstract class ResourceBundle { boolean expiredBundle = false; // First, look up the cache to see if it's in the cache, without - // declaring beginLoading. + // attempting to load bundle. cacheKey.setLocale(targetLocale); ResourceBundle bundle = findBundleInCache(cacheKey, control); if (isValidBundle(bundle)) { @@ -1408,56 +1398,25 @@ public abstract class ResourceBundle { CacheKey constKey = (CacheKey) cacheKey.clone(); try { - // Try declaring loading. If beginLoading() returns true, - // then we can proceed. Otherwise, we need to take a look - // at the cache again to see if someone else has loaded - // the bundle and put it in the cache while we've been - // waiting for other loading work to complete. - while (!beginLoading(constKey)) { - bundle = findBundleInCache(cacheKey, control); - if (bundle == null) { - continue; - } - if (bundle == NONEXISTENT_BUNDLE) { - // If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist. - return parent; - } - expiredBundle = bundle.expired; - if (!expiredBundle) { - if (bundle.parent == parent) { - return bundle; - } - BundleReference bundleRef = cacheList.get(cacheKey); - if (bundleRef != null && bundleRef.get() == bundle) { - cacheList.remove(cacheKey, bundleRef); - } + bundle = loadBundle(cacheKey, formats, control, expiredBundle); + if (bundle != null) { + if (bundle.parent == null) { + bundle.setParent(parent); } + bundle.locale = targetLocale; + bundle = putBundleInCache(cacheKey, bundle, control); + return bundle; } - try { - bundle = loadBundle(cacheKey, formats, control, expiredBundle); - if (bundle != null) { - if (bundle.parent == null) { - bundle.setParent(parent); - } - bundle.locale = targetLocale; - bundle = putBundleInCache(cacheKey, bundle, control); - return bundle; - } - - // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle - // instance for the locale. - putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control); - } finally { - endLoading(constKey); - } + // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle + // instance for the locale. + putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control); } finally { if (constKey.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); } } } - assert underConstruction.get(cacheKey) != Thread.currentThread(); return parent; } @@ -1465,7 +1424,6 @@ public abstract class ResourceBundle { List formats, Control control, boolean reload) { - assert underConstruction.get(cacheKey) == Thread.currentThread(); // Here we actually load the bundle in the order of formats // specified by the getFormats() value. @@ -1498,7 +1456,6 @@ public abstract class ResourceBundle { break; } } - assert underConstruction.get(cacheKey) == Thread.currentThread(); return bundle; } @@ -1529,57 +1486,6 @@ public abstract class ResourceBundle { return true; } - /** - * Declares the beginning of actual resource bundle loading. This method - * returns true if the declaration is successful and the current thread has - * been put in underConstruction. If someone else has already begun - * loading, this method waits until that loading work is complete and - * returns false. - */ - private static final boolean beginLoading(CacheKey constKey) { - Thread me = Thread.currentThread(); - Thread worker; - // We need to declare by putting the current Thread (me) to - // underConstruction that we are working on loading the specified - // resource bundle. If we are already working the loading, it means - // that the resource loading requires a recursive call. In that case, - // we have to proceed. (4300693) - if (((worker = underConstruction.putIfAbsent(constKey, me)) == null) - || worker == me) { - return true; - } - - // If someone else is working on the loading, wait until - // the Thread finishes the bundle loading. - synchronized (worker) { - while (underConstruction.get(constKey) == worker) { - try { - worker.wait(); - } catch (InterruptedException e) { - // record the interruption - constKey.setCause(e); - } - } - } - return false; - } - - /** - * Declares the end of the bundle loading. This method calls notifyAll - * for those who are waiting for this completion. - */ - private static final void endLoading(CacheKey constKey) { - // Remove this Thread from the underConstruction map and wake up - // those who have been waiting for me to complete this bundle - // loading. - Thread me = Thread.currentThread(); - assert (underConstruction.get(constKey) == me); - underConstruction.remove(constKey); - synchronized (me) { - me.notifyAll(); - } - } - /** * Throw a MissingResourceException with proper message */ diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java new file mode 100644 index 0000000000000000000000000000000000000000..4837661a4416028e8a3e5a12a98150b8f1229be0 --- /dev/null +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -0,0 +1,1445 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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 file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea and Martin Buchholz with assistance from members of + * JCP JSR-166 Expert Group and released to the public domain, as explained + * at http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +import java.util.AbstractCollection; +import java.util.ArrayList; +import java.util.Collection; +import java.util.ConcurrentModificationException; +import java.util.Deque; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Queue; + +/** + * An unbounded concurrent {@linkplain Deque deque} based on linked nodes. + * Concurrent insertion, removal, and access operations execute safely + * across multiple threads. + * A {@code ConcurrentLinkedDeque} is an appropriate choice when + * many threads will share access to a common collection. + * Like most other concurrent collection implementations, this class + * does not permit the use of {@code null} elements. + * + *

Iterators are weakly consistent, returning elements + * reflecting the state of the deque at some point at or since the + * creation of the iterator. They do not throw {@link + * java.util.ConcurrentModificationException + * ConcurrentModificationException}, and may proceed concurrently with + * other operations. + * + *

Beware that, unlike in most collections, the {@code size} + * method is NOT a constant-time operation. Because of the + * asynchronous nature of these deques, determining the current number + * of elements requires a traversal of the elements. + * + *

This class and its iterator implement all of the optional + * methods of the {@link Deque} and {@link Iterator} interfaces. + * + *

Memory consistency effects: As with other concurrent collections, + * actions in a thread prior to placing an object into a + * {@code ConcurrentLinkedDeque} + * happen-before + * actions subsequent to the access or removal of that element from + * the {@code ConcurrentLinkedDeque} in another thread. + * + *

This class is a member of the + * + * Java Collections Framework. + * + * @since 1.7 + * @author Doug Lea + * @author Martin Buchholz + * @param the type of elements held in this collection + */ + +public class ConcurrentLinkedDeque + extends AbstractCollection + implements Deque, java.io.Serializable { + + /* + * This is an implementation of a concurrent lock-free deque + * supporting interior removes but not interior insertions, as + * required to support the entire Deque interface. + * + * We extend the techniques developed for ConcurrentLinkedQueue and + * LinkedTransferQueue (see the internal docs for those classes). + * Understanding the ConcurrentLinkedQueue implementation is a + * prerequisite for understanding the implementation of this class. + * + * The data structure is a symmetrical doubly-linked "GC-robust" + * linked list of nodes. We minimize the number of volatile writes + * using two techniques: advancing multiple hops with a single CAS + * and mixing volatile and non-volatile writes of the same memory + * locations. + * + * A node contains the expected E ("item") and links to predecessor + * ("prev") and successor ("next") nodes: + * + * class Node { volatile Node prev, next; volatile E item; } + * + * A node p is considered "live" if it contains a non-null item + * (p.item != null). When an item is CASed to null, the item is + * atomically logically deleted from the collection. + * + * At any time, there is precisely one "first" node with a null + * prev reference that terminates any chain of prev references + * starting at a live node. Similarly there is precisely one + * "last" node terminating any chain of next references starting at + * a live node. The "first" and "last" nodes may or may not be live. + * The "first" and "last" nodes are always mutually reachable. + * + * A new element is added atomically by CASing the null prev or + * next reference in the first or last node to a fresh node + * containing the element. The element's node atomically becomes + * "live" at that point. + * + * A node is considered "active" if it is a live node, or the + * first or last node. Active nodes cannot be unlinked. + * + * A "self-link" is a next or prev reference that is the same node: + * p.prev == p or p.next == p + * Self-links are used in the node unlinking process. Active nodes + * never have self-links. + * + * A node p is active if and only if: + * + * p.item != null || + * (p.prev == null && p.next != p) || + * (p.next == null && p.prev != p) + * + * The deque object has two node references, "head" and "tail". + * The head and tail are only approximations to the first and last + * nodes of the deque. The first node can always be found by + * following prev pointers from head; likewise for tail. However, + * it is permissible for head and tail to be referring to deleted + * nodes that have been unlinked and so may not be reachable from + * any live node. + * + * There are 3 stages of node deletion; + * "logical deletion", "unlinking", and "gc-unlinking". + * + * 1. "logical deletion" by CASing item to null atomically removes + * the element from the collection, and makes the containing node + * eligible for unlinking. + * + * 2. "unlinking" makes a deleted node unreachable from active + * nodes, and thus eventually reclaimable by GC. Unlinked nodes + * may remain reachable indefinitely from an iterator. + * + * Physical node unlinking is merely an optimization (albeit a + * critical one), and so can be performed at our convenience. At + * any time, the set of live nodes maintained by prev and next + * links are identical, that is, the live nodes found via next + * links from the first node is equal to the elements found via + * prev links from the last node. However, this is not true for + * nodes that have already been logically deleted - such nodes may + * be reachable in one direction only. + * + * 3. "gc-unlinking" takes unlinking further by making active + * nodes unreachable from deleted nodes, making it easier for the + * GC to reclaim future deleted nodes. This step makes the data + * structure "gc-robust", as first described in detail by Boehm + * (http://portal.acm.org/citation.cfm?doid=503272.503282). + * + * GC-unlinked nodes may remain reachable indefinitely from an + * iterator, but unlike unlinked nodes, are never reachable from + * head or tail. + * + * Making the data structure GC-robust will eliminate the risk of + * unbounded memory retention with conservative GCs and is likely + * to improve performance with generational GCs. + * + * When a node is dequeued at either end, e.g. via poll(), we would + * like to break any references from the node to active nodes. We + * develop further the use of self-links that was very effective in + * other concurrent collection classes. The idea is to replace + * prev and next pointers with special values that are interpreted + * to mean off-the-list-at-one-end. These are approximations, but + * good enough to preserve the properties we want in our + * traversals, e.g. we guarantee that a traversal will never visit + * the same element twice, but we don't guarantee whether a + * traversal that runs out of elements will be able to see more + * elements later after enqueues at that end. Doing gc-unlinking + * safely is particularly tricky, since any node can be in use + * indefinitely (for example by an iterator). We must ensure that + * the nodes pointed at by head/tail never get gc-unlinked, since + * head/tail are needed to get "back on track" by other nodes that + * are gc-unlinked. gc-unlinking accounts for much of the + * implementation complexity. + * + * Since neither unlinking nor gc-unlinking are necessary for + * correctness, there are many implementation choices regarding + * frequency (eagerness) of these operations. Since volatile + * reads are likely to be much cheaper than CASes, saving CASes by + * unlinking multiple adjacent nodes at a time may be a win. + * gc-unlinking can be performed rarely and still be effective, + * since it is most important that long chains of deleted nodes + * are occasionally broken. + * + * The actual representation we use is that p.next == p means to + * goto the first node (which in turn is reached by following prev + * pointers from head), and p.next == null && p.prev == p means + * that the iteration is at an end and that p is a (final static) + * dummy node, NEXT_TERMINATOR, and not the last active node. + * Finishing the iteration when encountering such a TERMINATOR is + * good enough for read-only traversals, so such traversals can use + * p.next == null as the termination condition. When we need to + * find the last (active) node, for enqueueing a new node, we need + * to check whether we have reached a TERMINATOR node; if so, + * restart traversal from tail. + * + * The implementation is completely directionally symmetrical, + * except that most public methods that iterate through the list + * follow next pointers ("forward" direction). + * + * We believe (without full proof) that all single-element deque + * operations (e.g., addFirst, peekLast, pollLast) are linearizable + * (see Herlihy and Shavit's book). However, some combinations of + * operations are known not to be linearizable. In particular, + * when an addFirst(A) is racing with pollFirst() removing B, it is + * possible for an observer iterating over the elements to observe + * A B C and subsequently observe A C, even though no interior + * removes are ever performed. Nevertheless, iterators behave + * reasonably, providing the "weakly consistent" guarantees. + * + * Empirically, microbenchmarks suggest that this class adds about + * 40% overhead relative to ConcurrentLinkedQueue, which feels as + * good as we can hope for. + */ + + private static final long serialVersionUID = 876323262645176354L; + + /** + * A node from which the first node on list (that is, the unique node p + * with p.prev == null && p.next != p) can be reached in O(1) time. + * Invariants: + * - the first node is always O(1) reachable from head via prev links + * - all live nodes are reachable from the first node via succ() + * - head != null + * - (tmp = head).next != tmp || tmp != head + * - head is never gc-unlinked (but may be unlinked) + * Non-invariants: + * - head.item may or may not be null + * - head may not be reachable from the first or last node, or from tail + */ + private transient volatile Node head; + + /** + * A node from which the last node on list (that is, the unique node p + * with p.next == null && p.prev != p) can be reached in O(1) time. + * Invariants: + * - the last node is always O(1) reachable from tail via next links + * - all live nodes are reachable from the last node via pred() + * - tail != null + * - tail is never gc-unlinked (but may be unlinked) + * Non-invariants: + * - tail.item may or may not be null + * - tail may not be reachable from the first or last node, or from head + */ + private transient volatile Node tail; + + private final static Node PREV_TERMINATOR, NEXT_TERMINATOR; + + static { + PREV_TERMINATOR = new Node(null); + PREV_TERMINATOR.next = PREV_TERMINATOR; + NEXT_TERMINATOR = new Node(null); + NEXT_TERMINATOR.prev = NEXT_TERMINATOR; + } + + @SuppressWarnings("unchecked") + Node prevTerminator() { + return (Node) PREV_TERMINATOR; + } + + @SuppressWarnings("unchecked") + Node nextTerminator() { + return (Node) NEXT_TERMINATOR; + } + + static final class Node { + volatile Node prev; + volatile E item; + volatile Node next; + + /** + * Constructs a new node. Uses relaxed write because item can + * only be seen after publication via casNext or casPrev. + */ + Node(E item) { + UNSAFE.putObject(this, itemOffset, item); + } + + boolean casItem(E cmp, E val) { + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val); + } + + void lazySetNext(Node val) { + UNSAFE.putOrderedObject(this, nextOffset, val); + } + + boolean casNext(Node cmp, Node val) { + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); + } + + void lazySetPrev(Node val) { + UNSAFE.putOrderedObject(this, prevOffset, val); + } + + boolean casPrev(Node cmp, Node val) { + return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val); + } + + // Unsafe mechanics + + private static final sun.misc.Unsafe UNSAFE = + sun.misc.Unsafe.getUnsafe(); + private static final long prevOffset = + objectFieldOffset(UNSAFE, "prev", Node.class); + private static final long itemOffset = + objectFieldOffset(UNSAFE, "item", Node.class); + private static final long nextOffset = + objectFieldOffset(UNSAFE, "next", Node.class); + } + + /** + * Links e as first element. + */ + private void linkFirst(E e) { + checkNotNull(e); + final Node newNode = new Node(e); + + restartFromHead: + for (;;) + for (Node h = head, p = h, q;;) { + if ((q = p.prev) != null && + (q = (p = q).prev) != null) + // Check for head updates every other hop. + // If p == q, we are sure to follow head instead. + p = (h != (h = head)) ? h : q; + else if (p.next == p) // PREV_TERMINATOR + continue restartFromHead; + else { + // p is first node + newNode.lazySetNext(p); // CAS piggyback + if (p.casPrev(null, newNode)) { + // Successful CAS is the linearization point + // for e to become an element of this deque, + // and for newNode to become "live". + if (p != h) // hop two nodes at a time + casHead(h, newNode); // Failure is OK. + return; + } + // Lost CAS race to another thread; re-read prev + } + } + } + + /** + * Links e as last element. + */ + private void linkLast(E e) { + checkNotNull(e); + final Node newNode = new Node(e); + + restartFromTail: + for (;;) + for (Node t = tail, p = t, q;;) { + if ((q = p.next) != null && + (q = (p = q).next) != null) + // Check for tail updates every other hop. + // If p == q, we are sure to follow tail instead. + p = (t != (t = tail)) ? t : q; + else if (p.prev == p) // NEXT_TERMINATOR + continue restartFromTail; + else { + // p is last node + newNode.lazySetPrev(p); // CAS piggyback + if (p.casNext(null, newNode)) { + // Successful CAS is the linearization point + // for e to become an element of this deque, + // and for newNode to become "live". + if (p != t) // hop two nodes at a time + casTail(t, newNode); // Failure is OK. + return; + } + // Lost CAS race to another thread; re-read next + } + } + } + + private final static int HOPS = 2; + + /** + * Unlinks non-null node x. + */ + void unlink(Node x) { + // assert x != null; + // assert x.item == null; + // assert x != PREV_TERMINATOR; + // assert x != NEXT_TERMINATOR; + + final Node prev = x.prev; + final Node next = x.next; + if (prev == null) { + unlinkFirst(x, next); + } else if (next == null) { + unlinkLast(x, prev); + } else { + // Unlink interior node. + // + // This is the common case, since a series of polls at the + // same end will be "interior" removes, except perhaps for + // the first one, since end nodes cannot be unlinked. + // + // At any time, all active nodes are mutually reachable by + // following a sequence of either next or prev pointers. + // + // Our strategy is to find the unique active predecessor + // and successor of x. Try to fix up their links so that + // they point to each other, leaving x unreachable from + // active nodes. If successful, and if x has no live + // predecessor/successor, we additionally try to gc-unlink, + // leaving active nodes unreachable from x, by rechecking + // that the status of predecessor and successor are + // unchanged and ensuring that x is not reachable from + // tail/head, before setting x's prev/next links to their + // logical approximate replacements, self/TERMINATOR. + Node activePred, activeSucc; + boolean isFirst, isLast; + int hops = 1; + + // Find active predecessor + for (Node p = prev; ; ++hops) { + if (p.item != null) { + activePred = p; + isFirst = false; + break; + } + Node q = p.prev; + if (q == null) { + if (p.next == p) + return; + activePred = p; + isFirst = true; + break; + } + else if (p == q) + return; + else + p = q; + } + + // Find active successor + for (Node p = next; ; ++hops) { + if (p.item != null) { + activeSucc = p; + isLast = false; + break; + } + Node q = p.next; + if (q == null) { + if (p.prev == p) + return; + activeSucc = p; + isLast = true; + break; + } + else if (p == q) + return; + else + p = q; + } + + // TODO: better HOP heuristics + if (hops < HOPS + // always squeeze out interior deleted nodes + && (isFirst | isLast)) + return; + + // Squeeze out deleted nodes between activePred and + // activeSucc, including x. + skipDeletedSuccessors(activePred); + skipDeletedPredecessors(activeSucc); + + // Try to gc-unlink, if possible + if ((isFirst | isLast) && + + // Recheck expected state of predecessor and successor + (activePred.next == activeSucc) && + (activeSucc.prev == activePred) && + (isFirst ? activePred.prev == null : activePred.item != null) && + (isLast ? activeSucc.next == null : activeSucc.item != null)) { + + updateHead(); // Ensure x is not reachable from head + updateTail(); // Ensure x is not reachable from tail + + // Finally, actually gc-unlink + x.lazySetPrev(isFirst ? prevTerminator() : x); + x.lazySetNext(isLast ? nextTerminator() : x); + } + } + } + + /** + * Unlinks non-null first node. + */ + private void unlinkFirst(Node first, Node next) { + // assert first != null; + // assert next != null; + // assert first.item == null; + for (Node o = null, p = next, q;;) { + if (p.item != null || (q = p.next) == null) { + if (o != null && p.prev != p && first.casNext(next, p)) { + skipDeletedPredecessors(p); + if (first.prev == null && + (p.next == null || p.item != null) && + p.prev == first) { + + updateHead(); // Ensure o is not reachable from head + updateTail(); // Ensure o is not reachable from tail + + // Finally, actually gc-unlink + o.lazySetNext(o); + o.lazySetPrev(prevTerminator()); + } + } + return; + } + else if (p == q) + return; + else { + o = p; + p = q; + } + } + } + + /** + * Unlinks non-null last node. + */ + private void unlinkLast(Node last, Node prev) { + // assert last != null; + // assert prev != null; + // assert last.item == null; + for (Node o = null, p = prev, q;;) { + if (p.item != null || (q = p.prev) == null) { + if (o != null && p.next != p && last.casPrev(prev, p)) { + skipDeletedSuccessors(p); + if (last.next == null && + (p.prev == null || p.item != null) && + p.next == last) { + + updateHead(); // Ensure o is not reachable from head + updateTail(); // Ensure o is not reachable from tail + + // Finally, actually gc-unlink + o.lazySetPrev(o); + o.lazySetNext(nextTerminator()); + } + } + return; + } + else if (p == q) + return; + else { + o = p; + p = q; + } + } + } + + /** + * Guarantees that any node which was unlinked before a call to + * this method will be unreachable from head after it returns. + * Does not guarantee to eliminate slack, only that head will + * point to a node that was active while this method was running. + */ + private final void updateHead() { + // Either head already points to an active node, or we keep + // trying to cas it to the first node until it does. + Node h, p, q; + restartFromHead: + while ((h = head).item == null && (p = h.prev) != null) { + for (;;) { + if ((q = p.prev) == null || + (q = (p = q).prev) == null) { + // It is possible that p is PREV_TERMINATOR, + // but if so, the CAS is guaranteed to fail. + if (casHead(h, p)) + return; + else + continue restartFromHead; + } + else if (h != head) + continue restartFromHead; + else + p = q; + } + } + } + + /** + * Guarantees that any node which was unlinked before a call to + * this method will be unreachable from tail after it returns. + * Does not guarantee to eliminate slack, only that tail will + * point to a node that was active while this method was running. + */ + private final void updateTail() { + // Either tail already points to an active node, or we keep + // trying to cas it to the last node until it does. + Node t, p, q; + restartFromTail: + while ((t = tail).item == null && (p = t.next) != null) { + for (;;) { + if ((q = p.next) == null || + (q = (p = q).next) == null) { + // It is possible that p is NEXT_TERMINATOR, + // but if so, the CAS is guaranteed to fail. + if (casTail(t, p)) + return; + else + continue restartFromTail; + } + else if (t != tail) + continue restartFromTail; + else + p = q; + } + } + } + + private void skipDeletedPredecessors(Node x) { + whileActive: + do { + Node prev = x.prev; + // assert prev != null; + // assert x != NEXT_TERMINATOR; + // assert x != PREV_TERMINATOR; + Node p = prev; + findActive: + for (;;) { + if (p.item != null) + break findActive; + Node q = p.prev; + if (q == null) { + if (p.next == p) + continue whileActive; + break findActive; + } + else if (p == q) + continue whileActive; + else + p = q; + } + + // found active CAS target + if (prev == p || x.casPrev(prev, p)) + return; + + } while (x.item != null || x.next == null); + } + + private void skipDeletedSuccessors(Node x) { + whileActive: + do { + Node next = x.next; + // assert next != null; + // assert x != NEXT_TERMINATOR; + // assert x != PREV_TERMINATOR; + Node p = next; + findActive: + for (;;) { + if (p.item != null) + break findActive; + Node q = p.next; + if (q == null) { + if (p.prev == p) + continue whileActive; + break findActive; + } + else if (p == q) + continue whileActive; + else + p = q; + } + + // found active CAS target + if (next == p || x.casNext(next, p)) + return; + + } while (x.item != null || x.prev == null); + } + + /** + * Returns the successor of p, or the first node if p.next has been + * linked to self, which will only be true if traversing with a + * stale pointer that is now off the list. + */ + final Node succ(Node p) { + // TODO: should we skip deleted nodes here? + Node q = p.next; + return (p == q) ? first() : q; + } + + /** + * Returns the predecessor of p, or the last node if p.prev has been + * linked to self, which will only be true if traversing with a + * stale pointer that is now off the list. + */ + final Node pred(Node p) { + Node q = p.prev; + return (p == q) ? last() : q; + } + + /** + * Returns the first node, the unique node p for which: + * p.prev == null && p.next != p + * The returned node may or may not be logically deleted. + * Guarantees that head is set to the returned node. + */ + Node first() { + restartFromHead: + for (;;) + for (Node h = head, p = h, q;;) { + if ((q = p.prev) != null && + (q = (p = q).prev) != null) + // Check for head updates every other hop. + // If p == q, we are sure to follow head instead. + p = (h != (h = head)) ? h : q; + else if (p == h + // It is possible that p is PREV_TERMINATOR, + // but if so, the CAS is guaranteed to fail. + || casHead(h, p)) + return p; + else + continue restartFromHead; + } + } + + /** + * Returns the last node, the unique node p for which: + * p.next == null && p.prev != p + * The returned node may or may not be logically deleted. + * Guarantees that tail is set to the returned node. + */ + Node last() { + restartFromTail: + for (;;) + for (Node t = tail, p = t, q;;) { + if ((q = p.next) != null && + (q = (p = q).next) != null) + // Check for tail updates every other hop. + // If p == q, we are sure to follow tail instead. + p = (t != (t = tail)) ? t : q; + else if (p == t + // It is possible that p is NEXT_TERMINATOR, + // but if so, the CAS is guaranteed to fail. + || casTail(t, p)) + return p; + else + continue restartFromTail; + } + } + + // Minor convenience utilities + + /** + * Throws NullPointerException if argument is null. + * + * @param v the element + */ + private static void checkNotNull(Object v) { + if (v == null) + throw new NullPointerException(); + } + + /** + * Returns element unless it is null, in which case throws + * NoSuchElementException. + * + * @param v the element + * @return the element + */ + private E screenNullResult(E v) { + if (v == null) + throw new NoSuchElementException(); + return v; + } + + /** + * Creates an array list and fills it with elements of this list. + * Used by toArray. + * + * @return the arrayList + */ + private ArrayList toArrayList() { + ArrayList list = new ArrayList(); + for (Node p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null) + list.add(item); + } + return list; + } + + /** + * Constructs an empty deque. + */ + public ConcurrentLinkedDeque() { + head = tail = new Node(null); + } + + /** + * Constructs a deque initially containing the elements of + * the given collection, added in traversal order of the + * collection's iterator. + * + * @param c the collection of elements to initially contain + * @throws NullPointerException if the specified collection or any + * of its elements are null + */ + public ConcurrentLinkedDeque(Collection c) { + // Copy c into a private chain of Nodes + Node h = null, t = null; + for (E e : c) { + checkNotNull(e); + Node newNode = new Node(e); + if (h == null) + h = t = newNode; + else { + t.lazySetNext(newNode); + newNode.lazySetPrev(t); + t = newNode; + } + } + initHeadTail(h, t); + } + + /** + * Initializes head and tail, ensuring invariants hold. + */ + private void initHeadTail(Node h, Node t) { + if (h == t) { + if (h == null) + h = t = new Node(null); + else { + // Avoid edge case of a single Node with non-null item. + Node newNode = new Node(null); + t.lazySetNext(newNode); + newNode.lazySetPrev(t); + t = newNode; + } + } + head = h; + tail = t; + } + + /** + * Inserts the specified element at the front of this deque. + * + * @throws NullPointerException {@inheritDoc} + */ + public void addFirst(E e) { + linkFirst(e); + } + + /** + * Inserts the specified element at the end of this deque. + * + *

This method is equivalent to {@link #add}. + * + * @throws NullPointerException {@inheritDoc} + */ + public void addLast(E e) { + linkLast(e); + } + + /** + * Inserts the specified element at the front of this deque. + * + * @return {@code true} always + * @throws NullPointerException {@inheritDoc} + */ + public boolean offerFirst(E e) { + linkFirst(e); + return true; + } + + /** + * Inserts the specified element at the end of this deque. + * + *

This method is equivalent to {@link #add}. + * + * @return {@code true} always + * @throws NullPointerException {@inheritDoc} + */ + public boolean offerLast(E e) { + linkLast(e); + return true; + } + + public E peekFirst() { + for (Node p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null) + return item; + } + return null; + } + + public E peekLast() { + for (Node p = last(); p != null; p = pred(p)) { + E item = p.item; + if (item != null) + return item; + } + return null; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E getFirst() { + return screenNullResult(peekFirst()); + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E getLast() { + return screenNullResult(peekLast()); + } + + public E pollFirst() { + for (Node p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null && p.casItem(item, null)) { + unlink(p); + return item; + } + } + return null; + } + + public E pollLast() { + for (Node p = last(); p != null; p = pred(p)) { + E item = p.item; + if (item != null && p.casItem(item, null)) { + unlink(p); + return item; + } + } + return null; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E removeFirst() { + return screenNullResult(pollFirst()); + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E removeLast() { + return screenNullResult(pollLast()); + } + + // *** Queue and stack methods *** + + /** + * Inserts the specified element at the tail of this deque. + * + * @return {@code true} (as specified by {@link Queue#offer}) + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + return offerLast(e); + } + + /** + * Inserts the specified element at the tail of this deque. + * + * @return {@code true} (as specified by {@link Collection#add}) + * @throws NullPointerException if the specified element is null + */ + public boolean add(E e) { + return offerLast(e); + } + + public E poll() { return pollFirst(); } + public E remove() { return removeFirst(); } + public E peek() { return peekFirst(); } + public E element() { return getFirst(); } + public void push(E e) { addFirst(e); } + public E pop() { return removeFirst(); } + + /** + * Removes the first element {@code e} such that + * {@code o.equals(e)}, if such an element exists in this deque. + * If the deque does not contain the element, it is unchanged. + * + * @param o element to be removed from this deque, if present + * @return {@code true} if the deque contained the specified element + * @throws NullPointerException if the specified element is {@code null} + */ + public boolean removeFirstOccurrence(Object o) { + checkNotNull(o); + for (Node p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null && o.equals(item) && p.casItem(item, null)) { + unlink(p); + return true; + } + } + return false; + } + + /** + * Removes the last element {@code e} such that + * {@code o.equals(e)}, if such an element exists in this deque. + * If the deque does not contain the element, it is unchanged. + * + * @param o element to be removed from this deque, if present + * @return {@code true} if the deque contained the specified element + * @throws NullPointerException if the specified element is {@code null} + */ + public boolean removeLastOccurrence(Object o) { + checkNotNull(o); + for (Node p = last(); p != null; p = pred(p)) { + E item = p.item; + if (item != null && o.equals(item) && p.casItem(item, null)) { + unlink(p); + return true; + } + } + return false; + } + + /** + * Returns {@code true} if this deque contains at least one + * element {@code e} such that {@code o.equals(e)}. + * + * @param o element whose presence in this deque is to be tested + * @return {@code true} if this deque contains the specified element + */ + public boolean contains(Object o) { + if (o == null) return false; + for (Node p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null && o.equals(item)) + return true; + } + return false; + } + + /** + * Returns {@code true} if this collection contains no elements. + * + * @return {@code true} if this collection contains no elements + */ + public boolean isEmpty() { + return peekFirst() == null; + } + + /** + * Returns the number of elements in this deque. If this deque + * contains more than {@code Integer.MAX_VALUE} elements, it + * returns {@code Integer.MAX_VALUE}. + * + *

Beware that, unlike in most collections, this method is + * NOT a constant-time operation. Because of the + * asynchronous nature of these deques, determining the current + * number of elements requires traversing them all to count them. + * Additionally, it is possible for the size to change during + * execution of this method, in which case the returned result + * will be inaccurate. Thus, this method is typically not very + * useful in concurrent applications. + * + * @return the number of elements in this deque + */ + public int size() { + int count = 0; + for (Node p = first(); p != null; p = succ(p)) + if (p.item != null) + // Collection.size() spec says to max out + if (++count == Integer.MAX_VALUE) + break; + return count; + } + + /** + * Removes the first element {@code e} such that + * {@code o.equals(e)}, if such an element exists in this deque. + * If the deque does not contain the element, it is unchanged. + * + * @param o element to be removed from this deque, if present + * @return {@code true} if the deque contained the specified element + * @throws NullPointerException if the specified element is {@code null} + */ + public boolean remove(Object o) { + return removeFirstOccurrence(o); + } + + /** + * Appends all of the elements in the specified collection to the end of + * this deque, in the order that they are returned by the specified + * collection's iterator. Attempts to {@code addAll} of a deque to + * itself result in {@code IllegalArgumentException}. + * + * @param c the elements to be inserted into this deque + * @return {@code true} if this deque changed as a result of the call + * @throws NullPointerException if the specified collection or any + * of its elements are null + * @throws IllegalArgumentException if the collection is this deque + */ + public boolean addAll(Collection c) { + if (c == this) + // As historically specified in AbstractQueue#addAll + throw new IllegalArgumentException(); + + // Copy c into a private chain of Nodes + Node beginningOfTheEnd = null, last = null; + for (E e : c) { + checkNotNull(e); + Node newNode = new Node(e); + if (beginningOfTheEnd == null) + beginningOfTheEnd = last = newNode; + else { + last.lazySetNext(newNode); + newNode.lazySetPrev(last); + last = newNode; + } + } + if (beginningOfTheEnd == null) + return false; + + // Atomically append the chain at the tail of this collection + restartFromTail: + for (;;) + for (Node t = tail, p = t, q;;) { + if ((q = p.next) != null && + (q = (p = q).next) != null) + // Check for tail updates every other hop. + // If p == q, we are sure to follow tail instead. + p = (t != (t = tail)) ? t : q; + else if (p.prev == p) // NEXT_TERMINATOR + continue restartFromTail; + else { + // p is last node + beginningOfTheEnd.lazySetPrev(p); // CAS piggyback + if (p.casNext(null, beginningOfTheEnd)) { + // Successful CAS is the linearization point + // for all elements to be added to this queue. + if (!casTail(t, last)) { + // Try a little harder to update tail, + // since we may be adding many elements. + t = tail; + if (last.next == null) + casTail(t, last); + } + return true; + } + // Lost CAS race to another thread; re-read next + } + } + } + + /** + * Removes all of the elements from this deque. + */ + public void clear() { + while (pollFirst() != null) + ; + } + + /** + * Returns an array containing all of the elements in this deque, in + * proper sequence (from first to last element). + * + *

The returned array will be "safe" in that no references to it are + * maintained by this deque. (In other words, this method must allocate + * a new array). The caller is thus free to modify the returned array. + * + *

This method acts as bridge between array-based and collection-based + * APIs. + * + * @return an array containing all of the elements in this deque + */ + public Object[] toArray() { + return toArrayList().toArray(); + } + + /** + * Returns an array containing all of the elements in this deque, + * in proper sequence (from first to last element); the runtime + * type of the returned array is that of the specified array. If + * the deque fits in the specified array, it is returned therein. + * Otherwise, a new array is allocated with the runtime type of + * the specified array and the size of this deque. + * + *

If this deque fits in the specified array with room to spare + * (i.e., the array has more elements than this deque), the element in + * the array immediately following the end of the deque is set to + * {@code null}. + * + *

Like the {@link #toArray()} method, this method acts as + * bridge between array-based and collection-based APIs. Further, + * this method allows precise control over the runtime type of the + * output array, and may, under certain circumstances, be used to + * save allocation costs. + * + *

Suppose {@code x} is a deque known to contain only strings. + * The following code can be used to dump the deque into a newly + * allocated array of {@code String}: + * + *

+     *     String[] y = x.toArray(new String[0]);
+ * + * Note that {@code toArray(new Object[0])} is identical in function to + * {@code toArray()}. + * + * @param a the array into which the elements of the deque are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose + * @return an array containing all of the elements in this deque + * @throws ArrayStoreException if the runtime type of the specified array + * is not a supertype of the runtime type of every element in + * this deque + * @throws NullPointerException if the specified array is null + */ + public T[] toArray(T[] a) { + return toArrayList().toArray(a); + } + + /** + * Returns an iterator over the elements in this deque in proper sequence. + * The elements will be returned in order from first (head) to last (tail). + * + *

The returned {@code Iterator} is a "weakly consistent" iterator that + * will never throw {@link java.util.ConcurrentModificationException + * ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * @return an iterator over the elements in this deque in proper sequence + */ + public Iterator iterator() { + return new Itr(); + } + + /** + * Returns an iterator over the elements in this deque in reverse + * sequential order. The elements will be returned in order from + * last (tail) to first (head). + * + *

The returned {@code Iterator} is a "weakly consistent" iterator that + * will never throw {@link java.util.ConcurrentModificationException + * ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * @return an iterator over the elements in this deque in reverse order + */ + public Iterator descendingIterator() { + return new DescendingItr(); + } + + private abstract class AbstractItr implements Iterator { + /** + * Next node to return item for. + */ + private Node nextNode; + + /** + * nextItem holds on to item fields because once we claim + * that an element exists in hasNext(), we must return it in + * the following next() call even if it was in the process of + * being removed when hasNext() was called. + */ + private E nextItem; + + /** + * Node returned by most recent call to next. Needed by remove. + * Reset to null if this element is deleted by a call to remove. + */ + private Node lastRet; + + abstract Node startNode(); + abstract Node nextNode(Node p); + + AbstractItr() { + advance(); + } + + /** + * Sets nextNode and nextItem to next valid node, or to null + * if no such. + */ + private void advance() { + lastRet = nextNode; + + Node p = (nextNode == null) ? startNode() : nextNode(nextNode); + for (;; p = nextNode(p)) { + if (p == null) { + // p might be active end or TERMINATOR node; both are OK + nextNode = null; + nextItem = null; + break; + } + E item = p.item; + if (item != null) { + nextNode = p; + nextItem = item; + break; + } + } + } + + public boolean hasNext() { + return nextItem != null; + } + + public E next() { + E item = nextItem; + if (item == null) throw new NoSuchElementException(); + advance(); + return item; + } + + public void remove() { + Node l = lastRet; + if (l == null) throw new IllegalStateException(); + l.item = null; + unlink(l); + lastRet = null; + } + } + + /** Forward iterator */ + private class Itr extends AbstractItr { + Node startNode() { return first(); } + Node nextNode(Node p) { return succ(p); } + } + + /** Descending iterator */ + private class DescendingItr extends AbstractItr { + Node startNode() { return last(); } + Node nextNode(Node p) { return pred(p); } + } + + /** + * Saves the state to a stream (that is, serializes it). + * + * @serialData All of the elements (each an {@code E}) in + * the proper order, followed by a null + * @param s the stream + */ + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + + // Write out any hidden stuff + s.defaultWriteObject(); + + // Write out all elements in the proper order. + for (Node p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null) + s.writeObject(item); + } + + // Use trailing null as sentinel + s.writeObject(null); + } + + /** + * Reconstitutes the instance from a stream (that is, deserializes it). + * @param s the stream + */ + private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); + + // Read in elements until trailing null sentinel found + Node h = null, t = null; + Object item; + while ((item = s.readObject()) != null) { + @SuppressWarnings("unchecked") + Node newNode = new Node((E) item); + if (h == null) + h = t = newNode; + else { + t.lazySetNext(newNode); + newNode.lazySetPrev(t); + t = newNode; + } + } + initHeadTail(h, t); + } + + // Unsafe mechanics + + private static final sun.misc.Unsafe UNSAFE = + sun.misc.Unsafe.getUnsafe(); + private static final long headOffset = + objectFieldOffset(UNSAFE, "head", ConcurrentLinkedDeque.class); + private static final long tailOffset = + objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedDeque.class); + + private boolean casHead(Node cmp, Node val) { + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); + } + + private boolean casTail(Node cmp, Node val) { + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val); + } + + static long objectFieldOffset(sun.misc.Unsafe UNSAFE, + String field, Class klazz) { + try { + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); + } catch (NoSuchFieldException e) { + // Convert Exception to corresponding Error + NoSuchFieldError error = new NoSuchFieldError(field); + error.initCause(e); + throw error; + } + } +} diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 081d18eeef0ad1769a3b42f113b7fa1d6198d468..0d6381cd971e7c632f914a6aed936dee63a2fd36 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -28,9 +28,9 @@ * However, the following notice accompanied the original version of this * file: * - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain + * Written by Doug Lea and Martin Buchholz with assistance from members of + * JCP JSR-166 Expert Group and released to the public domain, as explained + * at http://creativecommons.org/licenses/publicdomain */ package java.util.concurrent; @@ -53,7 +53,8 @@ import java.util.Queue; * operations obtain elements at the head of the queue. * A {@code ConcurrentLinkedQueue} is an appropriate choice when * many threads will share access to a common collection. - * This queue does not permit {@code null} elements. + * Like most other concurrent collection implementations, this class + * does not permit the use of {@code null} elements. * *

This implementation employs an efficient "wait-free" * algorithm based on one described in by Maged M. Michael and Michael L. Scott. * + *

Iterators are weakly consistent, returning elements + * reflecting the state of the queue at some point at or since the + * creation of the iterator. They do not throw {@link + * ConcurrentModificationException}, and may proceed concurrently with + * other operations. Elements contained in the queue since the creation + * of the iterator will be returned exactly once. + * *

Beware that, unlike in most collections, the {@code size} method * is NOT a constant-time operation. Because of the * asynchronous nature of these queues, determining the current number * of elements requires a traversal of the elements. * - *

This class and its iterator implement all of the - * optional methods of the {@link Collection} and {@link - * Iterator} interfaces. + *

This class and its iterator implement all of the optional + * methods of the {@link Queue} and {@link Iterator} interfaces. * *

Memory consistency effects: As with other concurrent * collections, actions in a thread prior to placing an object into a @@ -132,9 +139,10 @@ public class ConcurrentLinkedQueue extends AbstractQueue * * Both head and tail are permitted to lag. In fact, failing to * update them every time one could is a significant optimization - * (fewer CASes). This is controlled by local "hops" variables - * that only trigger helping-CASes after experiencing multiple - * lags. + * (fewer CASes). As with LinkedTransferQueue (see the internal + * documentation for that class), we use a slack threshold of two; + * that is, we update head/tail when the current pointer appears + * to be two or more steps away from the first/last node. * * Since head and tail are updated concurrently and independently, * it is possible for tail to lag behind head (why not)? @@ -148,8 +156,8 @@ public class ConcurrentLinkedQueue extends AbstractQueue * this is merely an optimization. * * When constructing a Node (before enqueuing it) we avoid paying - * for a volatile write to item by using lazySet instead of a - * normal write. This allows the cost of enqueue to be + * for a volatile write to item by using Unsafe.putObject instead + * of a normal write. This allows the cost of enqueue to be * "one-and-a-half" CASes. * * Both head and tail may or may not point to a Node with a @@ -161,38 +169,25 @@ public class ConcurrentLinkedQueue extends AbstractQueue */ private static class Node { - private volatile E item; - private volatile Node next; + volatile E item; + volatile Node next; + /** + * Constructs a new node. Uses relaxed write because item can + * only be seen after publication via casNext. + */ Node(E item) { - // Piggyback on imminent casNext() - lazySetItem(item); - } - - E getItem() { - return item; + UNSAFE.putObject(this, itemOffset, item); } boolean casItem(E cmp, E val) { return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val); } - void setItem(E val) { - item = val; - } - - void lazySetItem(E val) { - UNSAFE.putOrderedObject(this, itemOffset, val); - } - void lazySetNext(Node val) { UNSAFE.putOrderedObject(this, nextOffset, val); } - Node getNext() { - return next; - } - boolean casNext(Node cmp, Node val) { return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); } @@ -219,7 +214,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue * - it is permitted for tail to lag behind head, that is, for tail * to not be reachable from head! */ - private transient volatile Node head = new Node(null); + private transient volatile Node head; /** * A node from which the last node on list (that is, the unique @@ -233,25 +228,41 @@ public class ConcurrentLinkedQueue extends AbstractQueue * to not be reachable from head! * - tail.next may or may not be self-pointing to tail. */ - private transient volatile Node tail = head; + private transient volatile Node tail; /** * Creates a {@code ConcurrentLinkedQueue} that is initially empty. */ - public ConcurrentLinkedQueue() {} + public ConcurrentLinkedQueue() { + head = tail = new Node(null); + } /** * Creates a {@code ConcurrentLinkedQueue} * initially containing the elements of the given collection, * added in traversal order of the collection's iterator. + * * @param c the collection of elements to initially contain * @throws NullPointerException if the specified collection or any * of its elements are null */ public ConcurrentLinkedQueue(Collection c) { - for (E e : c) - add(e); + Node h = null, t = null; + for (E e : c) { + checkNotNull(e); + Node newNode = new Node(e); + if (h == null) + h = t = newNode; + else { + t.lazySetNext(newNode); + t = newNode; + } + } + if (h == null) + h = t = new Node(null); + head = h; + tail = t; } // Have to override just to update the javadoc @@ -266,13 +277,6 @@ public class ConcurrentLinkedQueue extends AbstractQueue return offer(e); } - /** - * We don't bother to update head or tail pointers if fewer than - * HOPS links from "true" location. We assume that volatile - * writes are significantly more expensive than volatile reads. - */ - private static final int HOPS = 1; - /** * Try to CAS head to p. If successful, repoint old head to itself * as sentinel for succ(), below. @@ -288,7 +292,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue * stale pointer that is now off the list. */ final Node succ(Node p) { - Node next = p.getNext(); + Node next = p.next; return (p == next) ? head : next; } @@ -299,68 +303,75 @@ public class ConcurrentLinkedQueue extends AbstractQueue * @throws NullPointerException if the specified element is null */ public boolean offer(E e) { - if (e == null) throw new NullPointerException(); - Node n = new Node(e); - retry: - for (;;) { - Node t = tail; - Node p = t; - for (int hops = 0; ; hops++) { - Node next = succ(p); - if (next != null) { - if (hops > HOPS && t != tail) - continue retry; - p = next; - } else if (p.casNext(null, n)) { - if (hops >= HOPS) - casTail(t, n); // Failure is OK. + checkNotNull(e); + final Node newNode = new Node(e); + + for (Node t = tail, p = t;;) { + Node q = p.next; + if (q == null) { + // p is last node + if (p.casNext(null, newNode)) { + // Successful CAS is the linearization point + // for e to become an element of this queue, + // and for newNode to become "live". + if (p != t) // hop two nodes at a time + casTail(t, newNode); // Failure is OK. return true; - } else { - p = succ(p); } + // Lost CAS race to another thread; re-read next } + else if (p == q) + // We have fallen off list. If tail is unchanged, it + // will also be off-list, in which case we need to + // jump to head, from which all live nodes are always + // reachable. Else the new tail is a better bet. + p = (t != (t = tail)) ? t : head; + else + // Check for tail updates after two hops. + p = (p != t && t != (t = tail)) ? t : q; } } public E poll() { - Node h = head; - Node p = h; - for (int hops = 0; ; hops++) { - E item = p.getItem(); - - if (item != null && p.casItem(item, null)) { - if (hops >= HOPS) { - Node q = p.getNext(); - updateHead(h, (q != null) ? q : p); + restartFromHead: + for (;;) { + for (Node h = head, p = h, q;;) { + E item = p.item; + + if (item != null && p.casItem(item, null)) { + // Successful CAS is the linearization point + // for item to be removed from this queue. + if (p != h) // hop two nodes at a time + updateHead(h, ((q = p.next) != null) ? q : p); + return item; } - return item; - } - Node next = succ(p); - if (next == null) { - updateHead(h, p); - break; + else if ((q = p.next) == null) { + updateHead(h, p); + return null; + } + else if (p == q) + continue restartFromHead; + else + p = q; } - p = next; } - return null; } public E peek() { - Node h = head; - Node p = h; - E item; + restartFromHead: for (;;) { - item = p.getItem(); - if (item != null) - break; - Node next = succ(p); - if (next == null) { - break; + for (Node h = head, p = h, q;;) { + E item = p.item; + if (item != null || (q = p.next) == null) { + updateHead(h, p); + return item; + } + else if (p == q) + continue restartFromHead; + else + p = q; } - p = next; } - updateHead(h, p); - return item; } /** @@ -372,24 +383,20 @@ public class ConcurrentLinkedQueue extends AbstractQueue * of losing a race to a concurrent poll(). */ Node first() { - Node h = head; - Node p = h; - Node result; + restartFromHead: for (;;) { - E item = p.getItem(); - if (item != null) { - result = p; - break; - } - Node next = succ(p); - if (next == null) { - result = null; - break; + for (Node h = head, p = h, q;;) { + boolean hasItem = (p.item != null); + if (hasItem || (q = p.next) == null) { + updateHead(h, p); + return hasItem ? p : null; + } + else if (p == q) + continue restartFromHead; + else + p = q; } - p = next; } - updateHead(h, p); - return result; } /** @@ -410,18 +417,20 @@ public class ConcurrentLinkedQueue extends AbstractQueue * NOT a constant-time operation. Because of the * asynchronous nature of these queues, determining the current * number of elements requires an O(n) traversal. + * Additionally, if elements are added or removed during execution + * of this method, the returned result may be inaccurate. Thus, + * this method is typically not very useful in concurrent + * applications. * * @return the number of elements in this queue */ public int size() { int count = 0; - for (Node p = first(); p != null; p = succ(p)) { - if (p.getItem() != null) { - // Collections.size() spec says to max out + for (Node p = first(); p != null; p = succ(p)) + if (p.item != null) + // Collection.size() spec says to max out if (++count == Integer.MAX_VALUE) break; - } - } return count; } @@ -436,9 +445,8 @@ public class ConcurrentLinkedQueue extends AbstractQueue public boolean contains(Object o) { if (o == null) return false; for (Node p = first(); p != null; p = succ(p)) { - E item = p.getItem(); - if (item != null && - o.equals(item)) + E item = p.item; + if (item != null && o.equals(item)) return true; } return false; @@ -459,7 +467,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue if (o == null) return false; Node pred = null; for (Node p = first(); p != null; p = succ(p)) { - E item = p.getItem(); + E item = p.item; if (item != null && o.equals(item) && p.casItem(item, null)) { @@ -473,6 +481,69 @@ public class ConcurrentLinkedQueue extends AbstractQueue return false; } + /** + * Appends all of the elements in the specified collection to the end of + * this queue, in the order that they are returned by the specified + * collection's iterator. Attempts to {@code addAll} of a queue to + * itself result in {@code IllegalArgumentException}. + * + * @param c the elements to be inserted into this queue + * @return {@code true} if this queue changed as a result of the call + * @throws NullPointerException if the specified collection or any + * of its elements are null + * @throws IllegalArgumentException if the collection is this queue + */ + public boolean addAll(Collection c) { + if (c == this) + // As historically specified in AbstractQueue#addAll + throw new IllegalArgumentException(); + + // Copy c into a private chain of Nodes + Node beginningOfTheEnd = null, last = null; + for (E e : c) { + checkNotNull(e); + Node newNode = new Node(e); + if (beginningOfTheEnd == null) + beginningOfTheEnd = last = newNode; + else { + last.lazySetNext(newNode); + last = newNode; + } + } + if (beginningOfTheEnd == null) + return false; + + // Atomically append the chain at the tail of this collection + for (Node t = tail, p = t;;) { + Node q = p.next; + if (q == null) { + // p is last node + if (p.casNext(null, beginningOfTheEnd)) { + // Successful CAS is the linearization point + // for all elements to be added to this queue. + if (!casTail(t, last)) { + // Try a little harder to update tail, + // since we may be adding many elements. + t = tail; + if (last.next == null) + casTail(t, last); + } + return true; + } + // Lost CAS race to another thread; re-read next + } + else if (p == q) + // We have fallen off list. If tail is unchanged, it + // will also be off-list, in which case we need to + // jump to head, from which all live nodes are always + // reachable. Else the new tail is a better bet. + p = (t != (t = tail)) ? t : head; + else + // Check for tail updates after two hops. + p = (p != t && t != (t = tail)) ? t : q; + } + } + /** * Returns an array containing all of the elements in this queue, in * proper sequence. @@ -490,7 +561,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue // Use ArrayList to deal with resizing. ArrayList al = new ArrayList(); for (Node p = first(); p != null; p = succ(p)) { - E item = p.getItem(); + E item = p.item; if (item != null) al.add(item); } @@ -539,7 +610,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue int k = 0; Node p; for (p = first(); p != null && k < a.length; p = succ(p)) { - E item = p.getItem(); + E item = p.item; if (item != null) a[k++] = (T)item; } @@ -552,7 +623,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue // If won't fit, use ArrayList version ArrayList al = new ArrayList(); for (Node q = first(); q != null; q = succ(q)) { - E item = q.getItem(); + E item = q.item; if (item != null) al.add(item); } @@ -561,7 +632,9 @@ public class ConcurrentLinkedQueue extends AbstractQueue /** * Returns an iterator over the elements in this queue in proper sequence. - * The returned iterator is a "weakly consistent" iterator that + * The elements will be returned in order from first (head) to last (tail). + * + *

The returned {@code Iterator} is a "weakly consistent" iterator that * will never throw {@link java.util.ConcurrentModificationException * ConcurrentModificationException}, * and guarantees to traverse elements as they existed upon @@ -620,7 +693,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue nextItem = null; return x; } - E item = p.getItem(); + E item = p.item; if (item != null) { nextNode = p; nextItem = item; @@ -648,13 +721,13 @@ public class ConcurrentLinkedQueue extends AbstractQueue Node l = lastRet; if (l == null) throw new IllegalStateException(); // rely on a future traversal to relink. - l.setItem(null); + l.item = null; lastRet = null; } } /** - * Save the state to a stream (that is, serialize it). + * Saves the state to a stream (that is, serializes it). * * @serialData All of the elements (each an {@code E}) in * the proper order, followed by a null @@ -668,7 +741,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue // Write out all elements in the proper order. for (Node p = first(); p != null; p = succ(p)) { - Object item = p.getItem(); + Object item = p.item; if (item != null) s.writeObject(item); } @@ -678,25 +751,40 @@ public class ConcurrentLinkedQueue extends AbstractQueue } /** - * Reconstitute the Queue instance from a stream (that is, - * deserialize it). + * Reconstitutes the instance from a stream (that is, deserializes it). * @param s the stream */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { - // Read in capacity, and any hidden stuff s.defaultReadObject(); - head = new Node(null); - tail = head; - // Read in all elements and place in queue - for (;;) { + + // Read in elements until trailing null sentinel found + Node h = null, t = null; + Object item; + while ((item = s.readObject()) != null) { @SuppressWarnings("unchecked") - E item = (E)s.readObject(); - if (item == null) - break; - else - offer(item); + Node newNode = new Node((E) item); + if (h == null) + h = t = newNode; + else { + t.lazySetNext(newNode); + t = newNode; + } } + if (h == null) + h = t = new Node(null); + head = h; + tail = t; + } + + /** + * Throws NullPointerException if argument is null. + * + * @param v the element + */ + private static void checkNotNull(Object v) { + if (v == null) + throw new NullPointerException(); } // Unsafe mechanics @@ -715,10 +803,6 @@ public class ConcurrentLinkedQueue extends AbstractQueue return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); } - private void lazySetHead(Node val) { - UNSAFE.putOrderedObject(this, headOffset, val); - } - static long objectFieldOffset(sun.misc.Unsafe UNSAFE, String field, Class klazz) { try { diff --git a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java index 122ce86737e557d4ae81c80af47c73ef83059301..263552a93ea544b7220a289f72f3355c6b7c1ddc 100644 --- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java @@ -42,7 +42,6 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.Callable; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; @@ -823,15 +822,13 @@ public class ForkJoinPool extends AbstractExecutorService { (workerCounts & RUNNING_COUNT_MASK) <= 1); long startTime = untimed? 0 : System.nanoTime(); Thread.interrupted(); // clear/ignore interrupt - if (eventCount != ec || w.runState != 0 || - runState >= TERMINATING) // recheck after clear - break; + if (eventCount != ec || w.isTerminating()) + break; // recheck after clear if (untimed) LockSupport.park(w); else { LockSupport.parkNanos(w, SHRINK_RATE_NANOS); - if (eventCount != ec || w.runState != 0 || - runState >= TERMINATING) + if (eventCount != ec || w.isTerminating()) break; if (System.nanoTime() - startTime >= SHRINK_RATE_NANOS) tryShutdownUnusedWorker(ec); @@ -899,16 +896,23 @@ public class ForkJoinPool extends AbstractExecutorService { UNSAFE.compareAndSwapInt(this, workerCountsOffset, wc, wc + (ONE_RUNNING|ONE_TOTAL))) { ForkJoinWorkerThread w = null; + Throwable fail = null; try { w = factory.newThread(this); - } finally { // adjust on null or exceptional factory return - if (w == null) { - decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL); - tryTerminate(false); // handle failure during shutdown - } + } catch (Throwable ex) { + fail = ex; } - if (w == null) + if (w == null) { // null or exceptional factory return + decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL); + tryTerminate(false); // handle failure during shutdown + // If originating from an external caller, + // propagate exception, else ignore + if (fail != null && runState < TERMINATING && + !(Thread.currentThread() instanceof + ForkJoinWorkerThread)) + UNSAFE.throwException(fail); break; + } w.start(recordWorker(w), ueh); if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc) { int c; // advance event count @@ -997,8 +1001,12 @@ public class ForkJoinPool extends AbstractExecutorService { boolean active = w.active; boolean inactivate = false; int pc = parallelism; - int rs; - while (w.runState == 0 && (rs = runState) < TERMINATING) { + while (w.runState == 0) { + int rs = runState; + if (rs >= TERMINATING) { // propagate shutdown + w.shutdown(); + break; + } if ((inactivate || (active && (rs & ACTIVE_COUNT_MASK) >= pc)) && UNSAFE.compareAndSwapInt(this, runStateOffset, rs, rs - 1)) inactivate = active = w.active = false; @@ -1126,6 +1134,7 @@ public class ForkJoinPool extends AbstractExecutorService { return true; } + /** * Actions on transition to TERMINATING * @@ -1149,7 +1158,7 @@ public class ForkJoinPool extends AbstractExecutorService { if (passes > 0 && !w.isTerminated()) { w.cancelTasks(); LockSupport.unpark(w); - if (passes > 1) { + if (passes > 1 && !w.isInterrupted()) { try { w.interrupt(); } catch (SecurityException ignore) { @@ -1725,6 +1734,13 @@ public class ForkJoinPool extends AbstractExecutorService { return (runState & (TERMINATING|TERMINATED)) == TERMINATING; } + /** + * Returns true if terminating or terminated. Used by ForkJoinWorkerThread. + */ + final boolean isAtLeastTerminating() { + return runState >= TERMINATING; + } + /** * Returns {@code true} if this pool has been shut down. * diff --git a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java index 598578f0cf1e7189584e6a8fe85d81f445c1cd38..cd18360f83da6f3e4a5e2ba725975c4bc663514a 100644 --- a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java @@ -55,10 +55,10 @@ import java.util.WeakHashMap; * start other subtasks. As indicated by the name of this class, * many programs using {@code ForkJoinTask} employ only methods * {@link #fork} and {@link #join}, or derivatives such as {@link - * #invokeAll}. However, this class also provides a number of other - * methods that can come into play in advanced usages, as well as - * extension mechanics that allow support of new forms of fork/join - * processing. + * #invokeAll(ForkJoinTask...) invokeAll}. However, this class also + * provides a number of other methods that can come into play in + * advanced usages, as well as extension mechanics that allow + * support of new forms of fork/join processing. * *

A {@code ForkJoinTask} is a lightweight form of {@link Future}. * The efficiency of {@code ForkJoinTask}s stems from a set of @@ -250,7 +250,7 @@ public abstract class ForkJoinTask implements Future, Serializable { int s; // the odd construction reduces lock bias effects while ((s = status) >= 0) { try { - synchronized(this) { + synchronized (this) { if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL)) wait(); } @@ -270,7 +270,7 @@ public abstract class ForkJoinTask implements Future, Serializable { int s; if ((s = status) >= 0) { try { - synchronized(this) { + synchronized (this) { if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL)) wait(millis, 0); } @@ -288,7 +288,7 @@ public abstract class ForkJoinTask implements Future, Serializable { private void externalAwaitDone() { int s; while ((s = status) >= 0) { - synchronized(this) { + synchronized (this) { if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)){ boolean interrupted = false; while (status >= 0) { @@ -669,11 +669,34 @@ public abstract class ForkJoinTask implements Future, Serializable { setCompletion(NORMAL); } + /** + * Waits if necessary for the computation to complete, and then + * retrieves its result. + * + * @return the computed result + * @throws CancellationException if the computation was cancelled + * @throws ExecutionException if the computation threw an + * exception + * @throws InterruptedException if the current thread is not a + * member of a ForkJoinPool and was interrupted while waiting + */ public final V get() throws InterruptedException, ExecutionException { - quietlyJoin(); - if (Thread.interrupted()) - throw new InterruptedException(); - int s = status; + int s; + if (Thread.currentThread() instanceof ForkJoinWorkerThread) { + quietlyJoin(); + s = status; + } + else { + while ((s = status) >= 0) { + synchronized (this) { // interruptible form of awaitDone + if (UNSAFE.compareAndSwapInt(this, statusOffset, + s, SIGNAL)) { + while (status >= 0) + wait(); + } + } + } + } if (s < NORMAL) { Throwable ex; if (s == CANCELLED) @@ -684,6 +707,20 @@ public abstract class ForkJoinTask implements Future, Serializable { return getRawResult(); } + /** + * Waits if necessary for at most the given time for the computation + * to complete, and then retrieves its result, if available. + * + * @param timeout the maximum time to wait + * @param unit the time unit of the timeout argument + * @return the computed result + * @throws CancellationException if the computation was cancelled + * @throws ExecutionException if the computation threw an + * exception + * @throws InterruptedException if the current thread is not a + * member of a ForkJoinPool and was interrupted while waiting + * @throws TimeoutException if the wait timed out + */ public final V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { Thread t = Thread.currentThread(); @@ -725,7 +762,7 @@ public abstract class ForkJoinTask implements Future, Serializable { long ms = nt / 1000000; int ns = (int) (nt % 1000000); try { - synchronized(this) { + synchronized (this) { if (status >= 0) wait(ms, ns); } diff --git a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java index 784dd8056bca302cd9724cea05b8e78c92464d29..4dcfbbd571c55cfdead8edf85afa1a5f0151a01d 100644 --- a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java @@ -778,11 +778,20 @@ public class ForkJoinWorkerThread extends Thread { // status check methods used mainly by ForkJoinPool final boolean isRunning() { return runState == 0; } - final boolean isTerminating() { return (runState & TERMINATING) != 0; } final boolean isTerminated() { return (runState & TERMINATED) != 0; } final boolean isSuspended() { return (runState & SUSPENDED) != 0; } final boolean isTrimmed() { return (runState & TRIMMED) != 0; } + final boolean isTerminating() { + if ((runState & TERMINATING) != 0) + return true; + if (pool.isAtLeastTerminating()) { // propagate pool state + shutdown(); + return true; + } + return false; + } + /** * Sets state to TERMINATING. Does NOT unpark or interrupt * to wake up if currently blocked. Callers must do so if desired. diff --git a/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java b/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java index f703f8c570217e4afffb763e54e405583f199ff8..40bcc88f0f8fe4a29fa48d8dd514b74a6ecdb5ff 100644 --- a/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java +++ b/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java @@ -138,7 +138,7 @@ package java.util.concurrent; * if (right.tryUnfork()) // directly calculate if not stolen * sum += right.atLeaf(right.lo, right.hi); * else { - * right.helpJoin(); + * right.join(); * sum += right.result; * } * right = right.next; diff --git a/jdk/src/share/classes/java/util/logging/LogManager.java b/jdk/src/share/classes/java/util/logging/LogManager.java index 00f2d7c5e2fe5aed99b61cbc3e273a6fa41c37be..ed577bf0fa372a04d11ace84c0d498eec183b63c 100644 --- a/jdk/src/share/classes/java/util/logging/LogManager.java +++ b/jdk/src/share/classes/java/util/logging/LogManager.java @@ -690,6 +690,11 @@ public class LogManager { * Note that since untrusted code may create loggers with * arbitrary names this method should not be relied on to * find Loggers for security sensitive logging. + * It is also important to note that the Logger associated with the + * String {@code name} may be garbage collected at any time if there + * is no strong reference to the Logger. The caller of this method + * must check the return value for null in order to properly handle + * the case where the Logger has been garbage collected. *

* @param name name of the logger * @return matching logger or null if none is found @@ -713,6 +718,14 @@ public class LogManager { *

* Note: Loggers may be added dynamically as new classes are loaded. * This method only reports on the loggers that are currently registered. + * It is also important to note that this method only returns the name + * of a Logger, not a strong reference to the Logger itself. + * The returned String does nothing to prevent the Logger from being + * garbage collected. In particular, if the returned name is passed + * to {@code LogManager.getLogger()}, then the caller must check the + * return value from {@code LogManager.getLogger()} for null to properly + * handle the case where the Logger has been garbage collected in the + * time since its name was returned by this method. *

* @return enumeration of logger name strings */ diff --git a/jdk/src/share/classes/java/util/logging/Logger.java b/jdk/src/share/classes/java/util/logging/Logger.java index 234c09c0a8c25c215ab628d83e1be6569d780d64..72aade97a3f0b047bf646753c7ad709ae3f207b4 100644 --- a/jdk/src/share/classes/java/util/logging/Logger.java +++ b/jdk/src/share/classes/java/util/logging/Logger.java @@ -42,7 +42,10 @@ import java.lang.ref.WeakReference; *

* Logger objects may be obtained by calls on one of the getLogger * factory methods. These will either create a new Logger or - * return a suitable existing Logger. + * return a suitable existing Logger. It is important to note that + * the Logger returned by one of the {@code getLogger} factory methods + * may be garbage collected at any time if a strong reference to the + * Logger is not kept. *

* Logging messages will be forwarded to registered Handler * objects, which can forward the messages to a variety of @@ -210,7 +213,9 @@ public class Logger { * who are making serious use of the logging package (for example * in products) should create and use their own Logger objects, * with appropriate names, so that logging can be controlled on a - * suitable per-Logger granularity. + * suitable per-Logger granularity. Developers also need to keep a + * strong reference to their Logger objects to prevent them from + * being garbage collected. *

* @deprecated Initialization of this field is prone to deadlocks. * The field must be initialized by the Logger class initialization @@ -287,6 +292,15 @@ public class Logger { * based on the LogManager configuration and it will configured * to also send logging output to its parent's Handlers. It will * be registered in the LogManager global namespace. + *

+ * Note: The LogManager may only retain a weak reference to the newly + * created Logger. It is important to understand that a previously + * created Logger with the given name may be garbage collected at any + * time if there is no strong reference to the Logger. In particular, + * this means that two back-to-back calls like + * {@code getLogger("MyLogger").log(...)} may use different Logger + * objects named "MyLogger" if there is no strong reference to the + * Logger named "MyLogger" elsewhere in the program. * * @param name A name for the logger. This should * be a dot-separated name and should normally @@ -311,6 +325,15 @@ public class Logger { * output to its parent's Handlers. It will be registered in * the LogManager global namespace. *

+ * Note: The LogManager may only retain a weak reference to the newly + * created Logger. It is important to understand that a previously + * created Logger with the given name may be garbage collected at any + * time if there is no strong reference to the Logger. In particular, + * this means that two back-to-back calls like + * {@code getLogger("MyLogger", ...).log(...)} may use different Logger + * objects named "MyLogger" if there is no strong reference to the + * Logger named "MyLogger" elsewhere in the program. + *

* If the named Logger already exists and does not yet have a * localization resource bundle then the given resource bundle * name is used. If the named Logger already exists and has diff --git a/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java b/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java index ea6de394eab74e36f9c2638bf21180aeabe23f93..92f103254a68a733430f926618b047f47a47dbb4 100644 --- a/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java +++ b/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -734,7 +734,7 @@ public static final int ASCII_STREAM_PARAM = 2; throw new SQLException("Set initParams() before setCommand"); } params.clear(); - command = new String(cmd); + command = cmd; } } @@ -797,7 +797,7 @@ public static final int ASCII_STREAM_PARAM = 2; throw new SQLException("Invalid url string detected. " + "Cannot be of length less than 1"); } else { - URL = new String(url); + URL = url; } dataSource = null; @@ -854,7 +854,7 @@ public static final int ASCII_STREAM_PARAM = 2; } else if (name.equals("")) { throw new SQLException("DataSource name cannot be empty string"); } else { - dataSource = new String(name); + dataSource = name; } URL = null; @@ -889,7 +889,7 @@ public static final int ASCII_STREAM_PARAM = 2; { username = null; } else { - username = new String(name); + username = name; } } @@ -924,7 +924,7 @@ public static final int ASCII_STREAM_PARAM = 2; { password = null; } else { - password = new String(pass); + password = pass; } } @@ -1563,13 +1563,13 @@ public static final int ASCII_STREAM_PARAM = 2; nullVal = new Object[2]; nullVal[0] = null; - nullVal[1] = new Integer(sqlType); + nullVal[1] = Integer.valueOf(sqlType); if (params == null){ throw new SQLException("Set initParams() before setNull"); } - params.put(new Integer(parameterIndex - 1), nullVal); + params.put(Integer.valueOf(parameterIndex - 1), nullVal); } /** @@ -1644,14 +1644,14 @@ public static final int ASCII_STREAM_PARAM = 2; nullVal = new Object[3]; nullVal[0] = null; - nullVal[1] = new Integer(sqlType); - nullVal[2] = new String(typeName); + nullVal[1] = Integer.valueOf(sqlType); + nullVal[2] = typeName; if(params == null){ throw new SQLException("Set initParams() before setNull"); } - params.put(new Integer(parameterIndex - 1), nullVal); + params.put(Integer.valueOf(parameterIndex - 1), nullVal); } @@ -1686,7 +1686,7 @@ public static final int ASCII_STREAM_PARAM = 2; throw new SQLException("Set initParams() before setNull"); } - params.put(new Integer(parameterIndex - 1), new Boolean(x)); + params.put(Integer.valueOf(parameterIndex - 1), Boolean.valueOf(x)); } /** @@ -1720,7 +1720,7 @@ public static final int ASCII_STREAM_PARAM = 2; throw new SQLException("Set initParams() before setByte"); } - params.put(new Integer(parameterIndex - 1), new Byte(x)); + params.put(Integer.valueOf(parameterIndex - 1), Byte.valueOf(x)); } /** @@ -1754,7 +1754,7 @@ public static final int ASCII_STREAM_PARAM = 2; throw new SQLException("Set initParams() before setShort"); } - params.put(new Integer(parameterIndex - 1), new Short(x)); + params.put(Integer.valueOf(parameterIndex - 1), Short.valueOf(x)); } /** @@ -1786,7 +1786,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setInt"); } - params.put(new Integer(parameterIndex - 1), new Integer(x)); + params.put(Integer.valueOf(parameterIndex - 1), Integer.valueOf(x)); } /** @@ -1818,7 +1818,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setLong"); } - params.put(new Integer(parameterIndex - 1), new Long(x)); + params.put(Integer.valueOf(parameterIndex - 1), Long.valueOf(x)); } /** @@ -1850,7 +1850,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setFloat"); } - params.put(new Integer(parameterIndex - 1), new Float(x)); + params.put(Integer.valueOf(parameterIndex - 1), new Float(x)); } /** @@ -1882,7 +1882,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setDouble"); } - params.put(new Integer(parameterIndex - 1), new Double(x)); + params.put(Integer.valueOf(parameterIndex - 1), new Double(x)); } /** @@ -1914,7 +1914,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setBigDecimal"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -1948,7 +1948,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setString"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -1982,7 +1982,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setBytes"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -2024,7 +2024,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setDate"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -2069,7 +2069,7 @@ public static final int ASCII_STREAM_PARAM = 2; throw new SQLException("Set initParams() before setTime"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -2112,7 +2112,7 @@ public static final int ASCII_STREAM_PARAM = 2; throw new SQLException("Set initParams() before setTimestamp"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -2185,14 +2185,14 @@ public static final int ASCII_STREAM_PARAM = 2; asciiStream = new Object[3]; asciiStream[0] = x; - asciiStream[1] = new Integer(length); - asciiStream[2] = new Integer(ASCII_STREAM_PARAM); + asciiStream[1] = Integer.valueOf(length); + asciiStream[2] = Integer.valueOf(ASCII_STREAM_PARAM); if(params == null){ throw new SQLException("Set initParams() before setAsciiStream"); } - params.put(new Integer(parameterIndex - 1), asciiStream); + params.put(Integer.valueOf(parameterIndex - 1), asciiStream); } /** @@ -2290,13 +2290,13 @@ public static final int ASCII_STREAM_PARAM = 2; binaryStream = new Object[3]; binaryStream[0] = x; - binaryStream[1] = new Integer(length); - binaryStream[2] = new Integer(BINARY_STREAM_PARAM); + binaryStream[1] = Integer.valueOf(length); + binaryStream[2] = Integer.valueOf(BINARY_STREAM_PARAM); if(params == null){ throw new SQLException("Set initParams() before setBinaryStream"); } - params.put(new Integer(parameterIndex - 1), binaryStream); + params.put(Integer.valueOf(parameterIndex - 1), binaryStream); } @@ -2396,12 +2396,12 @@ public static final int ASCII_STREAM_PARAM = 2; unicodeStream = new Object[3]; unicodeStream[0] = x; - unicodeStream[1] = new Integer(length); - unicodeStream[2] = new Integer(UNICODE_STREAM_PARAM); + unicodeStream[1] = Integer.valueOf(length); + unicodeStream[2] = Integer.valueOf(UNICODE_STREAM_PARAM); if(params == null){ throw new SQLException("Set initParams() before setUnicodeStream"); } - params.put(new Integer(parameterIndex - 1), unicodeStream); + params.put(Integer.valueOf(parameterIndex - 1), unicodeStream); } /** @@ -2475,11 +2475,11 @@ public static final int ASCII_STREAM_PARAM = 2; charStream = new Object[2]; charStream[0] = reader; - charStream[1] = new Integer(length); + charStream[1] = Integer.valueOf(length); if(params == null){ throw new SQLException("Set initParams() before setCharacterStream"); } - params.put(new Integer(parameterIndex - 1), charStream); + params.put(Integer.valueOf(parameterIndex - 1), charStream); } /** @@ -2591,12 +2591,12 @@ public static final int ASCII_STREAM_PARAM = 2; obj = new Object[3]; obj[0] = x; - obj[1] = new Integer(targetSqlType); - obj[2] = new Integer(scale); + obj[1] = Integer.valueOf(targetSqlType); + obj[2] = Integer.valueOf(scale); if(params == null){ throw new SQLException("Set initParams() before setObject"); } - params.put(new Integer(parameterIndex - 1), obj); + params.put(Integer.valueOf(parameterIndex - 1), obj); } /** @@ -2654,11 +2654,11 @@ public static final int ASCII_STREAM_PARAM = 2; obj = new Object[2]; obj[0] = x; - obj[1] = new Integer(targetSqlType); + obj[1] = Integer.valueOf(targetSqlType); if (params == null){ throw new SQLException("Set initParams() before setObject"); } - params.put(new Integer(parameterIndex - 1), obj); + params.put(Integer.valueOf(parameterIndex - 1), obj); } /** @@ -2726,7 +2726,7 @@ public static final int ASCII_STREAM_PARAM = 2; if (params == null) { throw new SQLException("Set initParams() before setObject"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -2773,7 +2773,7 @@ public static final int ASCII_STREAM_PARAM = 2; if (params == null) { throw new SQLException("Set initParams() before setRef"); } - params.put(new Integer(parameterIndex - 1), new SerialRef(ref)); + params.put(Integer.valueOf(parameterIndex - 1), new SerialRef(ref)); } /** @@ -2817,7 +2817,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setBlob"); } - params.put(new Integer(parameterIndex - 1), new SerialBlob(x)); + params.put(Integer.valueOf(parameterIndex - 1), new SerialBlob(x)); } /** @@ -2862,7 +2862,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setClob"); } - params.put(new Integer(parameterIndex - 1), new SerialClob(x)); + params.put(Integer.valueOf(parameterIndex - 1), new SerialClob(x)); } /** @@ -2910,7 +2910,7 @@ public static final int ASCII_STREAM_PARAM = 2; if (params == null){ throw new SQLException("Set initParams() before setArray"); } - params.put(new Integer(parameterIndex - 1), new SerialArray(array)); + params.put(Integer.valueOf(parameterIndex - 1), new SerialArray(array)); } /** @@ -2975,7 +2975,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setDate"); } - params.put(new Integer(parameterIndex - 1), date); + params.put(Integer.valueOf(parameterIndex - 1), date); } /** @@ -3041,7 +3041,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setTime"); } - params.put(new Integer(parameterIndex - 1), time); + params.put(Integer.valueOf(parameterIndex - 1), time); } /** @@ -3107,7 +3107,7 @@ public static final int ASCII_STREAM_PARAM = 2; if(params == null){ throw new SQLException("Set initParams() before setTimestamp"); } - params.put(new Integer(parameterIndex - 1), timestamp); + params.put(Integer.valueOf(parameterIndex - 1), timestamp); } /** @@ -3181,7 +3181,7 @@ public static final int ASCII_STREAM_PARAM = 2; Object[] paramsArray = new Object[params.size()]; for (int i = 0; i < params.size(); i++) { - paramsArray[i] = params.get(new Integer(i)); + paramsArray[i] = params.get(Integer.valueOf(i)); if (paramsArray[i] == null) { throw new SQLException("missing parameter: " + (i + 1)); } //end if diff --git a/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java b/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java index 2a60bb3b7e7a20ecf71a3da0b7f73e228a54fcf8..7861223911bc330fdc2f1e7a958826c5f6344792 100644 --- a/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java +++ b/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java @@ -39,7 +39,7 @@ import javax.sql.rowset.spi.*; * CachedRowSet must implement. *

* The reference implementation of the CachedRowSet interface provided - * by Sun Microsystems is a standard implementation. Developers may use this implementation + * by Oracle Corporation is a standard implementation. Developers may use this implementation * just as it is, they may extend it, or they may choose to write their own implementations * of this interface. *

@@ -1623,4 +1623,3 @@ public interface CachedRowSet extends RowSet, Joinable { public boolean previousPage() throws SQLException; } - diff --git a/jdk/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java b/jdk/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java index b147c9e6bc9a61459a62edd4a8bd09982165cf19..cd18b2afd919cebce461a92cbe9e28feea9882a8 100644 --- a/jdk/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java +++ b/jdk/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -306,9 +306,9 @@ public class RowSetMetaDataImpl implements RowSetMetaData, Serializable { public void setColumnLabel(int columnIndex, String label) throws SQLException { checkColRange(columnIndex); if (label != null) { - colInfo[columnIndex].columnLabel = new String(label); + colInfo[columnIndex].columnLabel = label; } else { - colInfo[columnIndex].columnLabel = new String(""); + colInfo[columnIndex].columnLabel = ""; } } @@ -326,9 +326,9 @@ public class RowSetMetaDataImpl implements RowSetMetaData, Serializable { public void setColumnName(int columnIndex, String columnName) throws SQLException { checkColRange(columnIndex); if (columnName != null) { - colInfo[columnIndex].columnName = new String(columnName); + colInfo[columnIndex].columnName = columnName; } else { - colInfo[columnIndex].columnName = new String(""); + colInfo[columnIndex].columnName = ""; } } @@ -348,9 +348,9 @@ public class RowSetMetaDataImpl implements RowSetMetaData, Serializable { public void setSchemaName(int columnIndex, String schemaName) throws SQLException { checkColRange(columnIndex); if (schemaName != null ) { - colInfo[columnIndex].schemaName = new String(schemaName); + colInfo[columnIndex].schemaName = schemaName; } else { - colInfo[columnIndex].schemaName = new String(""); + colInfo[columnIndex].schemaName = ""; } } @@ -411,9 +411,9 @@ public class RowSetMetaDataImpl implements RowSetMetaData, Serializable { public void setTableName(int columnIndex, String tableName) throws SQLException { checkColRange(columnIndex); if (tableName != null) { - colInfo[columnIndex].tableName = new String(tableName); + colInfo[columnIndex].tableName = tableName; } else { - colInfo[columnIndex].tableName = new String(""); + colInfo[columnIndex].tableName = ""; } } @@ -432,9 +432,9 @@ public class RowSetMetaDataImpl implements RowSetMetaData, Serializable { public void setCatalogName(int columnIndex, String catalogName) throws SQLException { checkColRange(columnIndex); if (catalogName != null) - colInfo[columnIndex].catName = new String(catalogName); + colInfo[columnIndex].catName = catalogName; else - colInfo[columnIndex].catName = new String(""); + colInfo[columnIndex].catName = ""; } /** @@ -474,9 +474,9 @@ public class RowSetMetaDataImpl implements RowSetMetaData, Serializable { throws SQLException { checkColRange(columnIndex); if (typeName != null) { - colInfo[columnIndex].colTypeName = new String(typeName); + colInfo[columnIndex].colTypeName = typeName; } else { - colInfo[columnIndex].colTypeName = new String(""); + colInfo[columnIndex].colTypeName = ""; } } @@ -827,7 +827,7 @@ public class RowSetMetaDataImpl implements RowSetMetaData, Serializable { * or the given column number is out of bounds */ public String getColumnClassName(int columnIndex) throws SQLException { - String className = (new String()).getClass().getName(); + String className = String.class.getName(); int sqlType = getColumnType(columnIndex); @@ -835,65 +835,62 @@ public class RowSetMetaDataImpl implements RowSetMetaData, Serializable { case Types.NUMERIC: case Types.DECIMAL: - className = (new java.math.BigDecimal(0)).getClass().getName (); + className = java.math.BigDecimal.class.getName(); break; case Types.BIT: - className = (new Boolean(false)).getClass().getName (); + className = java.lang.Boolean.class.getName(); break; case Types.TINYINT: - className = (new Byte("0")).getClass().getName (); + className = java.lang.Byte.class.getName(); break; case Types.SMALLINT: - className = (new Short("0")).getClass().getName (); + className = java.lang.Short.class.getName(); break; case Types.INTEGER: - className = (new Integer(0)).getClass().getName (); + className = java.lang.Integer.class.getName(); break; case Types.BIGINT: - className = (new Long(0)).getClass().getName (); + className = java.lang.Long.class.getName(); break; case Types.REAL: - className = (new Float(0)).getClass().getName (); + className = java.lang.Float.class.getName(); break; case Types.FLOAT: case Types.DOUBLE: - className = (new Double(0)).getClass().getName(); + className = java.lang.Double.class.getName(); break; case Types.BINARY: case Types.VARBINARY: case Types.LONGVARBINARY: - byte[] b = {}; - className = (b.getClass()).getName(); + className = "byte[]"; break; case Types.DATE: - className = (new java.sql.Date(123456)).getClass().getName (); + className = java.sql.Date.class.getName(); break; case Types.TIME: - className = (new java.sql.Time(123456)).getClass().getName (); + className = java.sql.Time.class.getName(); break; case Types.TIMESTAMP: - className = (new java.sql.Timestamp(123456)).getClass().getName (); + className = java.sql.Timestamp.class.getName(); break; case Types.BLOB: - byte[] blob = {}; - className = (blob.getClass()).getName(); + className = java.sql.Blob.class.getName(); break; case Types.CLOB: - char[] c = {}; - className = (c.getClass()).getName(); + className = java.sql.Clob.class.getName(); break; } diff --git a/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java b/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java index 1a84161ce15af66a186c5733bf57ea9b4234879b..75875c7b576503d9486579ab55fec4e60f0cf651 100644 --- a/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java +++ b/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java @@ -29,7 +29,6 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.sql.SQLException; import java.util.ServiceLoader; -import javax.sql.rowset.RowSetFactory; /** * A factory API that enables applications to obtain a @@ -82,15 +81,15 @@ public class RowSetProvider { * the RowSetFactory implementation class to load:

*
    *
  • - * The System property {@code javax.sql.rowset.RowsetFactory}. For example: + * The System property {@code javax.sql.rowset.RowSetFactory}. For example: *
      *
    • - * -Djavax.sql.rowset.RowsetFactory=com.sun.rowset.RowSetFactoryImpl + * -Djavax.sql.rowset.RowSetFactory=com.sun.rowset.RowSetFactoryImpl *
    • *
    *
  • - * The ServiceLocator API. The ServiceLocator API will look - * for a classname in the file + * The {@link ServiceLoader} API. The {@code ServiceLoader} API will look + * for a class name in the file * {@code META-INF/services/javax.sql.rowset.RowSetFactory} * in jars available to the runtime. For example, to have the the RowSetFactory * implementation {@code com.sun.rowset.RowSetFactoryImpl } loaded, the @@ -271,7 +270,7 @@ public class RowSetProvider { /** * Returns the requested System Property. If a {@code SecurityException} * occurs, just return NULL - * @param propName - System property to retreive + * @param propName - System property to retrieve * @return The System property value or NULL if the property does not exist * or a {@code SecurityException} occurs. */ diff --git a/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java b/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java index c354c5fe7bb1e02f58a52eede7a5d5aa233f5594..abef62f1271f8175de65ac0a285e86c27fd07b34 100644 --- a/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java +++ b/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,7 +115,7 @@ import org.xml.sax.*; * <url>jdbc:thin:oracle</url> * <sync-provider> * <sync-provider-name>.com.rowset.provider.RIOptimisticProvider</sync-provider-name> - * <sync-provider-vendor>Sun Microsystems</sync-provider-vendor> + * <sync-provider-vendor>Oracle Corporation</sync-provider-vendor> * <sync-provider-version>1.0</sync-provider-name> * <sync-provider-grade>LOW</sync-provider-grade> * <data-source-lock>NONE</data-source-lock> @@ -489,7 +489,7 @@ public interface WebRowSet extends CachedRowSet { * tags and their valid values for a WebRowSet implementation. */ public static String PUBLIC_XML_SCHEMA = - "--//Sun Microsystems, Inc.//XSD Schema//EN"; + "--//Oracle Corporation//XSD Schema//EN"; /** * The URL for the XML Schema definition file that defines the XML tags and diff --git a/jdk/src/share/classes/javax/sql/rowset/rowset.properties b/jdk/src/share/classes/javax/sql/rowset/rowset.properties index 4fb38bd5242fdf7b4c7121471974aec44850443b..68dd95b0fb7a2af6a83d7330ada4d154798a7095 100644 --- a/jdk/src/share/classes/javax/sql/rowset/rowset.properties +++ b/jdk/src/share/classes/javax/sql/rowset/rowset.properties @@ -3,10 +3,10 @@ # Optimistic synchonriztaion provider rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider -rowset.provider.vendor.0=Sun Microsystems Inc +rowset.provider.vendor.0=Oracle Corporation rowset.provider.version.0=1.0 # XML Provider using standard XML schema rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider -rowset.provider.vendor.1=Sun Microsystems Inc. +rowset.provider.vendor.1=Oracle Corporation rowset.provider.version.1=1.0 diff --git a/jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java b/jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java index cba527b42f27ebb7f7c9680899e2f11b4ff330f2..7b5d8d4b867cf218f335a4501d793b21cec36d02 100644 --- a/jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,7 +137,7 @@ public class SQLOutputImpl implements SQLOutput { * values of a UDT to the database. */ public void writeBoolean(boolean x) throws SQLException { - attribs.add(new Boolean(x)); + attribs.add(Boolean.valueOf(x)); } /** @@ -151,7 +151,7 @@ public class SQLOutputImpl implements SQLOutput { * values of a UDT to the database. */ public void writeByte(byte x) throws SQLException { - attribs.add(new Byte(x)); + attribs.add(Byte.valueOf(x)); } /** @@ -165,7 +165,7 @@ public class SQLOutputImpl implements SQLOutput { * values of a UDT to the database. */ public void writeShort(short x) throws SQLException { - attribs.add(new Short(x)); + attribs.add(Short.valueOf(x)); } /** @@ -179,7 +179,7 @@ public class SQLOutputImpl implements SQLOutput { * values of a UDT to the database. */ public void writeInt(int x) throws SQLException { - attribs.add(new Integer(x)); + attribs.add(Integer.valueOf(x)); } /** @@ -193,7 +193,7 @@ public class SQLOutputImpl implements SQLOutput { * values of a UDT to the database. */ public void writeLong(long x) throws SQLException { - attribs.add(new Long(x)); + attribs.add(Long.valueOf(x)); } /** diff --git a/jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java b/jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java index e2031e3fa6a0a486ec80710ab768791ffc5edbe1..8503caaaf781384bb4c8938f07cc90822d0f383d 100644 --- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,7 @@ public class SerialRef implements Ref, Serializable, Cloneable { throw new SQLException("Cannot instantiate a SerialRef object " + "that returns a null base type name"); } else { - baseTypeName = new String(ref.getBaseTypeName()); + baseTypeName = ref.getBaseTypeName(); } } @@ -110,7 +110,7 @@ public class SerialRef implements Ref, Serializable, Cloneable { throws SerialException { map = new Hashtable(map); - if (!object.equals(null)) { + if (object != null) { return map.get(object); } else { throw new SerialException("The object is not set"); diff --git a/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java b/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java index 1abe5e9e823c1875c6548902ccb2a81a665e1f82..b546da769f4fdc83ce91e8c5104bf89c9b9be69f 100644 --- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,7 +94,7 @@ public class SerialStruct implements Struct, Serializable, Cloneable { try { // get the type name - SQLTypeName = new String(in.getSQLTypeName()); + SQLTypeName = in.getSQLTypeName(); System.out.println("SQLTypeName: " + SQLTypeName); // get the attributes of the struct @@ -137,7 +137,7 @@ public class SerialStruct implements Struct, Serializable, Cloneable { try { //set the type name - SQLTypeName = new String(in.getSQLTypeName()); + SQLTypeName = in.getSQLTypeName(); Vector tmp = new Vector(); in.writeSQL(new SQLOutputImpl(tmp, map)); @@ -247,7 +247,7 @@ public class SerialStruct implements Struct, Serializable, Cloneable { } /** - * The identifier that assists in the serialization of this + * The identifier that assists in the serialization of this * SerialStruct object. */ static final long serialVersionUID = -8322445504027483372L; diff --git a/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java b/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java index 4aec879a059b8212b6db3d23a3f45f1b416e077a..3369f466b415ffc101809532e7ce30714a332f8e 100644 --- a/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java +++ b/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java @@ -125,12 +125,12 @@ import javax.naming.*; * * # Optimistic synchronization provider * rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider - * rowset.provider.vendor.0=Sun Microsystems Inc + * rowset.provider.vendor.0=Oracle Corporation * rowset.provider.version.0=1.0 * * # XML Provider using standard XML schema * rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider - * rowset.provider.vendor.1=Sun Microsystems Inc. + * rowset.provider.vendor.1=Oracle Corporation * rowset.provider.version.1=1.0 * * The SyncFactory checks this file and registers the @@ -369,7 +369,7 @@ public class SyncFactory { try { // check if user is supplying his Synchronisation Provider - // Implementation if not use Sun's implementation. + // Implementation if not using Oracle's implementation. // properties.load(new FileInputStream(ROWSET_PROPERTIES)); // The rowset.properties needs to be in jdk/jre/lib when diff --git a/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java b/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java index 86a4bcd28e3d80c8a580e8599924bfc2af1167be..81425998889d0946c72f6fa36696757bc1c576aa 100644 --- a/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java +++ b/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java @@ -91,8 +91,8 @@ import javax.sql.*; * *

    * A vendor can register a SyncProvider implementation class name - * with Sun Microsystems, Inc. by sending email to jdbc@sun.com. - * Sun will maintain a database listing the + * with Oracle Corporation by sending email to jdbc@sun.com. + * Oracle will maintain a database listing the * available SyncProvider implementations for use with compliant * RowSet implementations. This database will be similar to the * one already maintained to list available JDBC drivers. diff --git a/jdk/src/share/classes/javax/sql/rowset/spi/package.html b/jdk/src/share/classes/javax/sql/rowset/spi/package.html index 89a84a3971515b8a8eacce238cfce044e02cf0e8..a5732719108314ebe95122770ed69243b68ea350 100644 --- a/jdk/src/share/classes/javax/sql/rowset/spi/package.html +++ b/jdk/src/share/classes/javax/sql/rowset/spi/package.html @@ -8,7 +8,7 @@