OpenJDK / jdk / jdk12
changeset 48297:48ff95f16a16
Merge
author | jwilhelm |
---|---|
date | Sat, 02 Dec 2017 06:51:10 +0100 |
parents | 3212e9bc5be7 be01bcb72309 |
children | 40b9faefb496 |
files | src/hotspot/share/prims/jvm.cpp src/java.base/share/classes/jdk/internal/util/jar/VersionedStream.java src/jdk.charsets/share/classes/sun/nio/cs/ext/MS950_HKSCS.java test/jdk/java/lang/SecurityManager/NoAWT.java test/jdk/jdk/internal/util/jar/TestVersionedStream.java test/langtools/tools/javac/doctree/dcapi/OverviewTest.java |
diffstat | 290 files changed, 10534 insertions(+), 3093 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Sat Dec 02 11:25:35 2017 +0530 +++ b/.hgtags Sat Dec 02 06:51:10 2017 +0100 @@ -458,3 +458,4 @@ e6278add9ff28fab70fe1cc4c1d65f7363dc9445 jdk-10+31 a2008587c13fa05fa2dbfcb09fe987576fbedfd1 jdk-10+32 bbd692ad4fa300ecca7939ffbe3b1d5e52a28cc6 jdk-10+33 +89deac44e51517841491ba86ff44aa82a5ca96b3 jdk-10+34
--- a/make/Bundles.gmk Sat Dec 02 11:25:35 2017 +0530 +++ b/make/Bundles.gmk Sat Dec 02 06:51:10 2017 +0100 @@ -177,7 +177,7 @@ # Create special filter rules when dealing with unzipped .dSYM directories on # macosx ifeq ($(OPENJDK_TARGET_OS), macosx) - ifeq ($(ZIP_DEBUGINFO_FILES), false) + ifeq ($(ZIP_EXTERNAL_DEBUG_SYMBOLS), false) JDK_SYMBOLS_EXCLUDE_PATTERN := $(addprefix %, \ $(call containing, .dSYM/, $(patsubst $(JDK_IMAGE_DIR)/%, %, $(ALL_JDK_FILES)))) endif @@ -212,7 +212,7 @@ # Create special filter rules when dealing with unzipped .dSYM directories on # macosx ifeq ($(OPENJDK_TARGET_OS), macosx) - ifeq ($(ZIP_DEBUGINFO_FILES), false) + ifeq ($(ZIP_EXTERNAL_DEBUG_SYMBOLS), false) JRE_SYMBOLS_EXCLUDE_PATTERN := $(addprefix %, \ $(call containing, .dSYM/, $(patsubst $(JRE_IMAGE_DIR)/%, %, $(ALL_JRE_FILES)))) endif
--- a/make/CompileJavaModules.gmk Sat Dec 02 11:25:35 2017 +0530 +++ b/make/CompileJavaModules.gmk Sat Dec 02 06:51:10 2017 +0100 @@ -300,7 +300,9 @@ ################################################################################ -java.xml_SETUP := GENERATE_JDKBYTECODE_NOWARNINGS +java.xml_ADD_JAVAC_FLAGS += -Xdoclint:all/protected \ + '-Xdoclint/package:$(call CommaList, javax.xml.catalog javax.xml.datatype \ + javax.xml.transform javax.xml.validation javax.xml.xpath)' java.xml_CLEAN += .properties ################################################################################
--- a/make/InitSupport.gmk Sat Dec 02 11:25:35 2017 +0530 +++ b/make/InitSupport.gmk Sat Dec 02 06:51:10 2017 +0100 @@ -47,7 +47,7 @@ # Make control variables, handled by Init.gmk INIT_CONTROL_VARIABLES += LOG CONF CONF_NAME SPEC JOBS TEST_JOBS CONF_CHECK \ - COMPARE_BUILD JTREG GTEST + COMPARE_BUILD JTREG GTEST TEST_OPTS TEST_VM_OPTS # All known make control variables MAKE_CONTROL_VARIABLES := $(INIT_CONTROL_VARIABLES) TEST JDK_FILTER
--- a/make/Main.gmk Sat Dec 02 11:25:35 2017 +0530 +++ b/make/Main.gmk Sat Dec 02 06:51:10 2017 +0100 @@ -480,8 +480,7 @@ # prepare-test-image: - $(MKDIR) -p $(TEST_IMAGE_DIR) - $(ECHO) > $(TEST_IMAGE_DIR)/Readme.txt 'JDK test image' + +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f TestImage.gmk prepare-test-image) build-test-hotspot-jtreg-native: +($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) -f JtregNativeHotspot.gmk \ @@ -1049,7 +1048,7 @@ # file. CLEAN_DIRS += hotspot jdk bootcycle-build test buildtools support \ - images make-support test-make bundles buildjdk + images make-support test-make bundles buildjdk test-results test-support CLEAN_DIR_TARGETS := $(addprefix clean-, $(CLEAN_DIRS)) CLEAN_SUPPORT_DIRS += demos CLEAN_SUPPORT_DIR_TARGETS := $(addprefix clean-, $(CLEAN_SUPPORT_DIRS)) @@ -1094,6 +1093,8 @@ # while classes and touch files end up in jdk. clean-support: clean-jdk +clean-test: clean-test-results clean-test-support + # Remove everything, including configure configuration. If the output # directory was created by configure and now becomes empty, remove it as well. dist-clean: clean
--- a/make/RunTests.gmk Sat Dec 02 11:25:35 2017 +0530 +++ b/make/RunTests.gmk Sat Dec 02 06:51:10 2017 +0100 @@ -32,17 +32,77 @@ # We will always run multiple tests serially .NOTPARALLEL: +################################################################################ +# Parse global control variables +################################################################################ + +ifneq ($(TEST_VM_OPTS), ) + ifneq ($(TEST_OPTS), ) + TEST_OPTS := $(TEST_OPTS);VM_OPTIONS=$(TEST_VM_OPTS) + else + TEST_OPTS := VM_OPTIONS=$(TEST_VM_OPTS) + endif +endif + +$(eval $(call ParseKeywordVariable, TEST_OPTS, \ + KEYWORDS := JOBS TIMEOUT, \ + STRING_KEYWORDS := VM_OPTIONS, \ +)) + +# Helper function to propagate TEST_OPTS values. +# +# Note: No spaces are allowed around the arguments. +# Arg $1 The variable in TEST_OPTS to propagate +# Arg $2 The control variable to propagate it to +define SetTestOpt + ifneq ($$(TEST_OPTS_$1), ) + $2_$1 := $$(TEST_OPTS_$1) + endif +endef + +################################################################################ # Hook to include the corresponding custom file, if present. $(eval $(call IncludeCustomExtension, RunTests.gmk)) +################################################################################ TEST_RESULTS_DIR := $(OUTPUTDIR)/test-results TEST_SUPPORT_DIR := $(OUTPUTDIR)/test-support +TEST_SUMMARY := $(TEST_RESULTS_DIR)/test-summary.txt +TEST_LAST_IDS := $(TEST_SUPPORT_DIR)/test-last-ids.txt +ifeq ($(CUSTOM_ROOT), ) + JTREG_TOPDIR := $(TOPDIR) +else + JTREG_TOPDIR := $(CUSTOM_ROOT) +endif + +JTREG_FAILURE_HANDLER_DIR := $(TEST_IMAGE_DIR)/failure_handler +JTREG_FAILURE_HANDLER := $(JTREG_FAILURE_HANDLER_DIR)/jtregFailureHandler.jar + +ifneq ($(wildcard $(JTREG_FAILURE_HANDLER)), ) + JTREG_FAILURE_HANDLER_OPTIONS := \ + -timeoutHandlerDir:$(JTREG_FAILURE_HANDLER) \ + -observerDir:$(JTREG_FAILURE_HANDLER) \ + -timeoutHandler:jdk.test.failurehandler.jtreg.GatherProcessInfoTimeoutHandler \ + -observer:jdk.test.failurehandler.jtreg.GatherDiagnosticInfoObserver \ + -timeoutHandlerTimeout:0 +endif ################################################################################ # Parse control variables ################################################################################ +ifneq ($(TEST_OPTS), ) + # Inform the user + $(info Running tests using TEST_OPTS control variable '$(TEST_OPTS)') + + $(eval $(call SetTestOpt,VM_OPTIONS,JTREG)) + $(eval $(call SetTestOpt,VM_OPTIONS,GTEST)) + + $(eval $(call SetTestOpt,JOBS,JTREG)) + $(eval $(call SetTestOpt,TIMEOUT,JTREG)) +endif + $(eval $(call ParseKeywordVariable, JTREG, \ KEYWORDS := JOBS TIMEOUT TEST_MODE ASSERT VERBOSE RETAIN MAX_MEM, \ STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS, \ @@ -55,7 +115,7 @@ $(eval $(call ParseKeywordVariable, GTEST, \ KEYWORDS := REPEAT, \ - STRING_KEYWORDS := OPTIONS, \ + STRING_KEYWORDS := OPTIONS VM_OPTIONS, \ )) ifneq ($(GTEST), ) @@ -84,6 +144,11 @@ hotspot_JTREG_NATIVEPATH := $(TEST_IMAGE_DIR)/hotspot/jtreg/native jdk_JTREG_NATIVEPATH := $(TEST_IMAGE_DIR)/jdk/jtreg/native +jdk_JTREG_PROBLEM_LIST += $(TOPDIR)/test/jdk/ProblemList.txt +jaxp_JTREG_PROBLEM_LIST += $(TOPDIR)/test/jaxp/ProblemList.txt +langtools_JTREG_PROBLEM_LIST += $(TOPDIR)/test/langtools/ProblemList.txt +nashorn_JTREG_PROBLEM_LIST += $(TOPDIR)/test/nashorn/ProblemList.txt +hotspot_JTREG_PROBLEM_LIST += $(TOPDIR)/test/hotspot/jtreg/ProblemList.txt ################################################################################ # Parse test selection @@ -116,17 +181,23 @@ ) endef +# Helper function that removes the TOPDIR part +CleanupJtregPath = \ + $(strip $(patsubst %/, %, $(subst $(JTREG_TOPDIR)/,, $1))) + # Take a partial Jtreg root path and return a full, absolute path to that Jtreg # root. Also support having "hotspot" as an alias for "hotspot/jtreg". ExpandJtregRoot = \ - $(strip $(wildcard $(patsubst %/, %, \ + $(call CleanupJtregPath, $(wildcard \ $(if $(filter /%, $1), \ - $1 \ + $(if $(wildcard $(strip $1)/TEST.ROOT), \ + $1 \ + ) \ , \ $(filter $(addprefix %, $1), $(JTREG_TESTROOTS) $(addsuffix /, $(JTREG_TESTROOTS))) \ $(filter $(addprefix %, $(strip $1)/jtreg), $(JTREG_TESTROOTS) $(addsuffix /, $(JTREG_TESTROOTS))) \ ) \ - ))) + )) # Take a partial Jtreg test path and return a full, absolute path to that Jtreg # test. Also support having "hotspot" as an alias for "hotspot/jtreg". @@ -134,14 +205,14 @@ $(if $(call ExpandJtregRoot, $1), \ $(call ExpandJtregRoot, $1) \ , \ - $(strip $(wildcard $(patsubst %/, %, \ + $(call CleanupJtregPath, $(wildcard \ $(if $(filter /%, $1), \ $1 \ , \ $(addsuffix /$(strip $1), $(JTREG_TESTROOTS) $(TEST_BASEDIRS)) \ $(addsuffix $(strip $(patsubst hotspot/%, /hotspot/jtreg/%, $1)), $(JTREG_TESTROOTS) $(TEST_BASEDIRS)) \ ) \ - ))) \ + )) \ ) # Helper function to determine if a test specification is a Jtreg test @@ -158,27 +229,26 @@ $(if $(findstring :, $(TEST_NAME)), \ $(if $(filter :%, $(TEST_NAME)), \ $(eval TEST_GROUP := $(patsubst :%, %, $(TEST_NAME))) \ - $(eval TEST_ROOTS := $(JTREG_TESTROOTS)) \ + $(eval TEST_ROOTS := $(foreach test_root, $(JTREG_TESTROOTS), \ + $(call CleanupJtregPath, $(test_root)))) \ , \ $(eval TEST_PATH := $(word 1, $(subst :, $(SPACE), $(TEST_NAME)))) \ $(eval TEST_GROUP := $(word 2, $(subst :, $(SPACE), $(TEST_NAME)))) \ $(eval TEST_ROOTS := $(call ExpandJtregRoot, $(TEST_PATH))) \ ) \ $(foreach test_root, $(TEST_ROOTS), \ - $(if $(filter $(TEST_GROUP), $($(test_root)_JTREG_TEST_GROUPS)), \ + $(if $(filter /%, $(test_root)), \ jtreg:$(test_root):$(TEST_GROUP) \ + , \ + $(if $(filter $(TEST_GROUP), $($(JTREG_TOPDIR)/$(test_root)_JTREG_TEST_GROUPS)), \ + jtreg:$(test_root):$(TEST_GROUP) \ + ) \ ) \ ) \ , \ - $(if $(filter /%, $(TEST_NAME)), \ - $(if $(wildcard $(TEST_NAME)), \ - jtreg:$(TEST_NAME) \ - ) \ - , \ - $(eval TEST_PATHS := $(call ExpandJtregPath, $(TEST_NAME))) \ - $(foreach test_path, $(TEST_PATHS), \ - jtreg:$(test_path) \ - ) \ + $(eval TEST_PATHS := $(call ExpandJtregPath, $(TEST_NAME))) \ + $(foreach test_path, $(TEST_PATHS), \ + jtreg:$(test_path) \ ) \ ) endef @@ -248,6 +318,7 @@ define SetupRunGtestTestBody $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1 $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1 + $1_EXITCODE := $$($1_TEST_RESULTS_DIR)/exitcode.txt $1_TEST_NAME := $$(strip $$(patsubst gtest:%, %, $$($1_TEST))) ifneq ($$($1_TEST_NAME), all) @@ -264,10 +335,13 @@ $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR)) $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/gtest, \ $$(FIXPATH) $$(TEST_IMAGE_DIR)/hotspot/gtest/server/gtestLauncher \ - -jdk $(JDK_IMAGE_DIR) $$($1_GTEST_FILTER) \ - --gtest_output=xml:$$($1_TEST_RESULTS_DIR)/gtest.xml \ - $$($1_GTEST_REPEAT) $$(GTEST_OPTIONS) \ - > >($(TEE) $$($1_TEST_RESULTS_DIR)/gtest.txt) || true ) + -jdk $(JDK_IMAGE_DIR) $$($1_GTEST_FILTER) \ + --gtest_output=xml:$$($1_TEST_RESULTS_DIR)/gtest.xml \ + $$($1_GTEST_REPEAT) $$(GTEST_OPTIONS) $$(GTEST_VM_OPTIONS) \ + > >($(TEE) $$($1_TEST_RESULTS_DIR)/gtest.txt) \ + && $$(ECHO) $$$$? > $$($1_EXITCODE) \ + || $$(ECHO) $$$$? > $$($1_EXITCODE) \ + ) $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/gtest.txt @@ -275,15 +349,24 @@ $$(call LogWarn, Finished running test '$$($1_TEST)') $$(call LogWarn, Test report is stored in $$(strip \ $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR)))) - $$(eval $1_TOTAL := $$(shell $$(AWK) '/==========.* tests? from .* \ - test cases? ran/ { print $$$$2 }' $$($1_RESULT_FILE))) - $$(eval $1_PASSED := $$(shell $$(AWK) '/\[ PASSED \] .* tests?./ \ - { print $$$$4 }' $$($1_RESULT_FILE))) - $$(eval $1_FAILED := $$(shell $$(AWK) '/\[ FAILED \] .* tests?, \ - listed below/ { print $$$$4 }' $$($1_RESULT_FILE))) - $$(if $$($1_FAILED), , $$(eval $1_FAILED := 0)) - $$(eval $1_ERROR := $$(shell \ - $$(EXPR) $$($1_TOTAL) - $$($1_PASSED) - $$($1_FAILED))) + $$(if $$(wildcard $$($1_RESULT_FILE)), \ + $$(eval $1_TOTAL := $$(shell $$(AWK) '/==========.* tests? from .* \ + test cases? ran/ { print $$$$2 }' $$($1_RESULT_FILE))) \ + $$(if $$($1_TOTAL), , $$(eval $1_TOTAL := 0)) \ + $$(eval $1_PASSED := $$(shell $$(AWK) '/\[ PASSED \] .* tests?./ \ + { print $$$$4 }' $$($1_RESULT_FILE))) \ + $$(if $$($1_PASSED), , $$(eval $1_PASSED := 0)) \ + $$(eval $1_FAILED := $$(shell $$(AWK) '/\[ FAILED \] .* tests?, \ + listed below/ { print $$$$4 }' $$($1_RESULT_FILE))) \ + $$(if $$($1_FAILED), , $$(eval $1_FAILED := 0)) \ + $$(eval $1_ERROR := $$(shell \ + $$(EXPR) $$($1_TOTAL) - $$($1_PASSED) - $$($1_FAILED))) \ + , \ + $$(eval $1_PASSED := 0) \ + $$(eval $1_FAILED := 0) \ + $$(eval $1_ERROR := 1) \ + $$(eval $1_TOTAL := 1) \ + ) $1: run-test-$1 parse-test-$1 @@ -321,12 +404,13 @@ define SetupRunJtregTestBody $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1 $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1 + $1_EXITCODE := $$($1_TEST_RESULTS_DIR)/exitcode.txt $1_TEST_NAME := $$(strip $$(patsubst jtreg:%, %, $$($1_TEST))) $1_COMPONENT := \ $$(strip $$(foreach root, $$(JTREG_TESTROOTS), \ - $$(if $$(filter $$(root)%, $$($1_TEST_NAME)), \ + $$(if $$(filter $$(root)%, $$(JTREG_TOPDIR)/$$($1_TEST_NAME)), \ $$(lastword $$(subst /, $$(SPACE), $$(root))) \ ) \ )) @@ -350,6 +434,7 @@ $$(eval $$(call SetJtregValue,$1,JTREG_MAX_MEM,512m)) $$(eval $$(call SetJtregValue,$1,JTREG_NATIVEPATH)) $$(eval $$(call SetJtregValue,$1,JTREG_BASIC_OPTIONS)) + $$(eval $$(call SetJtregValue,$1,JTREG_PROBLEM_LIST)) ifneq ($(TEST_JOBS), 0) # User has specified TEST_JOBS, use that as fallback default @@ -359,11 +444,6 @@ $$(eval $$(call SetJtregValue,$1,JTREG_JOBS,$$(JOBS))) endif - ifeq ($$(shell $$(EXPR) $$($1_JTREG_JOBS) \> 50), 1) - # Until CODETOOLS-7901892 is fixed, JTreg cannot handle more than 50 jobs - $1_JTREG_JOBS := 50 - endif - # Make sure MaxRAMPercentage is high enough to not cause OOM or swapping since # we may end up with a lot of JVM's $1_JTREG_MAX_RAM_PERCENTAGE := $$(shell $$(EXPR) 25 / $$($1_JTREG_JOBS)) @@ -403,11 +483,22 @@ $1_JTREG_BASIC_OPTIONS += -nativepath:$$($1_JTREG_NATIVEPATH) endif + ifneq ($$($1_JTREG_PROBLEM_LIST), ) + $1_JTREG_BASIC_OPTIONS += $$(addprefix -exclude:, $$($1_JTREG_PROBLEM_LIST)) + endif + ifneq ($$(JIB_JAR), ) $1_JTREG_BASIC_OPTIONS += -cpa:$$(JIB_JAR) endif - run-test-$1: + ifneq ($$(JTREG_FAILURE_HANDLER_OPTIONS), ) + $1_JTREG_LAUNCHER_OPTIONS += -Djava.library.path="$(JTREG_FAILURE_HANDLER_DIR)" + endif + + clean-workdir-$1: + $$(RM) -r $$($1_TEST_SUPPORT_DIR) + + run-test-$1: clean-workdir-$1 $$(call LogWarn) $$(call LogWarn, Running test '$$($1_TEST)') $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR)) @@ -416,11 +507,15 @@ -Dprogram=jtreg -jar $$(JT_HOME)/lib/jtreg.jar \ $$($1_JTREG_BASIC_OPTIONS) \ -testjdk:$$(JDK_IMAGE_DIR) \ - -dir:$$(TOPDIR) \ + -dir:$$(JTREG_TOPDIR) \ -reportDir:$$($1_TEST_RESULTS_DIR) \ -workDir:$$($1_TEST_SUPPORT_DIR) \ $$(JTREG_OPTIONS) \ - $$($1_TEST_NAME) || true ) + $$(JTREG_FAILURE_HANDLER_OPTIONS) \ + $$($1_TEST_NAME) \ + && $$(ECHO) $$$$? > $$($1_EXITCODE) \ + || $$(ECHO) $$$$? > $$($1_EXITCODE) \ + ) $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/text/stats.txt @@ -428,7 +523,7 @@ $$(call LogWarn, Finished running test '$$($1_TEST)') $$(call LogWarn, Test report is stored in $$(strip \ $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR)))) - $$(if $$(wildcard $$($1_RESULT_FILE)), \ + $$(if $$(wildcard $$($1_RESULT_FILE)), \ $$(eval $1_PASSED := $$(shell $$(AWK) '{ gsub(/[,;]/, ""); \ for (i=1; i<=NF; i++) { if ($$$$i == "passed:") \ print $$$$(i+1) } }' $$($1_RESULT_FILE))) \ @@ -470,7 +565,7 @@ # Now process each test to run and setup a proper make rule $(foreach test, $(TESTS_TO_RUN), \ $(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \ - $(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \ + $(TR) -cs '[a-z][A-Z][0-9]\n' '[_*1000]')) \ $(eval ALL_TEST_IDS += $(TEST_ID)) \ $(if $(call UseCustomTestHandler, $(test)), \ $(eval $(call SetupRunCustomTest, $(TEST_ID), \ @@ -504,35 +599,49 @@ TEST_FAILURE := false run-test: $(TARGETS) - # Print a table of the result of all tests run and their result - $(ECHO) - $(ECHO) ============================== - $(ECHO) Test summary - $(ECHO) ============================== - $(PRINTF) "%2s %-49s %5s %5s %5s %5s %2s\n" " " TEST \ - TOTAL PASS FAIL ERROR " " + # Create and print a table of the result of all tests run + $(RM) $(TEST_SUMMARY).old 2> /dev/null + $(MV) $(TEST_SUMMARY) $(TEST_SUMMARY).old 2> /dev/null || true + $(RM) $(TEST_LAST_IDS).old 2> /dev/null + $(MV) $(TEST_LAST_IDS) $(TEST_LAST_IDS).old 2> /dev/null || true + $(ECHO) >> $(TEST_SUMMARY) ============================== + $(ECHO) >> $(TEST_SUMMARY) Test summary + $(ECHO) >> $(TEST_SUMMARY) ============================== + $(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s %5s %5s %5s %5s %2s\n" " " \ + TEST TOTAL PASS FAIL ERROR " " $(foreach test, $(TESTS_TO_RUN), \ $(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \ - $(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \ + $(TR) -cs '[a-z][A-Z][0-9]\n' '[_*1000]')) \ + $(ECHO) >> $(TEST_LAST_IDS) $(TEST_ID) $(NEWLINE) \ + $(eval NAME_PATTERN := $(shell $(ECHO) $(test) | $(TR) -c '\n' '[_*1000]')) \ + $(if $(filter __________________________________________________%, $(NAME_PATTERN)), \ + $(eval TEST_NAME := ) \ + $(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s\n" " " "$(test)" $(NEWLINE) \ + , \ + $(eval TEST_NAME := $(test)) \ + ) \ $(if $(filter $($(TEST_ID)_PASSED), $($(TEST_ID)_TOTAL)), \ - $(PRINTF) "%2s %-49s %5d %5d %5d %5d %2s\n" " " "$(test)" \ - $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) $($(TEST_ID)_FAILED) \ - $($(TEST_ID)_ERROR) " " $(NEWLINE) \ + $(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s %5d %5d %5d %5d %2s\n" \ + " " "$(TEST_NAME)" $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) \ + $($(TEST_ID)_FAILED) $($(TEST_ID)_ERROR) " " $(NEWLINE) \ , \ - $(PRINTF) "%2s %-49s %5d %5d %5d %5d %2s\n" ">>" "$(test)" \ - $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) $($(TEST_ID)_FAILED) \ - $($(TEST_ID)_ERROR) "<<" $(NEWLINE) \ + $(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s %5d %5d %5d %5d %2s\n" \ + ">>" "$(TEST_NAME)" $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) \ + $($(TEST_ID)_FAILED) $($(TEST_ID)_ERROR) "<<" $(NEWLINE) \ $(eval TEST_FAILURE := true) \ ) \ ) - $(ECHO) ============================== + $(ECHO) >> $(TEST_SUMMARY) ============================== $(if $(filter true, $(TEST_FAILURE)), \ - $(ECHO) TEST FAILURE $(NEWLINE) \ + $(ECHO) >> $(TEST_SUMMARY) TEST FAILURE $(NEWLINE) \ + $(MKDIR) -p $(MAKESUPPORT_OUTPUTDIR) $(NEWLINE) \ $(TOUCH) $(MAKESUPPORT_OUTPUTDIR)/exit-with-error \ , \ - $(ECHO) TEST SUCCESS \ + $(ECHO) >> $(TEST_SUMMARY) TEST SUCCESS \ ) $(ECHO) + $(CAT) $(TEST_SUMMARY) + $(ECHO) ################################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/TestImage.gmk Sat Dec 02 06:51:10 2017 +0100 @@ -0,0 +1,46 @@ +# +# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute 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. +# + +default: all + +include $(SPEC) +include MakeBase.gmk + +############################################################################ + +ifeq ($(OPENJDK_TARGET_OS), windows) + FIXPATH_COPY := $(TEST_IMAGE_DIR)/bin/fixpath.exe + + $(FIXPATH_COPY): $(firstword $(FIXPATH)) + $(call install-file) +endif + +prepare-test-image: $(FIXPATH_COPY) + $(call MakeDir, $(TEST_IMAGE_DIR)) + $(ECHO) > $(TEST_IMAGE_DIR)/Readme.txt 'JDK test image' + +all: prepare-test-image + +.PHONY: default all prepare-test-image
--- a/make/autoconf/basics.m4 Sat Dec 02 11:25:35 2017 +0530 +++ b/make/autoconf/basics.m4 Sat Dec 02 06:51:10 2017 +0100 @@ -1092,10 +1092,6 @@ # We can build without it. LDD="true" fi - BASIC_PATH_PROGS(OTOOL, otool) - if test "x$OTOOL" = "x"; then - OTOOL="true" - fi BASIC_PATH_PROGS(READELF, [greadelf readelf]) BASIC_PATH_PROGS(DOT, dot) BASIC_PATH_PROGS(HG, hg)
--- a/make/autoconf/generated-configure.sh Sat Dec 02 11:25:35 2017 +0530 +++ b/make/autoconf/generated-configure.sh Sat Dec 02 06:51:10 2017 +0100 @@ -818,6 +818,8 @@ DUMPBIN RC MT +INSTALL_NAME_TOOL +OTOOL LIPO ac_ct_AR AR @@ -932,7 +934,6 @@ HG DOT READELF -OTOOL LDD ZIPEXE UNZIP @@ -1277,7 +1278,6 @@ UNZIP ZIPEXE LDD -OTOOL READELF DOT HG @@ -1310,6 +1310,8 @@ AS AR LIPO +OTOOL +INSTALL_NAME_TOOL STRIP NM GNM @@ -2226,7 +2228,6 @@ UNZIP Override default value for UNZIP ZIPEXE Override default value for ZIPEXE LDD Override default value for LDD - OTOOL Override default value for OTOOL READELF Override default value for READELF DOT Override default value for DOT HG Override default value for HG @@ -2260,6 +2261,9 @@ AS Override default value for AS AR Override default value for AR LIPO Override default value for LIPO + OTOOL Override default value for OTOOL + INSTALL_NAME_TOOL + Override default value for INSTALL_NAME_TOOL STRIP Override default value for STRIP NM Override default value for NM GNM Override default value for GNM @@ -5155,7 +5159,7 @@ #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1511254554 +DATE_WHEN_GENERATED=1512085548 ############################################################################### # @@ -22126,206 +22130,6 @@ # Publish this variable in the help. - if [ -z "${OTOOL+x}" ]; then - # The variable is not set by user, try to locate tool using the code snippet - for ac_prog in otool -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $OTOOL in - [\\/]* | ?:[\\/]*) - ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -OTOOL=$ac_cv_path_OTOOL -if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$OTOOL" && break -done - - else - # The variable is set, but is it from the command line or the environment? - - # Try to remove the string !OTOOL! from our list. - try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!OTOOL!/} - if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then - # If it failed, the variable was not from the command line. Ignore it, - # but warn the user (except for BASH, which is always set by the calling BASH). - if test "xOTOOL" != xBASH; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of OTOOL from the environment. Use command line variables instead." >&5 -$as_echo "$as_me: WARNING: Ignoring value of OTOOL from the environment. Use command line variables instead." >&2;} - fi - # Try to locate tool using the code snippet - for ac_prog in otool -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $OTOOL in - [\\/]* | ?:[\\/]*) - ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -OTOOL=$ac_cv_path_OTOOL -if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$OTOOL" && break -done - - else - # If it succeeded, then it was overridden by the user. We will use it - # for the tool. - - # First remove it from the list of overridden variables, so we can test - # for unknown variables in the end. - CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var" - - # Check if we try to supply an empty value - if test "x$OTOOL" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool OTOOL= (no value)" >&5 -$as_echo "$as_me: Setting user supplied tool OTOOL= (no value)" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OTOOL" >&5 -$as_echo_n "checking for OTOOL... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 -$as_echo "disabled" >&6; } - else - # Check if the provided tool contains a complete path. - tool_specified="$OTOOL" - tool_basename="${tool_specified##*/}" - if test "x$tool_basename" = "x$tool_specified"; then - # A command without a complete path is provided, search $PATH. - { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool OTOOL=$tool_basename" >&5 -$as_echo "$as_me: Will search for user supplied tool OTOOL=$tool_basename" >&6;} - # Extract the first word of "$tool_basename", so it can be a program name with args. -set dummy $tool_basename; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $OTOOL in - [\\/]* | ?:[\\/]*) - ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -OTOOL=$ac_cv_path_OTOOL -if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test "x$OTOOL" = x; then - as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5 - fi - else - # Otherwise we believe it is a complete path. Use it as it is. - { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool OTOOL=$tool_specified" >&5 -$as_echo "$as_me: Will use user supplied tool OTOOL=$tool_specified" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OTOOL" >&5 -$as_echo_n "checking for OTOOL... " >&6; } - if test ! -x "$tool_specified"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 -$as_echo "not found" >&6; } - as_fn_error $? "User supplied tool OTOOL=$tool_specified does not exist or is not executable" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5 -$as_echo "$tool_specified" >&6; } - fi - fi - fi - - fi - - - if test "x$OTOOL" = "x"; then - OTOOL="true" - fi - - - # Publish this variable in the help. - - if [ -z "${READELF+x}" ]; then # The variable is not set by user, try to locate tool using the code snippet for ac_prog in greadelf readelf @@ -39588,6 +39392,986 @@ fi fi + + + + # Publish this variable in the help. + + + if [ -z "${OTOOL+x}" ]; then + # The variable is not set by user, try to locate tool using the code snippet + for ac_prog in otool +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $OTOOL in + [\\/]* | ?:[\\/]*) + ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +OTOOL=$ac_cv_path_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$OTOOL" && break +done + + else + # The variable is set, but is it from the command line or the environment? + + # Try to remove the string !OTOOL! from our list. + try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!OTOOL!/} + if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then + # If it failed, the variable was not from the command line. Ignore it, + # but warn the user (except for BASH, which is always set by the calling BASH). + if test "xOTOOL" != xBASH; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of OTOOL from the environment. Use command line variables instead." >&5 +$as_echo "$as_me: WARNING: Ignoring value of OTOOL from the environment. Use command line variables instead." >&2;} + fi + # Try to locate tool using the code snippet + for ac_prog in otool +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $OTOOL in + [\\/]* | ?:[\\/]*) + ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +OTOOL=$ac_cv_path_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$OTOOL" && break +done + + else + # If it succeeded, then it was overridden by the user. We will use it + # for the tool. + + # First remove it from the list of overridden variables, so we can test + # for unknown variables in the end. + CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var" + + # Check if we try to supply an empty value + if test "x$OTOOL" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool OTOOL= (no value)" >&5 +$as_echo "$as_me: Setting user supplied tool OTOOL= (no value)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OTOOL" >&5 +$as_echo_n "checking for OTOOL... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } + else + # Check if the provided tool contains a complete path. + tool_specified="$OTOOL" + tool_basename="${tool_specified##*/}" + if test "x$tool_basename" = "x$tool_specified"; then + # A command without a complete path is provided, search $PATH. + { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool OTOOL=$tool_basename" >&5 +$as_echo "$as_me: Will search for user supplied tool OTOOL=$tool_basename" >&6;} + # Extract the first word of "$tool_basename", so it can be a program name with args. +set dummy $tool_basename; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $OTOOL in + [\\/]* | ?:[\\/]*) + ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +OTOOL=$ac_cv_path_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$OTOOL" = x; then + as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5 + fi + else + # Otherwise we believe it is a complete path. Use it as it is. + { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool OTOOL=$tool_specified" >&5 +$as_echo "$as_me: Will use user supplied tool OTOOL=$tool_specified" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OTOOL" >&5 +$as_echo_n "checking for OTOOL... " >&6; } + if test ! -x "$tool_specified"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } + as_fn_error $? "User supplied tool OTOOL=$tool_specified does not exist or is not executable" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5 +$as_echo "$tool_specified" >&6; } + fi + fi + fi + + fi + + + + if test "x$OTOOL" = x; then + as_fn_error $? "Could not find required tool for OTOOL" "$LINENO" 5 + fi + + + + # Only process if variable expands to non-empty + + if test "x$OTOOL" != x; then + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + + # First separate the path from the arguments. This will split at the first + # space. + complete="$OTOOL" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Input might be given as Windows format, start by converting to + # unix format. + new_path=`$CYGPATH -u "$path"` + + # Now try to locate executable using which + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in cygwin causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path=`$CYGPATH -u "$path"` + fi + if test "x$new_path" = x; then + # Oops. Which didn't find the executable. + # The splitting of arguments from the executable at a space might have been incorrect, + # since paths with space are more likely in Windows. Give it another try with the whole + # argument. + path="$complete" + arguments="EOL" + new_path=`$CYGPATH -u "$path"` + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in cygwin causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path=`$CYGPATH -u "$path"` + fi + if test "x$new_path" = x; then + # It's still not found. Now this is an unrecoverable error. + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of OTOOL, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of OTOOL, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5 +$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of OTOOL" "$LINENO" 5 + fi + fi + + # Cygwin tries to hide some aspects of the Windows file system, such that binaries are + # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered + # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then + # "foo.exe" is OK but "foo" is an error. + # + # This test is therefore slightly more accurate than "test -f" to check for file presence. + # It is also a way to make sure we got the proper file name for the real test later on. + test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` + if test "x$test_shortpath" = x; then + # Short path failed, file does not exist as specified. + # Try adding .exe or .cmd + if test -f "${new_path}.exe"; then + input_to_shortpath="${new_path}.exe" + elif test -f "${new_path}.cmd"; then + input_to_shortpath="${new_path}.cmd" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of OTOOL, which resolves as \"$new_path\", is invalid." >&5 +$as_echo "$as_me: The path of OTOOL, which resolves as \"$new_path\", is invalid." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&5 +$as_echo "$as_me: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&6;} + as_fn_error $? "Cannot locate the the path of OTOOL" "$LINENO" 5 + fi + else + input_to_shortpath="$new_path" + fi + + # Call helper function which possibly converts this using DOS-style short mode. + # If so, the updated path is stored in $new_path. + new_path="$input_to_shortpath" + + input_path="$input_to_shortpath" + # Check if we need to convert this using DOS-style short mode. If the path + # contains just simple characters, use it. Otherwise (spaces, weird characters), + # take no chances and rewrite it. + # Note: m4 eats our [], so we need to use [ and ] instead. + has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]` + if test "x$has_forbidden_chars" != x; then + # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) + shortmode_path=`$CYGPATH -s -m -a "$input_path"` + path_after_shortmode=`$CYGPATH -u "$shortmode_path"` + if test "x$path_after_shortmode" != "x$input_to_shortpath"; then + # Going to short mode and back again did indeed matter. Since short mode is + # case insensitive, let's make it lowercase to improve readability. + shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Now convert it back to Unix-style (cygpath) + input_path=`$CYGPATH -u "$shortmode_path"` + new_path="$input_path" + fi + fi + + test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/` + if test "x$test_cygdrive_prefix" = x; then + # As a simple fix, exclude /usr/bin since it's not a real path. + if test "x`$ECHO $input_to_shortpath | $GREP ^/usr/bin/`" = x; then + # The path is in a Cygwin special directory (e.g. /home). We need this converted to + # a path prefixed by /cygdrive for fixpath to work. + new_path="$CYGWIN_ROOT_PATH$input_path" + fi + fi + + # remove trailing .exe if any + new_path="${new_path/%.exe/}" + + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + + # First separate the path from the arguments. This will split at the first + # space. + complete="$OTOOL" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Input might be given as Windows format, start by converting to + # unix format. + new_path="$path" + + windows_path="$new_path" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + new_path="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + new_path="$unix_path" + fi + + + # Now try to locate executable using which + new_path=`$WHICH "$new_path" 2> /dev/null` + + if test "x$new_path" = x; then + # Oops. Which didn't find the executable. + # The splitting of arguments from the executable at a space might have been incorrect, + # since paths with space are more likely in Windows. Give it another try with the whole + # argument. + path="$complete" + arguments="EOL" + new_path="$path" + + windows_path="$new_path" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + new_path="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + new_path="$unix_path" + fi + + + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in MSYS causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path="$path" + + windows_path="$new_path" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + new_path="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + new_path="$unix_path" + fi + + fi + + if test "x$new_path" = x; then + # It's still not found. Now this is an unrecoverable error. + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of OTOOL, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of OTOOL, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5 +$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of OTOOL" "$LINENO" 5 + fi + fi + + # Now new_path has a complete unix path to the binary + if test "x`$ECHO $new_path | $GREP ^/bin/`" != x; then + # Keep paths in /bin as-is, but remove trailing .exe if any + new_path="${new_path/%.exe/}" + # Do not save /bin paths to all_fixpath_prefixes! + else + # Not in mixed or Windows style, start by that. + new_path=`cmd //c echo $new_path` + + input_path="$new_path" + # Check if we need to convert this using DOS-style short mode. If the path + # contains just simple characters, use it. Otherwise (spaces, weird characters), + # take no chances and rewrite it. + # Note: m4 eats our [], so we need to use [ and ] instead. + has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]` + if test "x$has_forbidden_chars" != x; then + # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) + new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + fi + + # Output is in $new_path + + windows_path="$new_path" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + new_path="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + new_path="$unix_path" + fi + + # remove trailing .exe if any + new_path="${new_path/%.exe/}" + + # Save the first 10 bytes of this path to the storage, so fixpath can work. + all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}") + fi + + else + # We're on a unix platform. Hooray! :) + # First separate the path from the arguments. This will split at the first + # space. + complete="$OTOOL" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Cannot rely on the command "which" here since it doesn't always work. + is_absolute_path=`$ECHO "$path" | $GREP ^/` + if test -z "$is_absolute_path"; then + # Path to executable is not absolute. Find it. + IFS_save="$IFS" + IFS=: + for p in $PATH; do + if test -f "$p/$path" && test -x "$p/$path"; then + new_path="$p/$path" + break + fi + done + IFS="$IFS_save" + else + # This is an absolute path, we can use it without further modifications. + new_path="$path" + fi + + if test "x$new_path" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of OTOOL, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of OTOOL, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: This might be caused by spaces in the path, which is not allowed." >&5 +$as_echo "$as_me: This might be caused by spaces in the path, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of OTOOL" "$LINENO" 5 + fi + fi + + # Now join together the path and the arguments once again + if test "x$arguments" != xEOL; then + new_complete="$new_path ${arguments% *}" + else + new_complete="$new_path" + fi + + if test "x$complete" != "x$new_complete"; then + OTOOL="$new_complete" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting OTOOL to \"$new_complete\"" >&5 +$as_echo "$as_me: Rewriting OTOOL to \"$new_complete\"" >&6;} + fi + fi + + + + + # Publish this variable in the help. + + + if [ -z "${INSTALL_NAME_TOOL+x}" ]; then + # The variable is not set by user, try to locate tool using the code snippet + for ac_prog in install_name_tool +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_INSTALL_NAME_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $INSTALL_NAME_TOOL in + [\\/]* | ?:[\\/]*) + ac_cv_path_INSTALL_NAME_TOOL="$INSTALL_NAME_TOOL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_INSTALL_NAME_TOOL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +INSTALL_NAME_TOOL=$ac_cv_path_INSTALL_NAME_TOOL +if test -n "$INSTALL_NAME_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL_NAME_TOOL" >&5 +$as_echo "$INSTALL_NAME_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$INSTALL_NAME_TOOL" && break +done + + else + # The variable is set, but is it from the command line or the environment? + + # Try to remove the string !INSTALL_NAME_TOOL! from our list. + try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!INSTALL_NAME_TOOL!/} + if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then + # If it failed, the variable was not from the command line. Ignore it, + # but warn the user (except for BASH, which is always set by the calling BASH). + if test "xINSTALL_NAME_TOOL" != xBASH; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of INSTALL_NAME_TOOL from the environment. Use command line variables instead." >&5 +$as_echo "$as_me: WARNING: Ignoring value of INSTALL_NAME_TOOL from the environment. Use command line variables instead." >&2;} + fi + # Try to locate tool using the code snippet + for ac_prog in install_name_tool +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_INSTALL_NAME_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $INSTALL_NAME_TOOL in + [\\/]* | ?:[\\/]*) + ac_cv_path_INSTALL_NAME_TOOL="$INSTALL_NAME_TOOL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_INSTALL_NAME_TOOL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +INSTALL_NAME_TOOL=$ac_cv_path_INSTALL_NAME_TOOL +if test -n "$INSTALL_NAME_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL_NAME_TOOL" >&5 +$as_echo "$INSTALL_NAME_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$INSTALL_NAME_TOOL" && break +done + + else + # If it succeeded, then it was overridden by the user. We will use it + # for the tool. + + # First remove it from the list of overridden variables, so we can test + # for unknown variables in the end. + CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var" + + # Check if we try to supply an empty value + if test "x$INSTALL_NAME_TOOL" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool INSTALL_NAME_TOOL= (no value)" >&5 +$as_echo "$as_me: Setting user supplied tool INSTALL_NAME_TOOL= (no value)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for INSTALL_NAME_TOOL" >&5 +$as_echo_n "checking for INSTALL_NAME_TOOL... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } + else + # Check if the provided tool contains a complete path. + tool_specified="$INSTALL_NAME_TOOL" + tool_basename="${tool_specified##*/}" + if test "x$tool_basename" = "x$tool_specified"; then + # A command without a complete path is provided, search $PATH. + { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool INSTALL_NAME_TOOL=$tool_basename" >&5 +$as_echo "$as_me: Will search for user supplied tool INSTALL_NAME_TOOL=$tool_basename" >&6;} + # Extract the first word of "$tool_basename", so it can be a program name with args. +set dummy $tool_basename; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_INSTALL_NAME_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $INSTALL_NAME_TOOL in + [\\/]* | ?:[\\/]*) + ac_cv_path_INSTALL_NAME_TOOL="$INSTALL_NAME_TOOL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_INSTALL_NAME_TOOL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +INSTALL_NAME_TOOL=$ac_cv_path_INSTALL_NAME_TOOL +if test -n "$INSTALL_NAME_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL_NAME_TOOL" >&5 +$as_echo "$INSTALL_NAME_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$INSTALL_NAME_TOOL" = x; then + as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5 + fi + else + # Otherwise we believe it is a complete path. Use it as it is. + { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool INSTALL_NAME_TOOL=$tool_specified" >&5 +$as_echo "$as_me: Will use user supplied tool INSTALL_NAME_TOOL=$tool_specified" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for INSTALL_NAME_TOOL" >&5 +$as_echo_n "checking for INSTALL_NAME_TOOL... " >&6; } + if test ! -x "$tool_specified"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } + as_fn_error $? "User supplied tool INSTALL_NAME_TOOL=$tool_specified does not exist or is not executable" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5 +$as_echo "$tool_specified" >&6; } + fi + fi + fi + + fi + + + + if test "x$INSTALL_NAME_TOOL" = x; then + as_fn_error $? "Could not find required tool for INSTALL_NAME_TOOL" "$LINENO" 5 + fi + + + + # Only process if variable expands to non-empty + + if test "x$INSTALL_NAME_TOOL" != x; then + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + + # First separate the path from the arguments. This will split at the first + # space. + complete="$INSTALL_NAME_TOOL" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Input might be given as Windows format, start by converting to + # unix format. + new_path=`$CYGPATH -u "$path"` + + # Now try to locate executable using which + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in cygwin causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path=`$CYGPATH -u "$path"` + fi + if test "x$new_path" = x; then + # Oops. Which didn't find the executable. + # The splitting of arguments from the executable at a space might have been incorrect, + # since paths with space are more likely in Windows. Give it another try with the whole + # argument. + path="$complete" + arguments="EOL" + new_path=`$CYGPATH -u "$path"` + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in cygwin causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path=`$CYGPATH -u "$path"` + fi + if test "x$new_path" = x; then + # It's still not found. Now this is an unrecoverable error. + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5 +$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of INSTALL_NAME_TOOL" "$LINENO" 5 + fi + fi + + # Cygwin tries to hide some aspects of the Windows file system, such that binaries are + # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered + # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then + # "foo.exe" is OK but "foo" is an error. + # + # This test is therefore slightly more accurate than "test -f" to check for file presence. + # It is also a way to make sure we got the proper file name for the real test later on. + test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` + if test "x$test_shortpath" = x; then + # Short path failed, file does not exist as specified. + # Try adding .exe or .cmd + if test -f "${new_path}.exe"; then + input_to_shortpath="${new_path}.exe" + elif test -f "${new_path}.cmd"; then + input_to_shortpath="${new_path}.cmd" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of INSTALL_NAME_TOOL, which resolves as \"$new_path\", is invalid." >&5 +$as_echo "$as_me: The path of INSTALL_NAME_TOOL, which resolves as \"$new_path\", is invalid." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&5 +$as_echo "$as_me: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&6;} + as_fn_error $? "Cannot locate the the path of INSTALL_NAME_TOOL" "$LINENO" 5 + fi + else + input_to_shortpath="$new_path" + fi + + # Call helper function which possibly converts this using DOS-style short mode. + # If so, the updated path is stored in $new_path. + new_path="$input_to_shortpath" + + input_path="$input_to_shortpath" + # Check if we need to convert this using DOS-style short mode. If the path + # contains just simple characters, use it. Otherwise (spaces, weird characters), + # take no chances and rewrite it. + # Note: m4 eats our [], so we need to use [ and ] instead. + has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]` + if test "x$has_forbidden_chars" != x; then + # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) + shortmode_path=`$CYGPATH -s -m -a "$input_path"` + path_after_shortmode=`$CYGPATH -u "$shortmode_path"` + if test "x$path_after_shortmode" != "x$input_to_shortpath"; then + # Going to short mode and back again did indeed matter. Since short mode is + # case insensitive, let's make it lowercase to improve readability. + shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Now convert it back to Unix-style (cygpath) + input_path=`$CYGPATH -u "$shortmode_path"` + new_path="$input_path" + fi + fi + + test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/` + if test "x$test_cygdrive_prefix" = x; then + # As a simple fix, exclude /usr/bin since it's not a real path. + if test "x`$ECHO $input_to_shortpath | $GREP ^/usr/bin/`" = x; then + # The path is in a Cygwin special directory (e.g. /home). We need this converted to + # a path prefixed by /cygdrive for fixpath to work. + new_path="$CYGWIN_ROOT_PATH$input_path" + fi + fi + + # remove trailing .exe if any + new_path="${new_path/%.exe/}" + + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + + # First separate the path from the arguments. This will split at the first + # space. + complete="$INSTALL_NAME_TOOL" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Input might be given as Windows format, start by converting to + # unix format. + new_path="$path" + + windows_path="$new_path" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + new_path="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + new_path="$unix_path" + fi + + + # Now try to locate executable using which + new_path=`$WHICH "$new_path" 2> /dev/null` + + if test "x$new_path" = x; then + # Oops. Which didn't find the executable. + # The splitting of arguments from the executable at a space might have been incorrect, + # since paths with space are more likely in Windows. Give it another try with the whole + # argument. + path="$complete" + arguments="EOL" + new_path="$path" + + windows_path="$new_path" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + new_path="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + new_path="$unix_path" + fi + + + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in MSYS causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path="$path" + + windows_path="$new_path" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + new_path="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + new_path="$unix_path" + fi + + fi + + if test "x$new_path" = x; then + # It's still not found. Now this is an unrecoverable error. + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5 +$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of INSTALL_NAME_TOOL" "$LINENO" 5 + fi + fi + + # Now new_path has a complete unix path to the binary + if test "x`$ECHO $new_path | $GREP ^/bin/`" != x; then + # Keep paths in /bin as-is, but remove trailing .exe if any + new_path="${new_path/%.exe/}" + # Do not save /bin paths to all_fixpath_prefixes! + else + # Not in mixed or Windows style, start by that. + new_path=`cmd //c echo $new_path` + + input_path="$new_path" + # Check if we need to convert this using DOS-style short mode. If the path + # contains just simple characters, use it. Otherwise (spaces, weird characters), + # take no chances and rewrite it. + # Note: m4 eats our [], so we need to use [ and ] instead. + has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]` + if test "x$has_forbidden_chars" != x; then + # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) + new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + fi + + # Output is in $new_path + + windows_path="$new_path" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + new_path="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + new_path="$unix_path" + fi + + # remove trailing .exe if any + new_path="${new_path/%.exe/}" + + # Save the first 10 bytes of this path to the storage, so fixpath can work. + all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}") + fi + + else + # We're on a unix platform. Hooray! :) + # First separate the path from the arguments. This will split at the first + # space. + complete="$INSTALL_NAME_TOOL" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Cannot rely on the command "which" here since it doesn't always work. + is_absolute_path=`$ECHO "$path" | $GREP ^/` + if test -z "$is_absolute_path"; then + # Path to executable is not absolute. Find it. + IFS_save="$IFS" + IFS=: + for p in $PATH; do + if test -f "$p/$path" && test -x "$p/$path"; then + new_path="$p/$path" + break + fi + done + IFS="$IFS_save" + else + # This is an absolute path, we can use it without further modifications. + new_path="$path" + fi + + if test "x$new_path" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: This might be caused by spaces in the path, which is not allowed." >&5 +$as_echo "$as_me: This might be caused by spaces in the path, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of INSTALL_NAME_TOOL" "$LINENO" 5 + fi + fi + + # Now join together the path and the arguments once again + if test "x$arguments" != xEOL; then + new_complete="$new_path ${arguments% *}" + else + new_complete="$new_path" + fi + + if test "x$complete" != "x$new_complete"; then + INSTALL_NAME_TOOL="$new_complete" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting INSTALL_NAME_TOOL to \"$new_complete\"" >&5 +$as_echo "$as_me: Rewriting INSTALL_NAME_TOOL to \"$new_complete\"" >&6;} + fi + fi + fi if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then @@ -54080,13 +54864,13 @@ else if test "x$OPENJDK_TARGET_OS" = xaix; then - # AIX doesn't support 'zipped' so use 'internal' as default + # AIX doesn't support 'external' so use 'internal' as default with_native_debug_symbols="internal" else if test "x$STATIC_BUILD" = xtrue; then with_native_debug_symbols="none" else - with_native_debug_symbols="zipped" + with_native_debug_symbols="external" fi fi @@ -64486,17 +65270,18 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUNDLE_FREETYPE" >&5 $as_echo "$BUNDLE_FREETYPE" >&6; } - fi # end freetype needed - - FREETYPE_LICENSE="" - if test "x$with_freetype_license" = "xyes"; then - as_fn_error $? "--with-freetype-license must have a value" "$LINENO" 5 - elif test "x$with_freetype_license" != "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype license" >&5 + if test "x$BUNDLE_FREETYPE" = xyes; then + FREETYPE_LICENSE="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype license" >&5 $as_echo_n "checking for freetype license... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_freetype_license" >&5 + if test "x$with_freetype_license" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "--with-freetype-license must have a value" "$LINENO" 5 + elif test "x$with_freetype_license" != "x"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_freetype_license" >&5 $as_echo "$with_freetype_license" >&6; } - FREETYPE_LICENSE="$with_freetype_license" + FREETYPE_LICENSE="$with_freetype_license" # Only process if variable expands to non-empty @@ -64629,10 +65414,154 @@ fi fi - if test ! -f "$FREETYPE_LICENSE"; then - as_fn_error $? "$FREETYPE_LICENSE cannot be found" "$LINENO" 5 - fi - fi + if test ! -f "$FREETYPE_LICENSE"; then + as_fn_error $? "$FREETYPE_LICENSE cannot be found" "$LINENO" 5 + fi + else + if test "x$with_freetype" != "x" && test -f $with_freetype/freetype.md; then + FREETYPE_LICENSE="$with_freetype/freetype.md" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FREETYPE_LICENSE" >&5 +$as_echo "$FREETYPE_LICENSE" >&6; } + + # Only process if variable expands to non-empty + + if test "x$FREETYPE_LICENSE" != x; then + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + + # Input might be given as Windows format, start by converting to + # unix format. + path="$FREETYPE_LICENSE" + new_path=`$CYGPATH -u "$path"` + + # Cygwin tries to hide some aspects of the Windows file system, such that binaries are + # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered + # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then + # "foo.exe" is OK but "foo" is an error. + # + # This test is therefore slightly more accurate than "test -f" to check for file precense. + # It is also a way to make sure we got the proper file name for the real test later on. + test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` + if test "x$test_shortpath" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of FREETYPE_LICENSE, which resolves as \"$path\", is invalid." >&5 +$as_echo "$as_me: The path of FREETYPE_LICENSE, which resolves as \"$path\", is invalid." >&6;} + as_fn_error $? "Cannot locate the the path of FREETYPE_LICENSE" "$LINENO" 5 + fi + + # Call helper function which possibly converts this using DOS-style short mode. + # If so, the updated path is stored in $new_path. + + input_path="$new_path" + # Check if we need to convert this using DOS-style short mode. If the path + # contains just simple characters, use it. Otherwise (spaces, weird characters), + # take no chances and rewrite it. + # Note: m4 eats our [], so we need to use [ and ] instead. + has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]` + if test "x$has_forbidden_chars" != x; then + # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) + shortmode_path=`$CYGPATH -s -m -a "$input_path"` + path_after_shortmode=`$CYGPATH -u "$shortmode_path"` + if test "x$path_after_shortmode" != "x$input_to_shortpath"; then + # Going to short mode and back again did indeed matter. Since short mode is + # case insensitive, let's make it lowercase to improve readability. + shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Now convert it back to Unix-style (cygpath) + input_path=`$CYGPATH -u "$shortmode_path"` + new_path="$input_path" + fi + fi + + test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/` + if test "x$test_cygdrive_prefix" = x; then + # As a simple fix, exclude /usr/bin since it's not a real path. + if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then + # The path is in a Cygwin special directory (e.g. /home). We need this converted to + # a path prefixed by /cygdrive for fixpath to work. + new_path="$CYGWIN_ROOT_PATH$input_path" + fi + fi + + + if test "x$path" != "x$new_path"; then + FREETYPE_LICENSE="$new_path" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting FREETYPE_LICENSE to \"$new_path\"" >&5 +$as_echo "$as_me: Rewriting FREETYPE_LICENSE to \"$new_path\"" >&6;} + fi + + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + + path="$FREETYPE_LICENSE" + has_colon=`$ECHO $path | $GREP ^.:` + new_path="$path" + if test "x$has_colon" = x; then + # Not in mixed or Windows style, start by that. + new_path=`cmd //c echo $path` + fi + + + input_path="$new_path" + # Check if we need to convert this using DOS-style short mode. If the path + # contains just simple characters, use it. Otherwise (spaces, weird characters), + # take no chances and rewrite it. + # Note: m4 eats our [], so we need to use [ and ] instead. + has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]` + if test "x$has_forbidden_chars" != x; then + # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) + new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + fi + + + windows_path="$new_path" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + new_path="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + new_path="$unix_path" + fi + + if test "x$path" != "x$new_path"; then + FREETYPE_LICENSE="$new_path" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting FREETYPE_LICENSE to \"$new_path\"" >&5 +$as_echo "$as_me: Rewriting FREETYPE_LICENSE to \"$new_path\"" >&6;} + fi + + # Save the first 10 bytes of this path to the storage, so fixpath can work. + all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}") + + else + # We're on a unix platform. Hooray! :) + path="$FREETYPE_LICENSE" + has_space=`$ECHO "$path" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of FREETYPE_LICENSE, which resolves as \"$path\", is invalid." >&5 +$as_echo "$as_me: The path of FREETYPE_LICENSE, which resolves as \"$path\", is invalid." >&6;} + as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5 + fi + + # Use eval to expand a potential ~ + eval path="$path" + if test ! -f "$path" && test ! -d "$path"; then + as_fn_error $? "The path of FREETYPE_LICENSE, which resolves as \"$path\", is not found." "$LINENO" 5 + fi + + if test -d "$path"; then + FREETYPE_LICENSE="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + FREETYPE_LICENSE="`cd "$dir"; $THEPWDCMD -L`/$base" + fi + fi + fi + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + fi + + fi # end freetype needed
--- a/make/autoconf/jdk-options.m4 Sat Dec 02 11:25:35 2017 +0530 +++ b/make/autoconf/jdk-options.m4 Sat Dec 02 06:51:10 2017 +0100 @@ -296,13 +296,13 @@ ], [ if test "x$OPENJDK_TARGET_OS" = xaix; then - # AIX doesn't support 'zipped' so use 'internal' as default + # AIX doesn't support 'external' so use 'internal' as default with_native_debug_symbols="internal" else if test "x$STATIC_BUILD" = xtrue; then with_native_debug_symbols="none" else - with_native_debug_symbols="zipped" + with_native_debug_symbols="external" fi fi ])
--- a/make/autoconf/lib-freetype.m4 Sat Dec 02 11:25:35 2017 +0530 +++ b/make/autoconf/lib-freetype.m4 Sat Dec 02 06:51:10 2017 +0100 @@ -443,21 +443,32 @@ fi AC_MSG_RESULT([$BUNDLE_FREETYPE]) + if test "x$BUNDLE_FREETYPE" = xyes; then + FREETYPE_LICENSE="" + AC_MSG_CHECKING([for freetype license]) + if test "x$with_freetype_license" = "xyes"; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([--with-freetype-license must have a value]) + elif test "x$with_freetype_license" != "x"; then + AC_MSG_RESULT([$with_freetype_license]) + FREETYPE_LICENSE="$with_freetype_license" + BASIC_FIXUP_PATH(FREETYPE_LICENSE) + if test ! -f "$FREETYPE_LICENSE"; then + AC_MSG_ERROR([$FREETYPE_LICENSE cannot be found]) + fi + else + if test "x$with_freetype" != "x" && test -f $with_freetype/freetype.md; then + FREETYPE_LICENSE="$with_freetype/freetype.md" + AC_MSG_RESULT([$FREETYPE_LICENSE]) + BASIC_FIXUP_PATH(FREETYPE_LICENSE) + else + AC_MSG_RESULT([no]) + fi + fi + fi + fi # end freetype needed - FREETYPE_LICENSE="" - if test "x$with_freetype_license" = "xyes"; then - AC_MSG_ERROR([--with-freetype-license must have a value]) - elif test "x$with_freetype_license" != "x"; then - AC_MSG_CHECKING([for freetype license]) - AC_MSG_RESULT([$with_freetype_license]) - FREETYPE_LICENSE="$with_freetype_license" - BASIC_FIXUP_PATH(FREETYPE_LICENSE) - if test ! -f "$FREETYPE_LICENSE"; then - AC_MSG_ERROR([$FREETYPE_LICENSE cannot be found]) - fi - fi - AC_SUBST(FREETYPE_BUNDLE_LIB_PATH) AC_SUBST(FREETYPE_CFLAGS) AC_SUBST(FREETYPE_LIBS)
--- a/make/autoconf/spec.gmk.in Sat Dec 02 11:25:35 2017 +0530 +++ b/make/autoconf/spec.gmk.in Sat Dec 02 06:51:10 2017 +0100 @@ -471,6 +471,7 @@ STRIP:=@STRIP@ LIPO:=@LIPO@ +INSTALL_NAME_TOOL:=@INSTALL_NAME_TOOL@ # Options to linker to specify a mapfile. # (Note absence of := assignment, because we do not want to evaluate the macro body here) @@ -565,12 +566,10 @@ BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS) # Interim langtools and rmic modules and arguments -INTERIM_LANGTOOLS_BASE_MODULES := java.compiler jdk.compiler jdk.jdeps jdk.javadoc +INTERIM_LANGTOOLS_BASE_MODULES := java.compiler jdk.compiler jdk.javadoc INTERIM_LANGTOOLS_MODULES := $(addsuffix .interim, $(INTERIM_LANGTOOLS_BASE_MODULES)) INTERIM_LANGTOOLS_ADD_EXPORTS := \ --add-exports java.base/sun.reflect.annotation=jdk.compiler.interim \ - --add-exports java.base/jdk.internal.util.jar=jdk.jdeps.interim \ - --add-exports java.base/jdk.internal.misc=jdk.jdeps.interim \ # INTERIM_LANGTOOLS_MODULES_COMMA := $(strip $(subst $(SPACE),$(COMMA),$(strip \ $(INTERIM_LANGTOOLS_MODULES))))
--- a/make/autoconf/toolchain.m4 Sat Dec 02 11:25:35 2017 +0530 +++ b/make/autoconf/toolchain.m4 Sat Dec 02 06:51:10 2017 +0100 @@ -628,6 +628,10 @@ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then BASIC_PATH_PROGS(LIPO, lipo) BASIC_FIXUP_EXECUTABLE(LIPO) + BASIC_REQUIRE_PROGS(OTOOL, otool) + BASIC_FIXUP_EXECUTABLE(OTOOL) + BASIC_REQUIRE_PROGS(INSTALL_NAME_TOOL, install_name_tool) + BASIC_FIXUP_EXECUTABLE(INSTALL_NAME_TOOL) fi if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
--- a/make/conf/jib-profiles.js Sat Dec 02 11:25:35 2017 +0530 +++ b/make/conf/jib-profiles.js Sat Dec 02 06:51:10 2017 +0100 @@ -429,7 +429,7 @@ "macosx-x64": { target_os: "macosx", target_cpu: "x64", - dependencies: ["devkit"], + dependencies: ["devkit", "freetype"], configure_args: concat(common.configure_args_64bit, "--with-zlib=system", "--with-macosx-version-max=10.7.0"), }, @@ -662,21 +662,6 @@ } }); - // The windows ri profile needs to add the freetype license file - profilesRiFreetype = { - "windows-x86-ri": { - configure_args: "--with-freetype-license=" - + input.get("freetype", "install_path") - + "/freetype-2.7.1-v120-x86/freetype.md" - }, - "windows-x64-ri": { - configure_args: "--with-freetype-license=" - + input.get("freetype", "install_path") - + "/freetype-2.7.1-v120-x64/freetype.md" - } - }; - profiles = concatObjects(profiles, profilesRiFreetype); - // Profiles used to run tests. Used in JPRT and Mach 5. var testOnlyProfiles = { "run-test-jprt": { @@ -788,6 +773,12 @@ var boot_jdk_platform = (input.build_os == "macosx" ? "osx" : input.build_os) + "-" + input.build_cpu; + var freetype_version = { + windows_x64: "2.7.1-v120+1.1", + windows_x86: "2.7.1-v120+1.1", + macosx_x64: "2.7.1-Xcode6.3-MacOSX10.9+1.0" + }[input.target_platform]; + var dependencies = { boot_jdk: { @@ -852,7 +843,7 @@ freetype: { organization: common.organization, ext: "tar.gz", - revision: "2.7.1-v120+1.0", + revision: freetype_version, module: "freetype-" + input.target_platform },
--- a/make/copy/Copy-java.desktop.gmk Sat Dec 02 11:25:35 2017 +0530 +++ b/make/copy/Copy-java.desktop.gmk Sat Dec 02 06:51:10 2017 +0100 @@ -44,7 +44,8 @@ ################################################################################ ifneq ($(FREETYPE_BUNDLE_LIB_PATH), ) - # We need to bundle the freetype library, so it will be available at runtime as well as link time. + # We need to bundle the freetype library, so it will be available at runtime + # as well as link time. # # NB: Default freetype build system uses -h linker option and # result .so contains hardcoded library name that is later @@ -61,10 +62,10 @@ # #TODO: rework this to avoid hardcoding library name in the makefile # - ifeq ($(OPENJDK_TARGET_OS), windows) + ifneq ($(filter $(OPENJDK_TARGET_OS), linux solaris), ) + FREETYPE_TARGET_LIB := $(LIB_DST_DIR)/$(call SHARED_LIBRARY,freetype).6 + else FREETYPE_TARGET_LIB := $(LIB_DST_DIR)/$(call SHARED_LIBRARY,freetype) - else - FREETYPE_TARGET_LIB := $(LIB_DST_DIR)/$(call SHARED_LIBRARY,freetype).6 endif # We can't use $(install-file) in this rule because it preserves symbolic links and
--- a/make/data/charsetmapping/charsets Sat Dec 02 11:25:35 2017 +0530 +++ b/make/data/charsetmapping/charsets Sat Dec 02 06:51:10 2017 +0100 @@ -492,7 +492,7 @@ charset x-MS950-HKSCS MS950_HKSCS package sun.nio.cs.ext - type source + type template hisname MS950_HKSCS ascii true alias MS950_HKSCS # JDK historical;
--- a/make/data/charsetmapping/stdcs-windows Sat Dec 02 11:25:35 2017 +0530 +++ b/make/data/charsetmapping/stdcs-windows Sat Dec 02 06:51:10 2017 +0100 @@ -13,4 +13,5 @@ MS936 MS949 MS950 +MS950_HKSCS MS950_HKSCS_XP
--- a/make/gendata/Gendata-jdk.compiler.gmk Sat Dec 02 11:25:35 2017 +0530 +++ b/make/gendata/Gendata-jdk.compiler.gmk Sat Dec 02 06:51:10 2017 +0100 @@ -49,13 +49,13 @@ --add-exports jdk.compiler.interim/com.sun.tools.javac.code=ALL-UNNAMED \ --add-exports jdk.compiler.interim/com.sun.tools.javac.util=ALL-UNNAMED \ --add-exports jdk.compiler.interim/com.sun.tools.javac.jvm=ALL-UNNAMED \ - --add-exports jdk.jdeps.interim/com.sun.tools.classfile=ALL-UNNAMED \ # $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \ SETUP := GENERATE_OLDBYTECODE, \ - SRC := $(TOPDIR)/make/langtools/src/classes, \ - INCLUDES := build/tools/symbolgenerator, \ + SRC := $(TOPDIR)/make/langtools/src/classes \ + $(TOPDIR)/src/jdk.jdeps/share/classes, \ + INCLUDES := build/tools/symbolgenerator com/sun/tools/classfile, \ BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols, \ ADD_JAVAC_FLAGS := $(INTERIM_LANGTOOLS_ARGS) \ $(COMPILECREATESYMBOLS_ADD_EXPORTS), \
--- a/make/hotspot/symbols/symbols-unix Sat Dec 02 11:25:35 2017 +0530 +++ b/make/hotspot/symbols/symbols-unix Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ JVM_ArrayCopy JVM_AssertionStatusDirectives JVM_CallStackWalk -JVM_ClassDepth -JVM_ClassLoaderDepth JVM_Clone JVM_ConstantPoolGetClassAt JVM_ConstantPoolGetClassAtIfLoaded @@ -47,8 +45,6 @@ JVM_ConstantPoolGetTagAt JVM_ConstantPoolGetUTF8At JVM_CountStackFrames -JVM_CurrentClassLoader -JVM_CurrentLoadedClass JVM_CurrentThread JVM_CurrentTimeMillis JVM_DefineClass
--- a/make/jdk/src/classes/build/tools/charsetmapping/Main.java Sat Dec 02 11:25:35 2017 +0530 +++ b/make/jdk/src/classes/build/tools/charsetmapping/Main.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,6 +54,7 @@ new File(args[SRC_DIR], args[CHARSETS])); String[] osStdcs = getOSStdCSList(new File(args[SRC_DIR], args[OS])); boolean hasBig5_HKSCS = false; + boolean hasMS950_HKSCS = false; boolean hasMS950_HKSCS_XP = false; boolean hasEUC_TW = false; for (String name : osStdcs) { @@ -63,6 +64,8 @@ } if (name.equals("Big5_HKSCS")) { hasBig5_HKSCS = true; + } else if (name.equals("MS950_HKSCS")) { + hasMS950_HKSCS = true; } else if (name.equals("MS950_HKSCS_XP")) { hasMS950_HKSCS_XP = true; } else if (name.equals("EUC_TW")) { @@ -98,12 +101,15 @@ args[TEMPLATE], args[OS].endsWith("windows") ? "windows" : "unix"); - // HKSCSMapping2008/XP.java goes together with Big5/MS950XP_HKSCS - if (isStandard && hasBig5_HKSCS || isExtended && !hasBig5_HKSCS) { + // HKSCSMapping(2008).java goes std if one of Big5_HKSCS MS950_HKSCS + // is in std + if (isStandard && (hasBig5_HKSCS || hasMS950_HKSCS) || + isExtended && !(hasBig5_HKSCS || hasMS950_HKSCS)) { HKSCS.genClass2008(args[SRC_DIR], args[DST_DIR], isStandard ? "sun.nio.cs" : "sun.nio.cs.ext", new File(args[COPYRIGHT_SRC], "HKSCS.java")); } + // HKSCS_XPMapping.java goes together with MS950XP_HKSCS if (isStandard && hasMS950_HKSCS_XP || isExtended && !hasMS950_HKSCS_XP) { HKSCS.genClassXP(args[SRC_DIR], args[DST_DIR], isStandard ? "sun.nio.cs" : "sun.nio.cs.ext",
--- a/make/lib/Awt2dLibraries.gmk Sat Dec 02 11:25:35 2017 +0530 +++ b/make/lib/Awt2dLibraries.gmk Sat Dec 02 06:51:10 2017 +0100 @@ -658,7 +658,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \ LIBRARY := fontmanager, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfontmanager, \ SRC := $(LIBFONTMANAGER_SRC), \ EXCLUDE_FILES := $(LIBFONTMANAGER_EXCLUDE_FILES) \ AccelGlyphCache.c, \ @@ -702,6 +702,21 @@ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfontmanager, \ )) +$(INSTALL_LIBRARIES_HERE)/$(call SHARED_LIBRARY,fontmanager): $(BUILD_LIBFONTMANAGER_TARGET) + $(install-file) + ifneq ($(FREETYPE_BUNDLE_LIB_PATH), ) + ifeq ($(OPENJDK_TARGET_OS), macosx) + # If bundling freetype on macosx, we need to rewrite the rpath location + # in the libfontmanager library to point to the bundled location + $(INSTALL_NAME_TOOL) -change \ + `$(OTOOL) -D $(FREETYPE_BUNDLE_LIB_PATH)/$(call SHARED_LIBRARY,freetype) | $(TAIL) -n1` \ + '@rpath/$(call SHARED_LIBRARY,freetype)' \ + $@ + endif + endif + +BUILD_LIBFONTMANAGER += $(INSTALL_LIBRARIES_HERE)/$(call SHARED_LIBRARY,fontmanager) + $(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT) ifneq (, $(findstring $(OPENJDK_TARGET_OS), solaris aix))
--- a/make/mapfiles/libjava/mapfile-vers Sat Dec 02 11:25:35 2017 +0530 +++ b/make/mapfiles/libjava/mapfile-vers Sat Dec 02 06:51:10 2017 +0100 @@ -205,10 +205,6 @@ Java_java_lang_Runtime_runFinalization0; Java_java_lang_Runtime_totalMemory; Java_java_lang_Runtime_availableProcessors; - Java_java_lang_SecurityManager_classDepth; - Java_java_lang_SecurityManager_classLoaderDepth0; - Java_java_lang_SecurityManager_currentClassLoader0; - Java_java_lang_SecurityManager_currentLoadedClass0; Java_java_lang_SecurityManager_getClassContext; Java_java_lang_Shutdown_halt0; Java_java_lang_StackTraceElement_initStackTraceElement;
--- a/make/nashorn/build.xml Sat Dec 02 11:25:35 2017 +0530 +++ b/make/nashorn/build.xml Sat Dec 02 06:51:10 2017 +0100 @@ -115,11 +115,11 @@ </target> - <!-- check minimum ant version required to be 1.8.4 --> + <!-- check minimum ant version required to be 1.9.5 --> <target name="check-ant-version"> - <property name="ant.version.required" value="1.8.4"/> + <property name="ant.version.required" value="1.9.5"/> <antversion property="ant.current.version" /> - <fail message="The current ant version, ${ant.current.version}, is too old. Please use 1.8.4 or above."> + <fail message="The current ant version, ${ant.current.version}, is too old. Please use 1.9.5 or above."> <condition> <not> <antversion atleast="${ant.version.required}"/>
--- a/src/hotspot/share/prims/jvm.cpp Sat Dec 02 11:25:35 2017 +0530 +++ b/src/hotspot/share/prims/jvm.cpp Sat Dec 02 06:51:10 2017 +0100 @@ -3129,64 +3129,6 @@ // java.lang.SecurityManager /////////////////////////////////////////////////////////////////////// -static bool is_trusted_frame(JavaThread* jthread, vframeStream* vfst) { - assert(jthread->is_Java_thread(), "must be a Java thread"); - if (jthread->privileged_stack_top() == NULL) return false; - if (jthread->privileged_stack_top()->frame_id() == vfst->frame_id()) { - oop loader = jthread->privileged_stack_top()->class_loader(); - if (loader == NULL) return true; - bool trusted = java_lang_ClassLoader::is_trusted_loader(loader); - if (trusted) return true; - } - return false; -} - -JVM_ENTRY(jclass, JVM_CurrentLoadedClass(JNIEnv *env)) - JVMWrapper("JVM_CurrentLoadedClass"); - ResourceMark rm(THREAD); - - for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { - // if a method in a class in a trusted loader is in a doPrivileged, return NULL - bool trusted = is_trusted_frame(thread, &vfst); - if (trusted) return NULL; - - Method* m = vfst.method(); - if (!m->is_native()) { - InstanceKlass* holder = m->method_holder(); - oop loader = holder->class_loader(); - if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) { - return (jclass) JNIHandles::make_local(env, holder->java_mirror()); - } - } - } - return NULL; -JVM_END - - -JVM_ENTRY(jobject, JVM_CurrentClassLoader(JNIEnv *env)) - JVMWrapper("JVM_CurrentClassLoader"); - ResourceMark rm(THREAD); - - for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { - - // if a method in a class in a trusted loader is in a doPrivileged, return NULL - bool trusted = is_trusted_frame(thread, &vfst); - if (trusted) return NULL; - - Method* m = vfst.method(); - if (!m->is_native()) { - InstanceKlass* holder = m->method_holder(); - assert(holder->is_klass(), "just checking"); - oop loader = holder->class_loader(); - if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) { - return JNIHandles::make_local(env, loader); - } - } - } - return NULL; -JVM_END - - JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env)) JVMWrapper("JVM_GetClassContext"); ResourceMark rm(THREAD); @@ -3226,58 +3168,6 @@ JVM_END -JVM_ENTRY(jint, JVM_ClassDepth(JNIEnv *env, jstring name)) - JVMWrapper("JVM_ClassDepth"); - ResourceMark rm(THREAD); - Handle h_name (THREAD, JNIHandles::resolve_non_null(name)); - Handle class_name_str = java_lang_String::internalize_classname(h_name, CHECK_0); - - const char* str = java_lang_String::as_utf8_string(class_name_str()); - TempNewSymbol class_name_sym = SymbolTable::probe(str, (int)strlen(str)); - if (class_name_sym == NULL) { - return -1; - } - - int depth = 0; - - for(vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { - if (!vfst.method()->is_native()) { - InstanceKlass* holder = vfst.method()->method_holder(); - assert(holder->is_klass(), "just checking"); - if (holder->name() == class_name_sym) { - return depth; - } - depth++; - } - } - return -1; -JVM_END - - -JVM_ENTRY(jint, JVM_ClassLoaderDepth(JNIEnv *env)) - JVMWrapper("JVM_ClassLoaderDepth"); - ResourceMark rm(THREAD); - int depth = 0; - for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { - // if a method in a class in a trusted loader is in a doPrivileged, return -1 - bool trusted = is_trusted_frame(thread, &vfst); - if (trusted) return -1; - - Method* m = vfst.method(); - if (!m->is_native()) { - InstanceKlass* holder = m->method_holder(); - assert(holder->is_klass(), "just checking"); - oop loader = holder->class_loader(); - if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) { - return depth; - } - depth++; - } - } - return -1; -JVM_END - - // java.lang.Package ////////////////////////////////////////////////////////////////
--- a/src/java.base/share/classes/java/lang/ClassLoader.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/lang/ClassLoader.java Sat Dec 02 06:51:10 2017 +0100 @@ -1813,7 +1813,7 @@ } /** - * Returns the platform class loader for delegation. All + * Returns the platform class loader. All * <a href="#builtinLoaders">platform classes</a> are visible to * the platform class loader. * @@ -1843,7 +1843,7 @@ } /** - * Returns the system class loader for delegation. This is the default + * Returns the system class loader. This is the default * delegation parent for new {@code ClassLoader} instances, and is * typically the class loader used to start the application. * @@ -1884,7 +1884,7 @@ * the application module path then the class path defaults to * the current working directory. * - * @return The system {@code ClassLoader} for delegation + * @return The system {@code ClassLoader} * * @throws SecurityException * If a security manager is present, and the caller's class loader
--- a/src/java.base/share/classes/java/lang/SecurityManager.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/lang/SecurityManager.java Sat Dec 02 06:51:10 2017 +0100 @@ -101,7 +101,7 @@ * <code>checkPermission</code> returns quietly. If denied, a * <code>SecurityException</code> is thrown. * <p> - * As of Java 2 SDK v1.2, the default implementation of each of the other + * The default implementation of each of the other * <code>check</code> methods in <code>SecurityManager</code> is to * call the <code>SecurityManager checkPermission</code> method * to determine if the calling thread has permission to perform the requested @@ -197,10 +197,10 @@ * See {@extLink security_guide_permissions * Permissions in the Java Development Kit (JDK)} * for permission-related information. - * This document includes, for example, a table listing the various SecurityManager + * This document includes a table listing the various SecurityManager * <code>check</code> methods and the permission(s) the default * implementation of each such method requires. - * It also contains a table of all the version 1.2 methods + * It also contains a table of the methods * that require permissions, and for each such method tells * which permission it requires. * @@ -228,20 +228,7 @@ * * @since 1.0 */ -public -class SecurityManager { - - /** - * This field is <code>true</code> if there is a security check in - * progress; <code>false</code> otherwise. - * - * @deprecated This type of security checking is not recommended. - * It is recommended that the <code>checkPermission</code> - * call be used instead. This field is subject to removal in a - * future version of Java SE. - */ - @Deprecated(since="1.2", forRemoval=true) - protected boolean inCheck; +public class SecurityManager { /* * Have we been initialized. Effective against finalizer attacks. @@ -262,24 +249,6 @@ } /** - * Tests if there is a security check in progress. - * - * @return the value of the <code>inCheck</code> field. This field - * should contain <code>true</code> if a security check is - * in progress, - * <code>false</code> otherwise. - * @see java.lang.SecurityManager#inCheck - * @deprecated This type of security checking is not recommended. - * It is recommended that the <code>checkPermission</code> - * call be used instead. This method is subject to removal in a - * future version of Java SE. - */ - @Deprecated(since="1.2", forRemoval=true) - public boolean getInCheck() { - return inCheck; - } - - /** * Constructs a new <code>SecurityManager</code>. * * <p> If there is a security manager already installed, this method first @@ -322,198 +291,6 @@ protected native Class<?>[] getClassContext(); /** - * Returns the class loader of the most recently executing method from - * a class defined using a non-system class loader. A non-system - * class loader is defined as being a class loader that is not equal to - * the system class loader (as returned - * by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors. - * <p> - * This method will return - * <code>null</code> in the following three cases: - * <ol> - * <li>All methods on the execution stack are from classes - * defined using the system class loader or one of its ancestors. - * - * <li>All methods on the execution stack up to the first - * "privileged" caller - * (see {@link java.security.AccessController#doPrivileged}) - * are from classes - * defined using the system class loader or one of its ancestors. - * - * <li> A call to <code>checkPermission</code> with - * <code>java.security.AllPermission</code> does not - * result in a SecurityException. - * - * </ol> - * - * @return the class loader of the most recent occurrence on the stack - * of a method from a class defined using a non-system class - * loader. - * - * @deprecated This type of security checking is not recommended. - * It is recommended that the <code>checkPermission</code> - * call be used instead. This method is subject to removal in a - * future version of Java SE. - * - * @see java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader - * @see #checkPermission(java.security.Permission) checkPermission - */ - @Deprecated(since="1.2", forRemoval=true) - protected ClassLoader currentClassLoader() { - ClassLoader cl = currentClassLoader0(); - if ((cl != null) && hasAllPermission()) - cl = null; - return cl; - } - - private native ClassLoader currentClassLoader0(); - - /** - * Returns the class of the most recently executing method from - * a class defined using a non-system class loader. A non-system - * class loader is defined as being a class loader that is not equal to - * the system class loader (as returned - * by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors. - * <p> - * This method will return - * <code>null</code> in the following three cases: - * <ol> - * <li>All methods on the execution stack are from classes - * defined using the system class loader or one of its ancestors. - * - * <li>All methods on the execution stack up to the first - * "privileged" caller - * (see {@link java.security.AccessController#doPrivileged}) - * are from classes - * defined using the system class loader or one of its ancestors. - * - * <li> A call to <code>checkPermission</code> with - * <code>java.security.AllPermission</code> does not - * result in a SecurityException. - * - * </ol> - * - * @return the class of the most recent occurrence on the stack - * of a method from a class defined using a non-system class - * loader. - * - * @deprecated This type of security checking is not recommended. - * It is recommended that the <code>checkPermission</code> - * call be used instead. This method is subject to removal in a - * future version of Java SE. - * - * @see java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader - * @see #checkPermission(java.security.Permission) checkPermission - */ - @Deprecated(since="1.2", forRemoval=true) - protected Class<?> currentLoadedClass() { - Class<?> c = currentLoadedClass0(); - if ((c != null) && hasAllPermission()) - c = null; - return c; - } - - /** - * Returns the stack depth of the specified class. - * - * @param name the fully qualified name of the class to search for. - * @return the depth on the stack frame of the first occurrence of a - * method from a class with the specified name; - * <code>-1</code> if such a frame cannot be found. - * @deprecated This type of security checking is not recommended. - * It is recommended that the <code>checkPermission</code> - * call be used instead. This method is subject to removal in a - * future version of Java SE. - */ - @Deprecated(since="1.2", forRemoval=true) - protected native int classDepth(String name); - - /** - * Returns the stack depth of the most recently executing method - * from a class defined using a non-system class loader. A non-system - * class loader is defined as being a class loader that is not equal to - * the system class loader (as returned - * by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors. - * <p> - * This method will return - * -1 in the following three cases: - * <ol> - * <li>All methods on the execution stack are from classes - * defined using the system class loader or one of its ancestors. - * - * <li>All methods on the execution stack up to the first - * "privileged" caller - * (see {@link java.security.AccessController#doPrivileged}) - * are from classes - * defined using the system class loader or one of its ancestors. - * - * <li> A call to <code>checkPermission</code> with - * <code>java.security.AllPermission</code> does not - * result in a SecurityException. - * - * </ol> - * - * @return the depth on the stack frame of the most recent occurrence of - * a method from a class defined using a non-system class loader. - * - * @deprecated This type of security checking is not recommended. - * It is recommended that the <code>checkPermission</code> - * call be used instead. This method is subject to removal in a - * future version of Java SE. - * - * @see java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader - * @see #checkPermission(java.security.Permission) checkPermission - */ - @Deprecated(since="1.2", forRemoval=true) - protected int classLoaderDepth() { - int depth = classLoaderDepth0(); - if (depth != -1) { - if (hasAllPermission()) - depth = -1; - else - depth--; // make sure we don't include ourself - } - return depth; - } - - private native int classLoaderDepth0(); - - /** - * Tests if a method from a class with the specified - * name is on the execution stack. - * - * @param name the fully qualified name of the class. - * @return <code>true</code> if a method from a class with the specified - * name is on the execution stack; <code>false</code> otherwise. - * @deprecated This type of security checking is not recommended. - * It is recommended that the <code>checkPermission</code> - * call be used instead. This method is subject to removal in a - * future version of Java SE. - */ - @Deprecated(since="1.2", forRemoval=true) - protected boolean inClass(String name) { - return classDepth(name) >= 0; - } - - /** - * Basically, tests if a method from a class defined using a - * class loader is on the execution stack. - * - * @return <code>true</code> if a call to <code>currentClassLoader</code> - * has a non-null return value. - * - * @deprecated This type of security checking is not recommended. - * It is recommended that the <code>checkPermission</code> - * call be used instead. This method is subject to removal in a - * future version of Java SE. - * @see #currentClassLoader() currentClassLoader - */ - @Deprecated(since="1.2", forRemoval=true) - protected boolean inClassLoader() { - return currentClassLoader() != null; - } - - /** * Creates an object that encapsulates the current execution * environment. The result of this method is used, for example, by the * three-argument <code>checkConnect</code> method and by the @@ -1698,64 +1475,32 @@ } /** - * Throws a <code>SecurityException</code> if the - * calling thread is not allowed to access members. - * <p> - * The default policy is to allow access to PUBLIC members, as well - * as access to classes that have the same class loader as the caller. - * In all other cases, this method calls <code>checkPermission</code> - * with the <code>RuntimePermission("accessDeclaredMembers") - * </code> permission. - * <p> - * If this method is overridden, then a call to - * <code>super.checkMemberAccess</code> cannot be made, - * as the default implementation of <code>checkMemberAccess</code> - * relies on the code being checked being at a stack depth of - * 4. + * Throws a {@code SecurityException} if the calling thread does + * not have {@code AllPermission}. * * @param clazz the class that reflection is to be performed on. - * * @param which type of access, PUBLIC or DECLARED. - * - * @exception SecurityException if the caller does not have - * permission to access members. - * @exception NullPointerException if the <code>clazz</code> argument is - * <code>null</code>. - * - * @deprecated This method relies on the caller being at a stack depth - * of 4 which is error-prone and cannot be enforced by the runtime. - * Users of this method should instead invoke {@link #checkPermission} - * directly. - * This method is subject to removal in a future version of Java SE. - * - * @see java.lang.reflect.Member + * @throws SecurityException if the caller does not have + * {@code AllPermission} + * @throws NullPointerException if the {@code clazz} argument is + * {@code null} + * @deprecated This method was originally used to check if the calling + * thread was allowed to access members. It relied on the + * caller being at a stack depth of 4 which is error-prone and + * cannot be enforced by the runtime. The method has been + * obsoleted and code should instead use + * {@link #checkPermission} to check + * {@code RuntimePermission("accessDeclaredMembers")}. This + * method is subject to removal in a future version of Java SE. * @since 1.1 * @see #checkPermission(java.security.Permission) checkPermission */ @Deprecated(since="1.8", forRemoval=true) - @CallerSensitive public void checkMemberAccess(Class<?> clazz, int which) { if (clazz == null) { throw new NullPointerException("class can't be null"); } - if (which != Member.PUBLIC) { - Class<?> stack[] = getClassContext(); - /* - * stack depth of 4 should be the caller of one of the - * methods in java.lang.Class that invoke checkMember - * access. The stack should look like: - * - * someCaller [3] - * java.lang.Class.someReflectionAPI [2] - * java.lang.Class.checkMemberAccess [1] - * SecurityManager.checkMemberAccess [0] - * - */ - if ((stack.length<4) || - (stack[3].getClassLoader() != clazz.getClassLoader())) { - checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION); - } - } + checkPermission(SecurityConstants.ALL_PERMISSION); } /** @@ -1792,8 +1537,6 @@ checkPermission(new SecurityPermission(target)); } - private native Class<?> currentLoadedClass0(); - /** * Returns the thread group into which to instantiate any new * thread being created at the time this is being called.
--- a/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java Sat Dec 02 06:51:10 2017 +0100 @@ -263,8 +263,12 @@ * methods from {@code Object}. * * @param caller Represents a lookup context with the accessibility - * privileges of the caller. When used with {@code invokedynamic}, - * this is stacked automatically by the VM. + * privileges of the caller. Specifically, the lookup context + * must have + * <a href="MethodHandles.Lookup.html#privacc">private access</a> + * privileges. + * When used with {@code invokedynamic}, this is stacked + * automatically by the VM. * @param invokedName The name of the method to implement. When used with * {@code invokedynamic}, this is provided by the * {@code NameAndType} of the {@code InvokeDynamic} @@ -294,7 +298,8 @@ * instances of the interface named by {@code invokedType} * @throws LambdaConversionException If any of the linkage invariants * described {@link LambdaMetafactory above} - * are violated + * are violated, or the lookup context + * does not have private access privileges. */ public static CallSite metafactory(MethodHandles.Lookup caller, String invokedName, @@ -404,8 +409,12 @@ * </ul> * * @param caller Represents a lookup context with the accessibility - * privileges of the caller. When used with {@code invokedynamic}, - * this is stacked automatically by the VM. + * privileges of the caller. Specifically, the lookup context + * must have + * <a href="MethodHandles.Lookup.html#privacc">private access</a> + * privileges. + * When used with {@code invokedynamic}, this is stacked + * automatically by the VM. * @param invokedName The name of the method to implement. When used with * {@code invokedynamic}, this is provided by the * {@code NameAndType} of the {@code InvokeDynamic} @@ -429,7 +438,8 @@ * instances of the interface named by {@code invokedType} * @throws LambdaConversionException If any of the linkage invariants * described {@link LambdaMetafactory above} - * are violated + * are violated, or the lookup context + * does not have private access privileges. */ public static CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName,
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Sat Dec 02 06:51:10 2017 +0100 @@ -385,9 +385,16 @@ * invoked, it returns the result of String concatenation, taking all * function arguments passed to the linkage method as inputs for * concatenation. The target signature is given by {@code concatType}. - * The arguments are concatenated as per requirements stated in JLS 15.18.1 - * "String Concatenation Operator +". Notably, the inputs are converted as - * per JLS 5.1.11 "String Conversion", and combined from left to right. + * For a target accepting: + * <ul> + * <li>zero inputs, concatenation results in an empty string;</li> + * <li>one input, concatenation results in the single + * input converted as per JLS 5.1.11 "String Conversion"; otherwise</li> + * <li>two or more inputs, the inputs are concatenated as per + * requirements stated in JLS 15.18.1 "String Concatenation Operator +". + * The inputs are converted as per JLS 5.1.11 "String Conversion", + * and combined from left to right.</li> + * </ul> * * <p>Assume the linkage arguments are as follows: * @@ -404,8 +411,12 @@ * </ul> * * @param lookup Represents a lookup context with the accessibility - * privileges of the caller. When used with {@code - * invokedynamic}, this is stacked automatically by the VM. + * privileges of the caller. Specifically, the lookup + * context must have + * <a href="MethodHandles.Lookup.html#privacc">private access</a> + * privileges. + * When used with {@code invokedynamic}, this is stacked + * automatically by the VM. * @param name The name of the method to implement. This name is * arbitrary, and has no meaning for this linkage method. * When used with {@code invokedynamic}, this is provided by @@ -422,7 +433,8 @@ * concatenation, with dynamic concatenation arguments described by the given * {@code concatType}. * @throws StringConcatException If any of the linkage invariants described - * here are violated. + * here are violated, or the lookup context + * does not have private access privileges. * @throws NullPointerException If any of the incoming arguments is null. * This will never happen when a bootstrap method * is called with invokedynamic. @@ -452,10 +464,17 @@ * invoked, it returns the result of String concatenation, taking all * function arguments and constants passed to the linkage method as inputs for * concatenation. The target signature is given by {@code concatType}, and - * does not include constants. The arguments are concatenated as per requirements - * stated in JLS 15.18.1 "String Concatenation Operator +". Notably, the inputs - * are converted as per JLS 5.1.11 "String Conversion", and combined from left - * to right. + * does not include constants. + * For a target accepting: + * <ul> + * <li>zero inputs, concatenation results in an empty string;</li> + * <li>one input, concatenation results in the single + * input converted as per JLS 5.1.11 "String Conversion"; otherwise</li> + * <li>two or more inputs, the inputs are concatenated as per + * requirements stated in JLS 15.18.1 "String Concatenation Operator +". + * The inputs are converted as per JLS 5.1.11 "String Conversion", + * and combined from left to right.</li> + * </ul> * * <p>The concatenation <em>recipe</em> is a String description for the way to * construct a concatenated String from the arguments and constants. The @@ -502,9 +521,12 @@ * </ul> * * @param lookup Represents a lookup context with the accessibility - * privileges of the caller. When used with {@code - * invokedynamic}, this is stacked automatically by the - * VM. + * privileges of the caller. Specifically, the lookup + * context must have + * <a href="MethodHandles.Lookup.html#privacc">private access</a> + * privileges. + * When used with {@code invokedynamic}, this is stacked + * automatically by the VM. * @param name The name of the method to implement. This name is * arbitrary, and has no meaning for this linkage method. * When used with {@code invokedynamic}, this is provided @@ -524,7 +546,8 @@ * concatenation, with dynamic concatenation arguments described by the given * {@code concatType}. * @throws StringConcatException If any of the linkage invariants described - * here are violated. + * here are violated, or the lookup context + * does not have private access privileges. * @throws NullPointerException If any of the incoming arguments is null, or * any constant in {@code recipe} is null. * This will never happen when a bootstrap method
--- a/src/java.base/share/classes/java/security/interfaces/DSAKeyPairGenerator.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/security/interfaces/DSAKeyPairGenerator.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,9 +32,12 @@ * * <p>The {@code initialize} methods may each be called any number * of times. If no {@code initialize} method is called on a - * DSAKeyPairGenerator, the default is to generate 1024-bit keys, using - * precomputed p, q and g parameters and an instance of SecureRandom as - * the random bit source. + * DSAKeyPairGenerator, each provider that implements this interface + * should supply (and document) a default initialization. Note that + * defaults may vary across different providers. Additionally, the default + * value for a provider may change in a future version. Therefore, it is + * recommended to explicitly initialize the DSAKeyPairGenerator instead + * of relying on provider-specific defaults. * * <p>Users wishing to indicate DSA-specific parameters, and to generate a key * pair suitable for use with the DSA algorithm typically @@ -45,12 +48,13 @@ * KeyPairGenerator {@code getInstance} method with "DSA" * as its argument. * - * <li>Initialize the generator by casting the result to a DSAKeyPairGenerator - * and calling one of the - * {@code initialize} methods from this DSAKeyPairGenerator interface. + * <li>Check if the returned key pair generator is an instance of + * DSAKeyPairGenerator before casting the result to a DSAKeyPairGenerator + * and calling one of the {@code initialize} methods from this + * DSAKeyPairGenerator interface. * * <li>Generate a key pair by calling the {@code generateKeyPair} - * method from the KeyPairGenerator class. + * method of the KeyPairGenerator class. * * </ol> * @@ -63,7 +67,7 @@ * parameters. * * <p>Note: Some earlier implementations of this interface may not support - * larger sizes of DSA parameters such as 2048 and 3072-bit. + * larger values of DSA parameters such as 3072-bit. * * @since 1.1 * @see java.security.KeyPairGenerator @@ -97,8 +101,7 @@ * p, q and g parameters. If it is false, the method uses precomputed * parameters for the modulus length requested. If there are no * precomputed parameters for that modulus length, an exception will be - * thrown. It is guaranteed that there will always be - * default parameters for modulus lengths of 512 and 1024 bits. + * thrown. * * @param modlen the modulus length in bits. Valid values are any * multiple of 64 between 512 and 1024, inclusive, 2048, and 3072.
--- a/src/java.base/share/classes/java/text/DateFormat.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/text/DateFormat.java Sat Dec 02 06:51:10 2017 +0100 @@ -294,28 +294,27 @@ private static final long serialVersionUID = 7218322306649953788L; /** - * Overrides Format. - * Formats a time object into a time string. Examples of time objects - * are a time value expressed in milliseconds and a Date object. - * @param obj must be a Number or a Date. - * @param toAppendTo the string buffer for the returning time string. - * @return the string buffer passed in as toAppendTo, with formatted text appended. - * @param fieldPosition keeps track of the position of the field - * within the returned string. - * On input: an alignment field, - * if desired. On output: the offsets of the alignment field. For - * example, given a time text "1996.07.10 AD at 15:08:56 PDT", - * if the given fieldPosition is DateFormat.YEAR_FIELD, the - * begin index and end index of fieldPosition will be set to - * 0 and 4, respectively. - * Notice that if the same time field appears - * more than once in a pattern, the fieldPosition will be set for the first - * occurrence of that time field. For instance, formatting a Date to - * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern - * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD, - * the begin index and end index of fieldPosition will be set to - * 5 and 8, respectively, for the first occurrence of the timezone - * pattern character 'z'. + * Formats the given {@code Object} into a date-time string. The formatted + * string is appended to the given {@code StringBuffer}. + * + * @param obj Must be a {@code Date} or a {@code Number} representing a + * millisecond offset from the <a href="../util/Calendar.html#Epoch">Epoch</a>. + * @param toAppendTo The string buffer for the returning date-time string. + * @param fieldPosition keeps track on the position of the field within + * the returned string. For example, given a date-time text + * {@code "1996.07.10 AD at 15:08:56 PDT"}, if the given {@code fieldPosition} + * is {@link DateFormat#YEAR_FIELD}, the begin index and end index of + * {@code fieldPosition} will be set to 0 and 4, respectively. + * Notice that if the same date-time field appears more than once in a + * pattern, the {@code fieldPosition} will be set for the first occurrence + * of that date-time field. For instance, formatting a {@code Date} to the + * date-time string {@code "1 PM PDT (Pacific Daylight Time)"} using the + * pattern {@code "h a z (zzzz)"} and the alignment field + * {@link DateFormat#TIMEZONE_FIELD}, the begin index and end index of + * {@code fieldPosition} will be set to 5 and 8, respectively, for the + * first occurrence of the timezone pattern character {@code 'z'}. + * @return the string buffer passed in as {@code toAppendTo}, + * with formatted text appended. * @exception IllegalArgumentException if the {@code Format} cannot format * the given {@code obj}. * @see java.text.Format @@ -333,34 +332,35 @@ } /** - * Formats a Date into a date/time string. - * @param date a Date to be formatted into a date/time string. - * @param toAppendTo the string buffer for the returning date/time string. - * @param fieldPosition keeps track of the position of the field - * within the returned string. - * On input: an alignment field, - * if desired. On output: the offsets of the alignment field. For - * example, given a time text "1996.07.10 AD at 15:08:56 PDT", - * if the given fieldPosition is DateFormat.YEAR_FIELD, the - * begin index and end index of fieldPosition will be set to - * 0 and 4, respectively. - * Notice that if the same time field appears - * more than once in a pattern, the fieldPosition will be set for the first - * occurrence of that time field. For instance, formatting a Date to - * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern - * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD, - * the begin index and end index of fieldPosition will be set to - * 5 and 8, respectively, for the first occurrence of the timezone - * pattern character 'z'. - * @return the string buffer passed in as toAppendTo, with formatted text appended. + * Formats a {@link Date} into a date-time string. The formatted + * string is appended to the given {@code StringBuffer}. + * + * @param date a Date to be formatted into a date-time string. + * @param toAppendTo the string buffer for the returning date-time string. + * @param fieldPosition keeps track on the position of the field within + * the returned string. For example, given a date-time text + * {@code "1996.07.10 AD at 15:08:56 PDT"}, if the given {@code fieldPosition} + * is {@link DateFormat#YEAR_FIELD}, the begin index and end index of + * {@code fieldPosition} will be set to 0 and 4, respectively. + * Notice that if the same date-time field appears more than once in a + * pattern, the {@code fieldPosition} will be set for the first occurrence + * of that date-time field. For instance, formatting a {@code Date} to the + * date-time string {@code "1 PM PDT (Pacific Daylight Time)"} using the + * pattern {@code "h a z (zzzz)"} and the alignment field + * {@link DateFormat#TIMEZONE_FIELD}, the begin index and end index of + * {@code fieldPosition} will be set to 5 and 8, respectively, for the + * first occurrence of the timezone pattern character {@code 'z'}. + * @return the string buffer passed in as {@code toAppendTo}, with formatted + * text appended. */ public abstract StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition); /** - * Formats a Date into a date/time string. - * @param date the time value to be formatted into a time string. - * @return the formatted time string. + * Formats a {@link Date} into a date-time string. + * + * @param date the time value to be formatted into a date-time string. + * @return the formatted date-time string. */ public final String format(Date date) {
--- a/src/java.base/share/classes/java/text/DecimalFormat.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/text/DecimalFormat.java Sat Dec 02 06:51:10 2017 +0100 @@ -480,8 +480,14 @@ * @param number the number to format * @param toAppendTo the <code>StringBuffer</code> to which the formatted * text is to be appended - * @param pos On input: an alignment field, if desired. - * On output: the offsets of the alignment field. + * @param pos keeps track on the position of the field within the + * returned string. For example, for formatting a number + * {@code 1234567.89} in {@code Locale.US} locale, + * if the given {@code fieldPosition} is + * {@link NumberFormat#INTEGER_FIELD}, the begin index + * and end index of {@code fieldPosition} will be set + * to 0 and 9, respectively for the output string + * {@code 1,234,567.89}. * @return the value passed in as <code>toAppendTo</code> * @exception IllegalArgumentException if <code>number</code> is * null or not an instance of <code>Number</code>. @@ -517,8 +523,14 @@ * Formats a double to produce a string. * @param number The double to format * @param result where the text is to be appended - * @param fieldPosition On input: an alignment field, if desired. - * On output: the offsets of the alignment field. + * @param fieldPosition keeps track on the position of the field within + * the returned string. For example, for formatting + * a number {@code 1234567.89} in {@code Locale.US} + * locale, if the given {@code fieldPosition} is + * {@link NumberFormat#INTEGER_FIELD}, the begin index + * and end index of {@code fieldPosition} will be set + * to 0 and 9, respectively for the output string + * {@code 1,234,567.89}. * @exception NullPointerException if {@code result} or * {@code fieldPosition} is {@code null} * @exception ArithmeticException if rounding is needed with rounding @@ -637,8 +649,14 @@ * Format a long to produce a string. * @param number The long to format * @param result where the text is to be appended - * @param fieldPosition On input: an alignment field, if desired. - * On output: the offsets of the alignment field. + * @param fieldPosition keeps track on the position of the field within + * the returned string. For example, for formatting + * a number {@code 123456789} in {@code Locale.US} + * locale, if the given {@code fieldPosition} is + * {@link NumberFormat#INTEGER_FIELD}, the begin index + * and end index of {@code fieldPosition} will be set + * to 0 and 11, respectively for the output string + * {@code 123,456,789}. * @exception NullPointerException if {@code result} or * {@code fieldPosition} is {@code null} * @exception ArithmeticException if rounding is needed with rounding @@ -727,8 +745,14 @@ * Formats a BigDecimal to produce a string. * @param number The BigDecimal to format * @param result where the text is to be appended - * @param fieldPosition On input: an alignment field, if desired. - * On output: the offsets of the alignment field. + * @param fieldPosition keeps track on the position of the field within + * the returned string. For example, for formatting + * a number {@code 1234567.89} in {@code Locale.US} + * locale, if the given {@code fieldPosition} is + * {@link NumberFormat#INTEGER_FIELD}, the begin index + * and end index of {@code fieldPosition} will be set + * to 0 and 9, respectively for the output string + * {@code 1,234,567.89}. * @return The formatted number string * @exception ArithmeticException if rounding is needed with rounding * mode being set to RoundingMode.UNNECESSARY @@ -780,8 +804,14 @@ * Format a BigInteger to produce a string. * @param number The BigInteger to format * @param result where the text is to be appended - * @param fieldPosition On input: an alignment field, if desired. - * On output: the offsets of the alignment field. + * @param fieldPosition keeps track on the position of the field within + * the returned string. For example, for formatting + * a number {@code 123456789} in {@code Locale.US} + * locale, if the given {@code fieldPosition} is + * {@link NumberFormat#INTEGER_FIELD}, the begin index + * and end index of {@code fieldPosition} will be set + * to 0 and 11, respectively for the output string + * {@code 123,456,789}. * @return The formatted number string * @exception ArithmeticException if rounding is needed with rounding * mode being set to RoundingMode.UNNECESSARY
--- a/src/java.base/share/classes/java/text/MessageFormat.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/text/MessageFormat.java Sat Dec 02 06:51:10 2017 +0100 @@ -820,8 +820,8 @@ * * @param arguments an array of objects to be formatted and substituted. * @param result where text is appended. - * @param pos On input: an alignment field, if desired. - * On output: the offsets of the alignment field. + * @param pos keeps track on the position of the first replaced argument + in the output string. * @return the string buffer passed in as {@code result}, with formatted * text appended * @exception IllegalArgumentException if an argument in the @@ -868,8 +868,8 @@ * * @param arguments an array of objects to be formatted and substituted. * @param result where text is appended. - * @param pos On input: an alignment field, if desired. - * On output: the offsets of the alignment field. + * @param pos keeps track on the position of the first replaced argument + * in the output string. * @exception IllegalArgumentException if an argument in the * <code>arguments</code> array is not of the type * expected by the format element(s) that use it. @@ -1239,11 +1239,11 @@ private int maxOffset = -1; /** - * Internal routine used by format. If <code>characterIterators</code> is - * non-null, AttributedCharacterIterator will be created from the - * subformats as necessary. If <code>characterIterators</code> is null - * and <code>fp</code> is non-null and identifies - * <code>Field.MESSAGE_ARGUMENT</code>, the location of + * Internal routine used by format. If {@code characterIterators} is + * {@code non-null}, AttributedCharacterIterator will be created from the + * subformats as necessary. If {@code characterIterators} is {@code null} + * and {@code fp} is {@code non-null} and identifies + * {@code Field.ARGUMENT} as the field attribute, the location of * the first replaced argument will be set in it. * * @exception IllegalArgumentException if an argument in the
--- a/src/java.base/share/classes/java/text/NumberFormat.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/text/NumberFormat.java Sat Dec 02 06:51:10 2017 +0100 @@ -240,8 +240,14 @@ * @param number the number to format * @param toAppendTo the <code>StringBuffer</code> to which the formatted * text is to be appended - * @param pos On input: an alignment field, if desired. - * On output: the offsets of the alignment field. + * @param pos keeps track on the position of the field within the + * returned string. For example, for formatting a number + * {@code 1234567.89} in {@code Locale.US} locale, + * if the given {@code fieldPosition} is + * {@link NumberFormat#INTEGER_FIELD}, the begin index + * and end index of {@code fieldPosition} will be set + * to 0 and 9, respectively for the output string + * {@code 1,234,567.89}. * @return the value passed in as <code>toAppendTo</code> * @exception IllegalArgumentException if <code>number</code> is * null or not an instance of <code>Number</code>. @@ -342,7 +348,14 @@ * @param number the double number to format * @param toAppendTo the StringBuffer to which the formatted text is to be * appended - * @param pos the field position + * @param pos keeps track on the position of the field within the + * returned string. For example, for formatting a number + * {@code 1234567.89} in {@code Locale.US} locale, + * if the given {@code fieldPosition} is + * {@link NumberFormat#INTEGER_FIELD}, the begin index + * and end index of {@code fieldPosition} will be set + * to 0 and 9, respectively for the output string + * {@code 1,234,567.89}. * @return the formatted StringBuffer * @exception ArithmeticException if rounding is needed with rounding * mode being set to RoundingMode.UNNECESSARY @@ -358,7 +371,14 @@ * @param number the long number to format * @param toAppendTo the StringBuffer to which the formatted text is to be * appended - * @param pos the field position + * @param pos keeps track on the position of the field within the + * returned string. For example, for formatting a number + * {@code 123456789} in {@code Locale.US} locale, + * if the given {@code fieldPosition} is + * {@link NumberFormat#INTEGER_FIELD}, the begin index + * and end index of {@code fieldPosition} will be set + * to 0 and 11, respectively for the output string + * {@code 123,456,789}. * @return the formatted StringBuffer * @exception ArithmeticException if rounding is needed with rounding * mode being set to RoundingMode.UNNECESSARY
--- a/src/java.base/share/classes/java/text/SimpleDateFormat.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/text/SimpleDateFormat.java Sat Dec 02 06:51:10 2017 +0100 @@ -942,8 +942,19 @@ * * @param date the date-time value to be formatted into a date-time string. * @param toAppendTo where the new date-time text is to be appended. - * @param pos the formatting position. On input: an alignment field, - * if desired. On output: the offsets of the alignment field. + * @param pos keeps track on the position of the field within + * the returned string. For example, given a date-time text + * {@code "1996.07.10 AD at 15:08:56 PDT"}, if the given {@code fieldPosition} + * is {@link DateFormat#YEAR_FIELD}, the begin index and end index of + * {@code fieldPosition} will be set to 0 and 4, respectively. + * Notice that if the same date-time field appears more than once in a + * pattern, the {@code fieldPosition} will be set for the first occurrence + * of that date-time field. For instance, formatting a {@code Date} to the + * date-time string {@code "1 PM PDT (Pacific Daylight Time)"} using the + * pattern {@code "h a z (zzzz)"} and the alignment field + * {@link DateFormat#TIMEZONE_FIELD}, the begin index and end index of + * {@code fieldPosition} will be set to 5 and 8, respectively, for the + * first occurrence of the timezone pattern character {@code 'z'}. * @return the formatted date-time string. * @exception NullPointerException if any of the parameters is {@code null}. */
--- a/src/java.base/share/classes/java/util/Collection.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/Collection.java Sat Dec 02 06:51:10 2017 +0100 @@ -192,7 +192,8 @@ * Returns an array containing all of the elements in this collection. * If this collection makes any guarantees as to what order its elements * are returned by its iterator, this method must return the elements in - * the same order. + * the same order. The returned array's {@linkplain Class#getComponentType + * runtime component type} is {@code Object}. * * <p>The returned array will be "safe" in that no references to it are * maintained by this collection. (In other words, this method must @@ -202,7 +203,8 @@ * <p>This method acts as bridge between array-based and collection-based * APIs. * - * @return an array containing all of the elements in this collection + * @return an array, whose {@linkplain Class#getComponentType runtime component + * type} is {@code Object}, containing all of the elements in this collection */ Object[] toArray(); @@ -239,14 +241,14 @@ * Note that {@code toArray(new Object[0])} is identical in function to * {@code toArray()}. * - * @param <T> the runtime type of the array to contain the collection + * @param <T> the component type of the array to contain the collection * @param a the array into which the elements of this collection 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 collection - * @throws ArrayStoreException if the runtime type of the specified array - * is not a supertype of the runtime type of every element in - * this collection + * @throws ArrayStoreException if the runtime type of any element in this + * collection is not assignable to the {@linkplain Class#getComponentType + * runtime component type} of the specified array * @throws NullPointerException if the specified array is null */ <T> T[] toArray(T[] a);
--- a/src/java.base/share/classes/java/util/jar/JarEntry.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/jar/JarEntry.java Sat Dec 02 06:51:10 2017 +0100 @@ -128,4 +128,25 @@ public CodeSigner[] getCodeSigners() { return signers == null ? null : signers.clone(); } + + /** + * Returns the real name of this {@code JarEntry}. + * + * If this {@code JarEntry} is an entry of a + * <a href="JarFile.html#multirelease">multi-release jar file</a> and the + * {@code JarFile} is configured to be processed as such, the name returned + * by this method is the path name of the versioned entry that the + * {@code JarEntry} represents, rather than the path name of the base entry + * that {@link #getName()} returns. If the {@code JarEntry} does not represent + * a versioned entry of a multi-release {@code JarFile} or the {@code JarFile} + * is not configured for processing a multi-release jar file, this method + * returns the same name that {@link #getName()} returns. + * + * @return the real name of the JarEntry + * + * @since 10 + */ + public String getRealName() { + return super.getName(); + } }
--- a/src/java.base/share/classes/java/util/jar/JarFile.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/jar/JarFile.java Sat Dec 02 06:51:10 2017 +0100 @@ -26,6 +26,7 @@ package java.util.jar; import jdk.internal.misc.SharedSecrets; +import jdk.internal.misc.JavaUtilZipFileAccess; import sun.security.action.GetPropertyAction; import sun.security.util.ManifestEntryVerifier; import sun.security.util.SignatureFileVerifier; @@ -45,10 +46,12 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Spliterator; import java.util.Spliterators; +import java.util.stream.Collector; import java.util.stream.Stream; import java.util.stream.StreamSupport; import java.util.zip.ZipEntry; @@ -163,9 +166,13 @@ // true if manifest checked for special attributes private volatile boolean hasCheckedSpecialAttributes; + private static final JavaUtilZipFileAccess JUZFA; + static { // Set up JavaUtilJarAccess in SharedSecrets SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl()); + // Get JavaUtilZipFileAccess from SharedSecrets + JUZFA = jdk.internal.misc.SharedSecrets.getJavaUtilZipFileAccess(); // multi-release jar file versions >= 9 BASE_VERSION = Runtime.Version.parse(Integer.toString(8)); BASE_VERSION_MAJOR = BASE_VERSION.major(); @@ -424,8 +431,7 @@ } private String[] getMetaInfEntryNames() { - return jdk.internal.misc.SharedSecrets.getJavaUtilZipFileAccess() - .getMetaInfEntryNames((ZipFile)this); + return JUZFA.getMetaInfEntryNames((ZipFile)this); } /** @@ -497,47 +503,11 @@ * </div> */ public ZipEntry getEntry(String name) { - ZipEntry ze = super.getEntry(name); - if (ze != null) { - return new JarFileEntry(ze); + JarFileEntry je = getEntry0(name); + if (isMultiRelease()) { + return getVersionedEntry(name, je); } - // no matching base entry, but maybe there is a versioned entry, - // like a new private class - if (isMultiRelease()) { - ze = new ZipEntry(name); - ZipEntry vze = getVersionedEntry(ze); - if (ze != vze) { - return new JarFileEntry(name, vze); - } - } - return null; - } - - private class JarEntryIterator implements Enumeration<JarEntry>, - Iterator<JarEntry> - { - final Enumeration<? extends ZipEntry> e = JarFile.super.entries(); - - public boolean hasNext() { - return e.hasMoreElements(); - } - - public JarEntry next() { - ZipEntry ze = e.nextElement(); - return new JarFileEntry(ze.getName(), ze); - } - - public boolean hasMoreElements() { - return hasNext(); - } - - public JarEntry nextElement() { - return next(); - } - - public Iterator<JarEntry> asIterator() { - return this; - } + return je; } /** @@ -548,7 +518,7 @@ * may be thrown if the jar file has been closed */ public Enumeration<JarEntry> entries() { - return new JarEntryIterator(); + return JUZFA.entries(this, JarFileEntry::new); } /** @@ -561,68 +531,100 @@ * @since 1.8 */ public Stream<JarEntry> stream() { - return StreamSupport.stream(Spliterators.spliterator( - new JarEntryIterator(), size(), - Spliterator.ORDERED | Spliterator.DISTINCT | - Spliterator.IMMUTABLE | Spliterator.NONNULL), false); - } - - private ZipEntry searchForVersionedEntry(final int version, String name) { - ZipEntry vze = null; - String sname = "/" + name; - int i = version; - while (i > BASE_VERSION_MAJOR) { - vze = super.getEntry(META_INF_VERSIONS + i + sname); - if (vze != null) break; - i--; - } - return vze; - } - - private ZipEntry getVersionedEntry(ZipEntry ze) { - ZipEntry vze = null; - if (BASE_VERSION_MAJOR < versionMajor) { - String name = ze.getName(); - if (!name.startsWith(META_INF)) { - vze = searchForVersionedEntry(versionMajor, name); - } - } - return vze == null ? ze : vze; + return JUZFA.stream(this, JarFileEntry::new); } /** - * Returns the real name of a {@code JarEntry}. If this {@code JarFile} is - * a multi-release jar file and is configured to be processed as such, the - * name returned by this method is the path name of the versioned entry - * that the {@code JarEntry} represents, rather than the path name of the - * base entry that {@link JarEntry#getName()} returns. If the - * {@code JarEntry} does not represent a versioned entry, or the - * jar file is not a multi-release jar file or {@code JarFile} is not - * configured for processing a multi-release jar file, this method returns - * the same name that {@link JarEntry#getName()} returns. + * Returns a {@code Stream} of the versioned jar file entries. * - * @param entry the JarEntry - * @return the real name of the JarEntry - * @since 9 + * <p>If this {@code JarFile} is a multi-release jar file and is configured to + * be processed as such, then an entry in the stream is the latest versioned entry + * associated with the corresponding base entry name. The maximum version of the + * latest versioned entry is the version returned by {@link #getVersion()}. + * The returned stream may include an entry that only exists as a versioned entry. + * + * If the jar file is not a multi-release jar file or the {@code JarFile} is not + * configured for processing a multi-release jar file, this method returns the + * same stream that {@link #stream()} returns. + * + * @return stream of versioned entries + * @since 10 */ + public Stream<JarEntry> versionedStream() { + + if (isMultiRelease()) { + return JUZFA.entryNameStream(this).map(this::getBasename) + .filter(Objects::nonNull) + .distinct() + .map(this::getJarEntry); + } + return stream(); + } + + /* + * Invokes {@ZipFile}'s getEntry to Return a {@code JarFileEntry} for the + * given entry name or {@code null} if not found. + */ + private JarFileEntry getEntry0(String name) { + return (JarFileEntry)JUZFA.getEntry(this, name, JarFileEntry::new); + } + + private String getBasename(String name) { + if (name.startsWith(META_INF_VERSIONS)) { + int off = META_INF_VERSIONS.length(); + int index = name.indexOf('/', off); + try { + // filter out dir META-INF/versions/ and META-INF/versions/*/ + // and any entry with version > 'version' + if (index == -1 || index == (name.length() - 1) || + Integer.parseInt(name, off, index, 10) > versionMajor) { + return null; + } + } catch (NumberFormatException x) { + return null; // remove malformed entries silently + } + // map to its base name + return name.substring(index + 1); + } + return name; + } + + private JarEntry getVersionedEntry(String name, JarEntry je) { + if (BASE_VERSION_MAJOR < versionMajor) { + if (!name.startsWith(META_INF)) { + // search for versioned entry + int v = versionMajor; + while (v > BASE_VERSION_MAJOR) { + JarFileEntry vje = getEntry0(META_INF_VERSIONS + v + "/" + name); + if (vje != null) { + return vje.withBasename(name); + } + v--; + } + } + } + return je; + } + + // placeholder for now String getRealName(JarEntry entry) { - if (entry instanceof JarFileEntry) { - return ((JarFileEntry)entry).realName(); - } - return entry.getName(); + return entry.getRealName(); } private class JarFileEntry extends JarEntry { - final private String name; + private String basename; - JarFileEntry(ZipEntry ze) { - super(isMultiRelease() ? getVersionedEntry(ze) : ze); - this.name = ze.getName(); + JarFileEntry(String name) { + super(name); + this.basename = name; } + JarFileEntry(String name, ZipEntry vze) { super(vze); - this.name = name; + this.basename = name; } + + @Override public Attributes getAttributes() throws IOException { Manifest man = JarFile.this.getManifest(); if (man != null) { @@ -631,6 +633,8 @@ return null; } } + + @Override public Certificate[] getCertificates() { try { maybeInstantiateVerifier(); @@ -642,6 +646,8 @@ } return certs == null ? null : certs.clone(); } + + @Override public CodeSigner[] getCodeSigners() { try { maybeInstantiateVerifier(); @@ -653,20 +659,30 @@ } return signers == null ? null : signers.clone(); } - JarFileEntry realEntry() { - if (isMultiRelease() && versionMajor != BASE_VERSION_MAJOR) { - String entryName = super.getName(); - return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this); - } - return this; - } - String realName() { + + @Override + public String getRealName() { return super.getName(); } @Override public String getName() { - return name; + return basename; + } + + JarFileEntry realEntry() { + if (isMultiRelease() && versionMajor != BASE_VERSION_MAJOR) { + String entryName = super.getName(); + return entryName == basename || entryName.equals(basename) ? + this : new JarFileEntry(entryName, this); + } + return this; + } + + // changes the basename, returns "this" + JarFileEntry withBasename(String name) { + basename = name; + return this; } } @@ -704,7 +720,6 @@ } } - /* * Initializes the verifier object by reading all the manifest * entries and passing them to the verifier. @@ -904,7 +919,7 @@ private JarEntry getManEntry() { if (manEntry == null) { // First look up manifest entry using standard name - ZipEntry manEntry = super.getEntry(MANIFEST_NAME); + JarEntry manEntry = getEntry0(MANIFEST_NAME); if (manEntry == null) { // If not found, then iterate through all the "META-INF/" // entries to find a match. @@ -912,15 +927,13 @@ if (names != null) { for (String name : names) { if (MANIFEST_NAME.equals(name.toUpperCase(Locale.ENGLISH))) { - manEntry = super.getEntry(name); + manEntry = getEntry0(name); break; } } } } - this.manEntry = (manEntry == null) - ? null - : new JarFileEntry(manEntry.getName(), manEntry); + this.manEntry = manEntry; } return manEntry; } @@ -1032,8 +1045,32 @@ } } - JarEntry newEntry(ZipEntry ze) { - return new JarFileEntry(ze); + /* + * Returns a versioned {@code JarFileEntry} for the given entry, + * if there is one. Otherwise returns the original entry. This + * is invoked by the {@code entries2} for verifier. + */ + JarEntry newEntry(JarEntry je) { + if (isMultiRelease()) { + return getVersionedEntry(je.getName(), je); + } + return je; + } + + /* + * Returns a versioned {@code JarFileEntry} for the given entry + * name, if there is one. Otherwise returns a {@code JarFileEntry} + * with the given name. It is invoked from JarVerifier's entries2 + * for {@code singers}. + */ + JarEntry newEntry(String name) { + if (isMultiRelease()) { + JarEntry vje = getVersionedEntry(name, (JarEntry)null); + if (vje != null) { + return vje; + } + } + return new JarFileEntry(name); } Enumeration<String> entryNames(CodeSource[] cs) { @@ -1077,35 +1114,37 @@ Enumeration<JarEntry> entries2() { ensureInitialization(); if (jv != null) { - return jv.entries2(this, super.entries()); + return jv.entries2(this, JUZFA.entries(JarFile.this, + JarFileEntry::new)); } // screen out entries which are never signed - final Enumeration<? extends ZipEntry> enum_ = super.entries(); + final var unfilteredEntries = JUZFA.entries(JarFile.this, JarFileEntry::new); + return new Enumeration<>() { - ZipEntry entry; + JarEntry entry; public boolean hasMoreElements() { if (entry != null) { return true; } - while (enum_.hasMoreElements()) { - ZipEntry ze = enum_.nextElement(); - if (JarVerifier.isSigningRelated(ze.getName())) { + while (unfilteredEntries.hasMoreElements()) { + JarEntry je = unfilteredEntries.nextElement(); + if (JarVerifier.isSigningRelated(je.getName())) { continue; } - entry = ze; + entry = je; return true; } return false; } - public JarFileEntry nextElement() { + public JarEntry nextElement() { if (hasMoreElements()) { - ZipEntry ze = entry; + JarEntry je = entry; entry = null; - return new JarFileEntry(ze); + return newEntry(je); } throw new NoSuchElementException(); }
--- a/src/java.base/share/classes/java/util/jar/JarVerifier.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/jar/JarVerifier.java Sat Dec 02 06:51:10 2017 +0100 @@ -724,10 +724,10 @@ * Like entries() but screens out internal JAR mechanism entries * and includes signed entries with no ZIP data. */ - public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration<? extends ZipEntry> e) { + public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration<JarEntry> e) { final Map<String, CodeSigner[]> map = new HashMap<>(); map.putAll(signerMap()); - final Enumeration<? extends ZipEntry> enum_ = e; + final Enumeration<JarEntry> enum_ = e; return new Enumeration<>() { Enumeration<String> signers = null; @@ -738,11 +738,11 @@ return true; } while (enum_.hasMoreElements()) { - ZipEntry ze = enum_.nextElement(); - if (JarVerifier.isSigningRelated(ze.getName())) { + JarEntry je = enum_.nextElement(); + if (JarVerifier.isSigningRelated(je.getName())) { continue; } - entry = jar.newEntry(ze); + entry = jar.newEntry(je); return true; } if (signers == null) { @@ -750,7 +750,7 @@ } while (signers.hasMoreElements()) { String name = signers.nextElement(); - entry = jar.newEntry(new ZipEntry(name)); + entry = jar.newEntry(name); return true; }
--- a/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java Sat Dec 02 06:51:10 2017 +0100 @@ -60,8 +60,4 @@ public List<Object> getManifestDigests(JarFile jar) { return jar.getManifestDigests(); } - - public String getRealName(JarFile jar, JarEntry entry) { - return jar.getRealName(entry); - } }
--- a/src/java.base/share/classes/java/util/stream/DoubleStream.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/stream/DoubleStream.java Sat Dec 02 06:51:10 2017 +0100 @@ -1089,11 +1089,27 @@ * streams is parallel. When the resulting stream is closed, the close * handlers for both input streams are invoked. * + * <p>This method operates on the two input streams and binds each stream + * to its source. As a result subsequent modifications to an input stream + * source may not be reflected in the concatenated stream result. + * * @implNote * Use caution when constructing streams from repeated concatenation. * Accessing an element of a deeply concatenated stream can result in deep * call chains, or even {@code StackOverflowError}. * + * @apiNote + * To preserve optimization opportunities this method binds each stream to + * its source and accepts only two streams as parameters. For example, the + * exact size of the concatenated stream source can be computed if the exact + * size of each input stream source is known. + * To concatenate more streams without binding, or without nested calls to + * this method, try creating a stream of streams and flat-mapping with the + * identity function, for example: + * <pre>{@code + * DoubleStream concat = Stream.of(s1, s2, s3, s4).flatMapToDouble(s -> s); + * }</pre> + * * @param a the first stream * @param b the second stream * @return the concatenation of the two input streams
--- a/src/java.base/share/classes/java/util/stream/IntStream.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/stream/IntStream.java Sat Dec 02 06:51:10 2017 +0100 @@ -1081,11 +1081,27 @@ * streams is parallel. When the resulting stream is closed, the close * handlers for both input streams are invoked. * + * <p>This method operates on the two input streams and binds each stream + * to its source. As a result subsequent modifications to an input stream + * source may not be reflected in the concatenated stream result. + * * @implNote * Use caution when constructing streams from repeated concatenation. * Accessing an element of a deeply concatenated stream can result in deep * call chains, or even {@code StackOverflowError}. * + * @apiNote + * To preserve optimization opportunities this method binds each stream to + * its source and accepts only two streams as parameters. For example, the + * exact size of the concatenated stream source can be computed if the exact + * size of each input stream source is known. + * To concatenate more streams without binding, or without nested calls to + * this method, try creating a stream of streams and flat-mapping with the + * identity function, for example: + * <pre>{@code + * IntStream concat = Stream.of(s1, s2, s3, s4).flatMapToInt(s -> s); + * }</pre> + * * @param a the first stream * @param b the second stream * @return the concatenation of the two input streams
--- a/src/java.base/share/classes/java/util/stream/LongStream.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/stream/LongStream.java Sat Dec 02 06:51:10 2017 +0100 @@ -1086,11 +1086,27 @@ * streams is parallel. When the resulting stream is closed, the close * handlers for both input streams are invoked. * + * <p>This method operates on the two input streams and binds each stream + * to its source. As a result subsequent modifications to an input stream + * source may not be reflected in the concatenated stream result. + * * @implNote * Use caution when constructing streams from repeated concatenation. * Accessing an element of a deeply concatenated stream can result in deep * call chains, or even {@code StackOverflowError}. * + * @apiNote + * To preserve optimization opportunities this method binds each stream to + * its source and accepts only two streams as parameters. For example, the + * exact size of the concatenated stream source can be computed if the exact + * size of each input stream source is known. + * To concatenate more streams without binding, or without nested calls to + * this method, try creating a stream of streams and flat-mapping with the + * identity function, for example: + * <pre>{@code + * LongStream concat = Stream.of(s1, s2, s3, s4).flatMapToLong(s -> s); + * }</pre> + * * @param a the first stream * @param b the second stream * @return the concatenation of the two input streams
--- a/src/java.base/share/classes/java/util/stream/Stream.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/stream/Stream.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1341,6 +1341,10 @@ * streams is parallel. When the resulting stream is closed, the close * handlers for both input streams are invoked. * + * <p>This method operates on the two input streams and binds each stream + * to its source. As a result subsequent modifications to an input stream + * source may not be reflected in the concatenated stream result. + * * @implNote * Use caution when constructing streams from repeated concatenation. * Accessing an element of a deeply concatenated stream can result in deep @@ -1349,6 +1353,18 @@ * <p>Subsequent changes to the sequential/parallel execution mode of the * returned stream are not guaranteed to be propagated to the input streams. * + * @apiNote + * To preserve optimization opportunities this method binds each stream to + * its source and accepts only two streams as parameters. For example, the + * exact size of the concatenated stream source can be computed if the exact + * size of each input stream source is known. + * To concatenate more streams without binding, or without nested calls to + * this method, try creating a stream of streams and flat-mapping with the + * identity function, for example: + * <pre>{@code + * Stream<T> concat = Stream.of(s1, s2, s3, s4).flatMap(s -> s); + * }</pre> + * * @param <T> The type of stream elements * @param a the first stream * @param b the second stream
--- a/src/java.base/share/classes/java/util/zip/ZipCoder.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/zip/ZipCoder.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,34 @@ final class ZipCoder { + private static boolean isASCII(byte[] ba, int off, int len) { + for (int i = off; i < off + len; i++) { + if (ba[i] < 0) + return false; + } + return true; + } + + private static boolean hasReplaceChar(byte[] ba) { + for (int i = 0; i < ba.length; i++) { + if (ba[i] == (byte)'?') + return true; + } + return false; + } + String toString(byte[] ba, int off, int length) { + + // fastpath for UTF-8 cs and ascii only name, leverage the + // compact string impl to avoid the unnecessary char[] copy/ + // paste. A temporary workaround before we have better approach, + // such as a String constructor that throws exception for + // malformed and/or unmappable characters, instead of silently + // replacing with repl char + if (isUTF8 && isASCII(ba, off, length)) { + return new String(ba, off, length, cs); + } + CharsetDecoder cd = decoder().reset(); int len = (int)(length * cd.maxCharsPerByte()); char[] ca = new char[len]; @@ -78,6 +105,15 @@ } byte[] getBytes(String s) { + if (isUTF8) { + // fastpath for UTF8. should only occur when the string + // has malformed surrogates. A postscan should still be + // faster and use less memory. + byte[] ba = s.getBytes(cs); + if (!hasReplaceChar(ba)) { + return ba; + } + } CharsetEncoder ce = encoder().reset(); char[] ca = s.toCharArray(); int len = (int)(ca.length * ce.maxBytesPerChar());
--- a/src/java.base/share/classes/java/util/zip/ZipFile.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java Sat Dec 02 06:51:10 2017 +0100 @@ -50,11 +50,15 @@ import java.util.Spliterator; import java.util.Spliterators; import java.util.WeakHashMap; + +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.jar.JarEntry; import java.util.stream.Stream; import java.util.stream.StreamSupport; import jdk.internal.misc.JavaUtilZipFileAccess; import jdk.internal.misc.SharedSecrets; -import jdk.internal.misc.JavaIORandomAccessFileAccess; import jdk.internal.misc.VM; import jdk.internal.perf.PerfCounter; @@ -296,13 +300,27 @@ * @throws IllegalStateException if the zip file has been closed */ public ZipEntry getEntry(String name) { + return getEntry(name, ZipEntry::new); + } + + /* + * Returns the zip file entry for the specified name, or null + * if not found. + * + * @param name the name of the entry + * @param func the function that creates the returned entry + * + * @return the zip file entry, or null if not found + * @throws IllegalStateException if the zip file has been closed + */ + private ZipEntry getEntry(String name, Function<String, ? extends ZipEntry> func) { Objects.requireNonNull(name, "name"); synchronized (this) { ensureOpen(); byte[] bname = zc.getBytes(name); int pos = zsrc.getEntryPos(bname, true); if (pos != -1) { - return getZipEntry(name, bname, pos); + return getZipEntry(name, bname, pos, func); } } return null; @@ -374,12 +392,10 @@ private class ZipFileInflaterInputStream extends InflaterInputStream { private volatile boolean closeRequested; private boolean eof = false; - private final ZipFileInputStream zfin; ZipFileInflaterInputStream(ZipFileInputStream zfin, Inflater inf, int size) { super(zfin, inf, size); - this.zfin = zfin; } public void close() throws IOException { @@ -416,7 +432,7 @@ public int available() throws IOException { if (closeRequested) return 0; - long avail = zfin.size() - inf.getBytesWritten(); + long avail = ((ZipFileInputStream)in).size() - inf.getBytesWritten(); return (avail > (long) Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) avail); } @@ -466,41 +482,48 @@ return name; } - private class ZipEntryIterator implements Enumeration<ZipEntry>, Iterator<ZipEntry> { + private class ZipEntryIterator<T extends ZipEntry> + implements Enumeration<T>, Iterator<T> { + private int i = 0; private final int entryCount; + private final Function<String, T> gen; - public ZipEntryIterator() { - synchronized (ZipFile.this) { - ensureOpen(); - this.entryCount = zsrc.total; - } + public ZipEntryIterator(int entryCount, Function<String, T> gen) { + this.entryCount = entryCount; + this.gen = gen; } + @Override public boolean hasMoreElements() { return hasNext(); } + @Override public boolean hasNext() { return i < entryCount; } - public ZipEntry nextElement() { + @Override + public T nextElement() { return next(); } - public ZipEntry next() { + @Override + @SuppressWarnings("unchecked") + public T next() { synchronized (ZipFile.this) { ensureOpen(); if (!hasNext()) { throw new NoSuchElementException(); } // each "entry" has 3 ints in table entries - return getZipEntry(null, null, zsrc.getEntryPos(i++ * 3)); + return (T)getZipEntry(null, null, zsrc.getEntryPos(i++ * 3), gen); } } - public Iterator<ZipEntry> asIterator() { + @Override + public Iterator<T> asIterator() { return this; } } @@ -511,11 +534,51 @@ * @throws IllegalStateException if the zip file has been closed */ public Enumeration<? extends ZipEntry> entries() { - return new ZipEntryIterator(); + synchronized (this) { + ensureOpen(); + return new ZipEntryIterator<ZipEntry>(zsrc.total, ZipEntry::new); + } + } + + private Enumeration<JarEntry> entries(Function<String, JarEntry> func) { + synchronized (this) { + ensureOpen(); + return new ZipEntryIterator<JarEntry>(zsrc.total, func); + } + } + + private class EntrySpliterator<T> extends Spliterators.AbstractSpliterator<T> { + private int index; + private final int fence; + private final IntFunction<T> gen; + + EntrySpliterator(int index, int fence, IntFunction<T> gen) { + super((long)fence, + Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.IMMUTABLE | + Spliterator.NONNULL); + this.index = index; + this.fence = fence; + this.gen = gen; + } + + @Override + public boolean tryAdvance(Consumer<? super T> action) { + if (action == null) + throw new NullPointerException(); + if (index >= 0 && index < fence) { + synchronized (ZipFile.this) { + ensureOpen(); + action.accept(gen.apply(zsrc.getEntryPos(index++ * 3))); + } + return true; + } + return false; + } } /** * Returns an ordered {@code Stream} over the ZIP file entries. + * * Entries appear in the {@code Stream} in the order they appear in * the central directory of the ZIP file. * @@ -524,17 +587,68 @@ * @since 1.8 */ public Stream<? extends ZipEntry> stream() { - return StreamSupport.stream(Spliterators.spliterator( - new ZipEntryIterator(), size(), - Spliterator.ORDERED | Spliterator.DISTINCT | - Spliterator.IMMUTABLE | Spliterator.NONNULL), false); + synchronized (this) { + ensureOpen(); + return StreamSupport.stream(new EntrySpliterator<>(0, zsrc.total, + pos -> getZipEntry(null, null, pos, ZipEntry::new)), false); + } + } + + private String getEntryName(int pos) { + byte[] cen = zsrc.cen; + int nlen = CENNAM(cen, pos); + int clen = CENCOM(cen, pos); + int flag = CENFLG(cen, pos); + if (!zc.isUTF8() && (flag & EFS) != 0) { + return zc.toStringUTF8(cen, pos + CENHDR, nlen); + } else { + return zc.toString(cen, pos + CENHDR, nlen); + } + } + + /* + * Returns an ordered {@code Stream} over the zip file entry names. + * + * Entry names appear in the {@code Stream} in the order they appear in + * the central directory of the ZIP file. + * + * @return an ordered {@code Stream} of entry names in this zip file + * @throws IllegalStateException if the zip file has been closed + * @since 10 + */ + private Stream<String> entryNameStream() { + synchronized (this) { + ensureOpen(); + return StreamSupport.stream( + new EntrySpliterator<>(0, zsrc.total, this::getEntryName), false); + } + } + + /* + * Returns an ordered {@code Stream} over the zip file entries. + * + * Entries appear in the {@code Stream} in the order they appear in + * the central directory of the jar file. + * + * @param func the function that creates the returned entry + * @return an ordered {@code Stream} of entries in this zip file + * @throws IllegalStateException if the zip file has been closed + * @since 10 + */ + private Stream<JarEntry> stream(Function<String, JarEntry> func) { + synchronized (this) { + ensureOpen(); + return StreamSupport.stream(new EntrySpliterator<>(0, zsrc.total, + pos -> (JarEntry)getZipEntry(null, null, pos, func)), false); + } } private String lastEntryName; private int lastEntryPos; /* Checks ensureOpen() before invoke this method */ - private ZipEntry getZipEntry(String name, byte[] bname, int pos) { + private ZipEntry getZipEntry(String name, byte[] bname, int pos, + Function<String, ? extends ZipEntry> func) { byte[] cen = zsrc.cen; int nlen = CENNAM(cen, pos); int elen = CENEXT(cen, pos); @@ -551,7 +665,7 @@ name = zc.toString(cen, pos + CENHDR, nlen); } } - ZipEntry e = new ZipEntry(name); + ZipEntry e = func.apply(name); //ZipEntry e = new ZipEntry(name); e.flag = flag; e.xdostime = CENTIM(cen, pos); e.crc = CENCRC(cen, pos); @@ -791,7 +905,6 @@ public long skip(long n) throws IOException { synchronized (ZipFile.this) { - ensureOpenOrZipException(); initDataOffset(); if (n > rem) { n = rem; @@ -857,12 +970,33 @@ static { SharedSecrets.setJavaUtilZipFileAccess( new JavaUtilZipFileAccess() { + @Override public boolean startsWithLocHeader(ZipFile zip) { return zip.zsrc.startsWithLoc; } + @Override public String[] getMetaInfEntryNames(ZipFile zip) { return zip.getMetaInfEntryNames(); } + @Override + public JarEntry getEntry(ZipFile zip, String name, + Function<String, JarEntry> func) { + return (JarEntry)zip.getEntry(name, func); + } + @Override + public Enumeration<JarEntry> entries(ZipFile zip, + Function<String, JarEntry> func) { + return zip.entries(func); + } + @Override + public Stream<JarEntry> stream(ZipFile zip, + Function<String, JarEntry> func) { + return zip.stream(func); + } + @Override + public Stream<String> entryNameStream(ZipFile zip) { + return zip.entryNameStream(); + } } ); isWindows = VM.getSavedProperty("os.name").contains("Windows");
--- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Sat Dec 02 06:51:10 2017 +0100 @@ -274,7 +274,7 @@ if (o.path.length() == 0) { return this; } - StringBuilder sb = new StringBuilder(path.length() + o.path.length()); + StringBuilder sb = new StringBuilder(path.length() + o.path.length() + 1); sb.append(path); if (path.charAt(path.length() - 1) != '/') sb.append('/'); @@ -478,12 +478,15 @@ // Remove DotSlash(./) and resolve DotDot (..) components private String getResolved() { - if (path.length() == 0) { + int length = path.length(); + if (length == 0 || (path.indexOf("./") == -1 && path.charAt(length - 1) != '.')) { return path; + } else { + return resolvePath(); } - if (path.indexOf('.') == -1) { - return path; - } + } + + private String resolvePath() { int length = path.length(); char[] to = new char[length]; int nc = getNameCount();
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java Sat Dec 02 06:51:10 2017 +0100 @@ -834,7 +834,7 @@ try { String nm; if (jar.isMultiRelease()) { - nm = SharedSecrets.javaUtilJarAccess().getRealName(jar, entry); + nm = entry.getRealName(); } else { nm = name; }
--- a/src/java.base/share/classes/jdk/internal/misc/JavaUtilJarAccess.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/jdk/internal/misc/JavaUtilJarAccess.java Sat Dec 02 06:51:10 2017 +0100 @@ -41,5 +41,4 @@ public Enumeration<JarEntry> entries2(JarFile jar); public void setEagerValidation(JarFile jar, boolean eager); public List<Object> getManifestDigests(JarFile jar); - public String getRealName(JarFile jar, JarEntry entry); }
--- a/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java Sat Dec 02 06:51:10 2017 +0100 @@ -25,10 +25,19 @@ package jdk.internal.misc; +import java.io.IOException; +import java.util.Enumeration; +import java.util.function.Function; +import java.util.jar.JarEntry; +import java.util.stream.Stream; import java.util.zip.ZipFile; public interface JavaUtilZipFileAccess { public boolean startsWithLocHeader(ZipFile zip); public String[] getMetaInfEntryNames(ZipFile zip); + public JarEntry getEntry(ZipFile zip, String name, Function<String, JarEntry> func); + public Enumeration<JarEntry> entries(ZipFile zip, Function<String, JarEntry> func); + public Stream<JarEntry> stream(ZipFile zip, Function<String, JarEntry> func); + public Stream<String> entryNameStream(ZipFile zip); }
--- a/src/java.base/share/classes/jdk/internal/module/ModulePath.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/jdk/internal/module/ModulePath.java Sat Dec 02 06:51:10 2017 +0100 @@ -66,8 +66,6 @@ import jdk.internal.jmod.JmodFile; import jdk.internal.jmod.JmodFile.Section; import jdk.internal.perf.PerfCounter; -import jdk.internal.util.jar.VersionedStream; - /** * A {@code ModuleFinder} that locates modules on the file system by searching @@ -515,7 +513,7 @@ builder.version(vs); // scan the names of the entries in the JAR file - Map<Boolean, Set<String>> map = VersionedStream.stream(jf) + Map<Boolean, Set<String>> map = jf.versionedStream() .filter(e -> !e.isDirectory()) .map(JarEntry::getName) .filter(e -> (e.endsWith(".class") ^ e.startsWith(SERVICES_PREFIX))) @@ -615,7 +613,7 @@ } private Set<String> jarPackages(JarFile jf) { - return VersionedStream.stream(jf) + return jf.versionedStream() .filter(e -> !e.isDirectory()) .map(JarEntry::getName) .map(this::toPackageName)
--- a/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java Sat Dec 02 06:51:10 2017 +0100 @@ -50,9 +50,7 @@ import java.util.zip.ZipFile; import jdk.internal.jmod.JmodFile; -import jdk.internal.misc.SharedSecrets; import jdk.internal.module.ModuleHashes.HashSupplier; -import jdk.internal.util.jar.VersionedStream; import sun.net.www.ParseUtil; @@ -250,7 +248,7 @@ JarEntry je = getEntry(name); if (je != null) { if (jf.isMultiRelease()) - name = SharedSecrets.javaUtilJarAccess().getRealName(jf, je); + name = je.getRealName(); if (je.isDirectory() && !name.endsWith("/")) name += "/"; String encodedPath = ParseUtil.encodePath(name, false); @@ -274,7 +272,7 @@ @Override Stream<String> implList() throws IOException { // take snapshot to avoid async close - List<String> names = VersionedStream.stream(jf) + List<String> names = jf.versionedStream() .map(JarEntry::getName) .collect(Collectors.toList()); return names.stream();
--- a/src/java.base/share/classes/jdk/internal/util/jar/VersionedStream.java Sat Dec 02 11:25:35 2017 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.internal.util.jar; - -import java.util.Objects; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.stream.Stream; - -public class VersionedStream { - private static final String META_INF_VERSIONS = "META-INF/versions/"; - - /** - * Returns a stream of versioned entries, derived from the base names of - * all entries in a multi-release {@code JarFile} that are present either in - * the base directory or in any versioned directory with a version number - * less than or equal to the {@code Runtime.Version::major} that the - * {@code JarFile} was opened with. These versioned entries are aliases - * for the real entries -- i.e. the names are base names and the content - * may come from a versioned directory entry. If the {@code jarFile} is not - * a multi-release jar, a stream of all entries is returned. - * - * @param jf the input JarFile - * @return stream of entries - * @since 9 - */ - public static Stream<JarEntry> stream(JarFile jf) { - if (jf.isMultiRelease()) { - int version = jf.getVersion().major(); - return jf.stream() - .map(je -> getBaseSuffix(je, version)) - .filter(Objects::nonNull) - .distinct() - .map(jf::getJarEntry); - } - return jf.stream(); - } - - private static String getBaseSuffix(JarEntry je, int version) { - String name = je.getName(); - if (name.startsWith(META_INF_VERSIONS)) { - int len = META_INF_VERSIONS.length(); - int index = name.indexOf('/', len); - if (index == -1 || index == (name.length() - 1)) { - // filter out META-INF/versions/* and META-INF/versions/*/ - return null; - } - try { - if (Integer.parseInt(name, len, index, 10) > version) { - // not an integer - return null; - } - } catch (NumberFormatException x) { - // silently remove malformed entries - return null; - } - // We know name looks like META-INF/versions/*/* - return name.substring(index + 1); - } - return name; - } -}
--- a/src/java.base/share/classes/module-info.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/classes/module-info.java Sat Dec 02 06:51:10 2017 +0100 @@ -210,9 +210,7 @@ jdk.internal.vm.ci, jdk.incubator.httpclient; exports jdk.internal.util.jar to - jdk.jartool, - jdk.jdeps, - jdk.jlink; + jdk.jartool; exports sun.net to jdk.incubator.httpclient; exports sun.net.ext to
--- a/src/java.base/share/native/include/jvm.h Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/native/include/jvm.h Sat Dec 02 06:51:10 2017 +0100 @@ -262,21 +262,9 @@ /* * java.lang.SecurityManager */ -JNIEXPORT jclass JNICALL -JVM_CurrentLoadedClass(JNIEnv *env); - -JNIEXPORT jobject JNICALL -JVM_CurrentClassLoader(JNIEnv *env); - JNIEXPORT jobjectArray JNICALL JVM_GetClassContext(JNIEnv *env); -JNIEXPORT jint JNICALL -JVM_ClassDepth(JNIEnv *env, jstring name); - -JNIEXPORT jint JNICALL -JVM_ClassLoaderDepth(JNIEnv *env); - /* * java.lang.Package */
--- a/src/java.base/share/native/libjava/SecurityManager.c Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.base/share/native/libjava/SecurityManager.c Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,53 +76,3 @@ return JVM_GetClassContext(env); } - -JNIEXPORT jclass JNICALL -Java_java_lang_SecurityManager_currentLoadedClass0(JNIEnv *env, jobject this) -{ - /* Make sure the security manager instance is initialized */ - if (!check(env, this)) { - return NULL; /* exception */ - } - - return JVM_CurrentLoadedClass(env); -} - -JNIEXPORT jobject JNICALL -Java_java_lang_SecurityManager_currentClassLoader0(JNIEnv *env, jobject this) -{ - /* Make sure the security manager instance is initialized */ - if (!check(env, this)) { - return NULL; /* exception */ - } - - return JVM_CurrentClassLoader(env); -} - -JNIEXPORT jint JNICALL -Java_java_lang_SecurityManager_classDepth(JNIEnv *env, jobject this, - jstring name) -{ - /* Make sure the security manager instance is initialized */ - if (!check(env, this)) { - return -1; /* exception */ - } - - if (name == NULL) { - JNU_ThrowNullPointerException(env, 0); - return -1; - } - - return JVM_ClassDepth(env, name); -} - -JNIEXPORT jint JNICALL -Java_java_lang_SecurityManager_classLoaderDepth0(JNIEnv *env, jobject this) -{ - /* Make sure the security manager instance is initialized */ - if (!check(env, this)) { - return -1; /* exception */ - } - - return JVM_ClassLoaderDepth(env); -}
--- a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java Sat Dec 02 06:51:10 2017 +0100 @@ -257,7 +257,7 @@ * * @implSpec This implementation dispatches to the visit method for * the specific {@linkplain TypeKind kind} of pseudo-type: - * {@code VOID}, {@code PACKAGE}, or {@code NONE}. + * {@code VOID}, {@code PACKAGE}, {@code MODULE}, or {@code NONE}. * * @param t {@inheritDoc} * @param p {@inheritDoc} @@ -273,6 +273,9 @@ case PACKAGE: return visitNoTypeAsPackage(t, p); + case MODULE: + return visitNoTypeAsModule(t, p); + case NONE: return visitNoTypeAsNone(t, p); @@ -308,6 +311,21 @@ } /** + * Visits a {@link TypeKind#MODULE MODULE} pseudo-type. + * + * @implSpec This implementation calls {@code visitUnknown}. + * + * @param t the type to visit + * @param p a visitor-specified parameter + * @return the result of {@code visitUnknown} + * + * @since 10 + */ + public R visitNoTypeAsModule(NoType t, P p) { + return visitUnknown(t, p); + } + + /** * Visits a {@link TypeKind#NONE NONE} pseudo-type. * * @implSpec This implementation calls {@code defaultAction}.
--- a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor9.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor9.java Sat Dec 02 06:51:10 2017 +0100 @@ -93,4 +93,20 @@ protected TypeKindVisitor9(R defaultValue) { super(defaultValue); } + + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param t {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + * + * @since 10 + */ + @Override + public R visitNoTypeAsModule(NoType t, P p) { + return defaultAction(t, p); + } }
--- a/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -329,7 +329,7 @@ } } - private final void swap(final Vector<Object> a, final int i, final int j) { + private void swap(final Vector<Object> a, final int i, final int j) { final Object T = a.elementAt(i); a.setElementAt(a.elementAt(j), i); a.setElementAt(T, j);
--- a/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1448,7 +1448,7 @@ * * @return true during layout, false otherwise. */ - private final boolean isLayouting() { + private boolean isLayouting() { return isLayouting; } }
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java Sat Dec 02 06:51:10 2017 +0100 @@ -1359,14 +1359,18 @@ this.pixelStream = new DataInputStream(is); /* - * NB: the PNG spec declares that valid range for width + * PNG spec declares that valid range for width * and height is [1, 2^31-1], so here we may fail to allocate * a buffer for destination image due to memory limitation. * - * However, the recovery strategy for this case should be - * defined on the level of application, so we will not - * try to estimate the required amount of the memory and/or - * handle OOM in any way. + * If the read operation triggers OutOfMemoryError, the same + * will be wrapped in an IIOException at PNGImageReader.read + * method. + * + * The recovery strategy for this case should be defined at + * the level of application, so we will not try to estimate + * the required amount of the memory and/or handle OOM in + * any way. */ theImage = getDestination(param, getImageTypes(0), @@ -1671,7 +1675,16 @@ throw new IndexOutOfBoundsException("imageIndex != 0!"); } - readImage(param); + try { + readImage(param); + } catch (IOException | + IllegalStateException | + IllegalArgumentException e) + { + throw e; + } catch (Throwable e) { + throw new IIOException("Caught exception during read: ", e); + } return theImage; } @@ -1685,5 +1698,6 @@ gotMetadata = false; metadata = null; pixelStream = null; + imageStartPosition = -1L; } }
--- a/src/java.desktop/share/classes/com/sun/media/sound/RIFFReader.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/com/sun/media/sound/RIFFReader.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ private final String fourcc; private String riff_type = null; private final long ckSize; - private InputStream stream; + private final InputStream stream; private long avail = 0xffffffffL; // MAX_UNSIGNED_INT private RIFFReader lastiterator = null; @@ -338,8 +338,6 @@ @Override public void close() throws IOException { finish(); - if (this == root) - stream.close(); - stream = null; + stream.close(); } }
--- a/src/java.desktop/share/classes/java/awt/Component.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/java/awt/Component.java Sat Dec 02 06:51:10 2017 +0100 @@ -1135,9 +1135,18 @@ if (graphicsConfig == gc) { return false; } - + GraphicsConfiguration oldConfig = graphicsConfig; graphicsConfig = gc; + /* + * If component is moved from one screen to another sceeen + * graphicsConfiguration property is fired to enable the component + * to recalculate any rendering data, if needed + */ + if (oldConfig != null && gc != null) { + firePropertyChange("graphicsConfiguration", oldConfig, gc); + } + ComponentPeer peer = this.peer; if (peer != null) { return peer.updateGraphicsData(gc); @@ -2030,14 +2039,14 @@ * used by GlobalCursormanager to update cursor */ final Point getLocationOnScreen_NoTreeLock() { - + ComponentPeer peer = this.peer; if (peer != null && isShowing()) { if (peer instanceof LightweightPeer) { // lightweight component location needs to be translated // relative to a native component. Container host = getNativeContainer(); Point pt = host.peer.getLocationOnScreen(); - for(Component c = this; c != host; c = c.getParent()) { + for(Component c = this; c != host; c = c.getContainer()) { pt.x += c.x; pt.y += c.y; } @@ -10218,7 +10227,7 @@ applyCompoundShape(getAppliedShape().getDifference(s)); } - private final void applyCurrentShapeBelowMe() { + private void applyCurrentShapeBelowMe() { checkTreeLock(); Container parent = getContainer(); if (parent != null && parent.isShowing()) {
--- a/src/java.desktop/share/classes/java/awt/EventQueue.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/java/awt/EventQueue.java Sat Dec 02 06:51:10 2017 +0100 @@ -283,7 +283,7 @@ * @param theEvent an instance of {@code java.awt.AWTEvent}, * or a subclass of it */ - private final void postEventPrivate(AWTEvent theEvent) { + private void postEventPrivate(AWTEvent theEvent) { theEvent.isPosted = true; pushPopLock.lock(); try {
--- a/src/java.desktop/share/classes/java/awt/MenuItem.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/java/awt/MenuItem.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -410,7 +410,7 @@ * Returns true if the item and all its ancestors are * enabled, false otherwise */ - private final boolean isItemEnabled() { + private boolean isItemEnabled() { // Fix For 6185151: Menu shortcuts of all menuitems within a menu // should be disabled when the menu itself is disabled if (!isEnabled()) {
--- a/src/java.desktop/share/classes/java/awt/geom/AffineTransform.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/java/awt/geom/AffineTransform.java Sat Dec 02 06:51:10 2017 +0100 @@ -1354,7 +1354,7 @@ /* SH | SC => */ APPLY_SHEAR | APPLY_SCALE, /* SH | SC | TR => */ APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE, }; - private final void rotate90() { + private void rotate90() { double M0 = m00; m00 = m01; m01 = -M0; @@ -1370,7 +1370,7 @@ this.state = state; type = TYPE_UNKNOWN; } - private final void rotate180() { + private void rotate180() { m00 = -m00; m11 = -m11; int state = this.state; @@ -1390,7 +1390,7 @@ } type = TYPE_UNKNOWN; } - private final void rotate270() { + private void rotate270() { double M0 = m00; m00 = -m01; m01 = M0;
--- a/src/java.desktop/share/classes/java/awt/image/BufferedImageFilter.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/java/awt/image/BufferedImageFilter.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -397,7 +397,7 @@ consumer.imageComplete(status); } - private final WritableRaster createDCMraster() { + private WritableRaster createDCMraster() { WritableRaster wr; DirectColorModel dcm = (DirectColorModel) model; boolean hasAlpha = model.hasAlpha();
--- a/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -295,7 +295,7 @@ } } - private final BufferedImage ICCBIFilter(BufferedImage src, + private BufferedImage ICCBIFilter(BufferedImage src, ColorSpace srcColorSpace, BufferedImage dest, ColorSpace destColorSpace) { @@ -753,7 +753,7 @@ return hints; } - private final BufferedImage nonICCBIFilter(BufferedImage src, + private BufferedImage nonICCBIFilter(BufferedImage src, ColorSpace srcColorSpace, BufferedImage dst, ColorSpace dstColorSpace) { @@ -947,7 +947,7 @@ /* color convert a Raster - handles byte, ushort, int, short, float, or double transferTypes */ - private final WritableRaster nonICCRasterFilter(Raster src, + private WritableRaster nonICCRasterFilter(Raster src, WritableRaster dst) { if (CSList.length != 2) {
--- a/src/java.desktop/share/classes/java/awt/image/IndexColorModel.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/java/awt/image/IndexColorModel.java Sat Dec 02 06:51:10 2017 +0100 @@ -755,7 +755,7 @@ * value is used to mask off the pixel parameters for methods such * as getRed(), getGreen(), getBlue(), getAlpha(), and getRGB(). */ - private final void calculatePixelMask() { + private void calculatePixelMask() { // Note that we adjust the mask so that our masking behavior here // is consistent with that of our native rendering loops. int maskbits = pixel_bits;
--- a/src/java.desktop/share/classes/java/awt/image/LookupOp.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/java/awt/image/LookupOp.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -472,7 +472,7 @@ return hints; } - private final void byteFilter(ByteLookupTable lookup, Raster src, + private void byteFilter(ByteLookupTable lookup, Raster src, WritableRaster dst, int width, int height, int numBands) { int[] srcPix = null; @@ -519,7 +519,7 @@ } } - private final void shortFilter(ShortLookupTable lookup, Raster src, + private void shortFilter(ShortLookupTable lookup, Raster src, WritableRaster dst, int width, int height, int numBands) { int band;
--- a/src/java.desktop/share/classes/java/awt/image/LookupTable.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/java/awt/image/LookupTable.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ * @see ShortLookupTable * @see LookupOp */ -public abstract class LookupTable extends Object{ +public abstract class LookupTable { /** * Constants
--- a/src/java.desktop/share/classes/javax/swing/JComponent.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/JComponent.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -775,8 +775,7 @@ * transform. If you need to do these operations you may find it * easier to create a new <code>Graphics</code> from the passed in * <code>Graphics</code> and manipulate it. Further, if you do not - * invoker super's implementation you must honor the opaque property, - * that is + * invoke super's implementation you must honor the opaque property, that is * if this component is opaque, you must completely fill in the background * in an opaque color. If you do not honor the opaque property you * will likely see visual artifacts.
--- a/src/java.desktop/share/classes/javax/swing/event/EventListenerList.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/event/EventListenerList.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,7 +102,7 @@ /* A null array to be shared by all empty listener lists*/ private static final Object[] NULL_ARRAY = new Object[0]; /** The list of ListenerType - Listener pairs */ - protected transient Object[] listenerList = NULL_ARRAY; + protected transient volatile Object[] listenerList = NULL_ARRAY; /** * Passes back the event listener list as an array
--- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonListener.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonListener.java Sat Dec 02 06:51:10 2017 +0100 @@ -75,7 +75,8 @@ checkOpacity((AbstractButton) e.getSource() ); } else if(prop == AbstractButton.TEXT_CHANGED_PROPERTY || - "font" == prop || "foreground" == prop) { + "font" == prop || "foreground" == prop || + "ancestor" == prop || "graphicsConfiguration" == prop) { AbstractButton b = (AbstractButton) e.getSource(); BasicHTML.updateRenderer(b, b.getText()); }
--- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLabelUI.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLabelUI.java Sat Dec 02 06:51:10 2017 +0100 @@ -472,7 +472,8 @@ public void propertyChange(PropertyChangeEvent e) { String name = e.getPropertyName(); - if (name == "text" || "font" == name || "foreground" == name) { + if (name == "text" || "font" == name || "foreground" == name || + "ancestor" == name || "graphicsConfiguration" == name) { // remove the old html view client property if one // existed, and install a new one if the text installed // into the JLabel is html source.
--- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java Sat Dec 02 06:51:10 2017 +0100 @@ -1106,7 +1106,8 @@ name == "accelerator") { updateAcceleratorBinding(); } else if (name == "text" || "font" == name || - "foreground" == name) { + "foreground" == name || + "ancestor" == name || "graphicsConfiguration" == name) { // remove the old html view client property if one // existed, and install a new one if the text installed // into the JLabel is html source.
--- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java Sat Dec 02 06:51:10 2017 +0100 @@ -226,8 +226,13 @@ return (MenuKeyListener)getHandler(); } + public Dimension getMinimumSize(JComponent c) { + return (((JMenu)menuItem).isTopLevelMenu()) ? + c.getPreferredSize() : null; + } + public Dimension getMaximumSize(JComponent c) { - if (((JMenu)menuItem).isTopLevelMenu() == true) { + if (((JMenu)menuItem).isTopLevelMenu()) { Dimension d = c.getPreferredSize(); return new Dimension(d.width, Short.MAX_VALUE); }
--- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToolTipUI.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToolTipUI.java Sat Dec 02 06:51:10 2017 +0100 @@ -261,7 +261,8 @@ public void propertyChange(PropertyChangeEvent e) { String name = e.getPropertyName(); if (name.equals("tiptext") || "font".equals(name) || - "foreground".equals(name)) { + "foreground".equals(name) || + "ancestor" == name || "graphicsConfiguration" == name) { // remove the old html view client property if one // existed, and install a new one if the text installed // into the JLabel is html source.
--- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTreeUI.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTreeUI.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3490,7 +3490,7 @@ * the destination it is constructed with. It is assumed all the * events are currently target at source. */ - public class MouseInputHandler extends Object implements + public class MouseInputHandler implements MouseInputListener { /** Source that events are coming from. */
--- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthToolTipUI.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthToolTipUI.java Sat Dec 02 06:51:10 2017 +0100 @@ -227,7 +227,8 @@ } String name = e.getPropertyName(); if (name.equals("tiptext") || "font".equals(name) || - "foreground".equals(name)) { + "foreground".equals(name) || + "ancestor" == name || "graphicsConfiguration" == name) { // remove the old html view client property if one // existed, and install a new one if the text installed // into the JLabel is html source.
--- a/src/java.desktop/share/classes/javax/swing/table/TableColumn.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/table/TableColumn.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,7 +83,7 @@ * @see JTable#getCellEditor(int, int) */ @SuppressWarnings("serial") // Same-version serialization only -public class TableColumn extends Object implements Serializable { +public class TableColumn implements Serializable { /** * Obsolete as of Java 2 platform v1.3. Please use string literals to identify
--- a/src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1797,7 +1797,7 @@ } } - private final void indent(PrintWriter out, int n) { + private void indent(PrintWriter out, int n) { for (int i = 0; i < n; i++) { out.print(" "); } @@ -2063,7 +2063,7 @@ } } - private final void checkForIllegalCast() { + private void checkForIllegalCast() { Thread t = getCurrentWriter(); if ((t == null) || (t != Thread.currentThread())) { throw new StateInvariantError("Illegal cast to MutableAttributeSet");
--- a/src/java.desktop/share/classes/javax/swing/text/GlyphPainter1.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/text/GlyphPainter1.java Sat Dec 02 06:51:10 2017 +0100 @@ -59,7 +59,8 @@ sync(v); Segment text = v.getText(p0, p1); int[] justificationData = getJustificationData(v); - int width = Utilities.getTabbedTextWidth(v, text, metrics, (int) x, e, p0, + + int width = Utilities.getTabbedTextWidth(v, text, metrics, (int)x, e, p0, justificationData); SegmentCache.releaseSharedSegment(text); return width; @@ -222,10 +223,15 @@ @SuppressWarnings("deprecation") void sync(GlyphView v) { Font f = v.getFont(); - if ((metrics == null) || (! f.equals(metrics.getFont()))) { + FontMetrics fm = null; + Container c = v.getContainer(); + if (c != null) { + fm = c.getFontMetrics(f); + } + if ((metrics == null) || (! f.equals(metrics.getFont())) + || (! metrics.equals(fm))) { // fetch a new FontMetrics - Container c = v.getContainer(); - metrics = (c != null) ? c.getFontMetrics(f) : + metrics = (c != null) ? fm : Toolkit.getDefaultToolkit().getFontMetrics(f); } }
--- a/src/java.desktop/share/classes/javax/swing/text/html/parser/Parser.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/Parser.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2422,7 +2422,7 @@ private int currentPosition; - private final int readCh() throws IOException { + private int readCh() throws IOException { if (pos >= len) {
--- a/src/java.desktop/share/classes/javax/swing/tree/TreePath.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/javax/swing/tree/TreePath.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ * @author Philip Milne */ @SuppressWarnings("serial") // Same-version serialization only -public class TreePath extends Object implements Serializable { +public class TreePath implements Serializable { /** Path representing the parent, null if lastPathComponent represents * the root. */ private TreePath parentPath;
--- a/src/java.desktop/share/classes/sun/applet/AppletSecurity.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/applet/AppletSecurity.java Sat Dec 02 06:51:10 2017 +0100 @@ -48,6 +48,8 @@ import sun.awt.AWTPermissions; import sun.security.util.SecurityConstants; +import static java.lang.StackWalker.*; +import static java.lang.StackWalker.Option.*; /** @@ -106,11 +108,90 @@ }); } + private static final StackWalker walker = + AccessController.doPrivileged( + (PrivilegedAction<StackWalker>) () -> + StackWalker.getInstance(RETAIN_CLASS_REFERENCE)); + /** + * Returns the class loader of the most recently executing method from + * a class defined using a non-system class loader. A non-system + * class loader is defined as being a class loader that is not equal to + * the system class loader (as returned + * by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors. + * <p> + * This method will return + * <code>null</code> in the following three cases: + * <ol> + * <li>All methods on the execution stack are from classes + * defined using the system class loader or one of its ancestors. + * + * <li>All methods on the execution stack up to the first + * "privileged" caller + * (see {@link java.security.AccessController#doPrivileged}) + * are from classes + * defined using the system class loader or one of its ancestors. + * + * <li> A call to <code>checkPermission</code> with + * <code>java.security.AllPermission</code> does not + * result in a SecurityException. + * </ol> + * + * NOTE: This is an implementation of the SecurityManager.currentClassLoader + * method that uses StackWalker. SecurityManager.currentClassLoader + * has been removed from SE. This is a temporary workaround which is + * only needed while applets are still supported. + * + * @return the class loader of the most recent occurrence on the stack + * of a method from a class defined using a non-system class + * loader. + */ + private static ClassLoader currentClassLoader() { + StackFrame f = + walker.walk(s -> s.takeWhile(AppletSecurity::isNonPrivileged) + .filter(AppletSecurity::isNonSystemFrame) + .findFirst()) + .orElse(null); + + SecurityManager sm = System.getSecurityManager(); + if (f != null && sm != null) { + try { + sm.checkPermission(new AllPermission()); + } catch (SecurityException se) { + return f.getDeclaringClass().getClassLoader(); + } + } + return null; + } + + /** + * Returns true if the StackFrame is not AccessController.doPrivileged. + */ + private static boolean isNonPrivileged(StackFrame f) { + // possibly other doPrivileged variants + Class<?> c = f.getDeclaringClass(); + return c == AccessController.class && + f.getMethodName().equals("doPrivileged"); + } + + /** + * Returns true if the StackFrame is not from a class defined by the + * system class loader or one of its ancestors. + */ + private static boolean isNonSystemFrame(StackFrame f) { + ClassLoader loader = ClassLoader.getSystemClassLoader(); + ClassLoader ld = f.getDeclaringClass().getClassLoader(); + if (ld == null || ld == loader) return false; + + while ((loader = loader.getParent()) != null) { + if (ld == loader) + return false; + } + return true; + } + /** * get the current (first) instance of an AppletClassLoader on the stack. */ - @SuppressWarnings({"deprecation", - "removal"}) // SecurityManager.currentClassLoader() private AppletClassLoader currentAppletClassLoader() { // try currentClassLoader first
--- a/src/java.desktop/share/classes/sun/awt/image/PNGImageDecoder.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/awt/image/PNGImageDecoder.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,7 +89,7 @@ private void property(String key,float value) { property(key, Float.valueOf(value)); } - private final void pngassert(boolean b) throws IOException { + private void pngassert(boolean b) throws IOException { if(!b) { PNGException e = new PNGException("Broken file"); e.printStackTrace(); @@ -692,20 +692,20 @@ fill(); return limit-pos>=n; } - private final int getInt(int pos) { + private int getInt(int pos) { return ((inbuf[pos ]&0xFF)<<24) | ((inbuf[pos+1]&0xFF)<<16) | ((inbuf[pos+2]&0xFF)<< 8) | ((inbuf[pos+3]&0xFF) ); } - private final int getShort(int pos) { + private int getShort(int pos) { return (short)(((inbuf[pos ]&0xFF)<<8) | ((inbuf[pos+1]&0xFF) )); } - private final int getByte(int pos) { + private int getByte(int pos) { return inbuf[pos]&0xFF; } - private final boolean getChunk() throws IOException { + private boolean getChunk() throws IOException { chunkLength = 0; if (!need(8)) return false; chunkLength = getInt(pos);
--- a/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java Sat Dec 02 06:51:10 2017 +0100 @@ -40,6 +40,7 @@ import sun.java2d.SurfaceManagerFactory; import sun.java2d.DestSurfaceProvider; import sun.java2d.Surface; +import sun.java2d.pipe.Region; import static sun.java2d.pipe.hw.AccelSurface.*; /** @@ -245,8 +246,8 @@ * or a backup surface with the given horizontal and vertical scale factors. */ public BufferedImage getBackupImage(double scaleX, double scaleY) { - int w = (int) Math.ceil(getWidth() * scaleX); - int h = (int) Math.ceil(getHeight() * scaleY); + int w = Region.clipRound(getWidth() * scaleX); + int h = Region.clipRound(getHeight() * scaleY); return graphicsConfig.createCompatibleImage(w, h, getTransparency()); }
--- a/src/java.desktop/share/classes/sun/font/ExtendedTextSourceLabel.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/font/ExtendedTextSourceLabel.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -310,7 +310,7 @@ return new Rectangle2D.Float(l, t, r - l, b - t); } - private final StandardGlyphVector getGV() { + private StandardGlyphVector getGV() { if (gv == null) { gv = createGV(); } @@ -543,7 +543,7 @@ } } - private final float[] getCharinfo() { + private float[] getCharinfo() { if (charinfo == null) { charinfo = createCharinfo(); }
--- a/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -998,14 +998,14 @@ } // called by getGlyphsPixelBounds - private final void setDTX(AffineTransform tx) { + private void setDTX(AffineTransform tx) { if (!equalNonTranslateTX(dtx, tx)) { resetDTX(getNonTranslateTX(tx)); } } // called by most functions - private final void setFRCTX() { + private void setFRCTX() { if (!equalNonTranslateTX(frctx, dtx)) { resetDTX(getNonTranslateTX(frctx)); } @@ -1016,7 +1016,7 @@ * must not contain translation. * Called by setRenderTransform, setDTX, initFontData. */ - private final void resetDTX(AffineTransform at) { + private void resetDTX(AffineTransform at) { fsref = null; dtx = at; invdtx = null;
--- a/src/java.desktop/share/classes/sun/font/TextSourceLabel.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/font/TextSourceLabel.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -147,7 +147,7 @@ return createLogicalBounds(); } - private final GlyphVector getGV() { + private GlyphVector getGV() { if (gv == null) { gv = createGV(); }
--- a/src/java.desktop/share/classes/sun/font/TrueTypeGlyphMapper.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/font/TrueTypeGlyphMapper.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -106,11 +106,11 @@ cmap = CMap.theNullCmap; } - private final char remapJAChar(char unicode) { + private char remapJAChar(char unicode) { return (unicode == REVERSE_SOLIDUS) ? JA_YEN : unicode; } - private final int remapJAIntChar(int unicode) { + private int remapJAIntChar(int unicode) { return (unicode == REVERSE_SOLIDUS) ? JA_YEN : unicode; }
--- a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Sat Dec 02 06:51:10 2017 +0100 @@ -3146,6 +3146,14 @@ double widthScale = ((double) rvWidth) / width; double heightScale = ((double) rvHeight) / height; + if (resolutionVariant instanceof VolatileImage) { + SurfaceData sd = SurfaceManager + .getManager(resolutionVariant) + .getPrimarySurfaceData(); + widthScale *= sd.getDefaultScaleX(); + heightScale *= sd.getDefaultScaleY(); + } + sx1 = Region.clipScale(sx1, widthScale); sy1 = Region.clipScale(sy1, heightScale); sx2 = Region.clipScale(sx2, widthScale);
--- a/src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java Sat Dec 02 06:51:10 2017 +0100 @@ -227,7 +227,7 @@ pc2d); } - private final double userSpaceLineWidth(AffineTransform at, double lw) { + private double userSpaceLineWidth(AffineTransform at, double lw) { double widthScale;
--- a/src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java Sat Dec 02 06:51:10 2017 +0100 @@ -227,7 +227,7 @@ pc2d); } - private final float userSpaceLineWidth(AffineTransform at, float lw) { + private float userSpaceLineWidth(AffineTransform at, float lw) { float widthScale;
--- a/src/java.desktop/share/classes/sun/swing/AccumulativeRunnable.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/swing/AccumulativeRunnable.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -152,7 +152,7 @@ * * @return accumulated arguments */ - private final synchronized List<T> flush() { + private synchronized List<T> flush() { List<T> list = arguments; arguments = null; return list;
--- a/src/java.desktop/share/classes/sun/swing/CachedPainter.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/share/classes/sun/swing/CachedPainter.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,9 +24,21 @@ */ package sun.swing; -import java.awt.*; -import java.awt.image.*; -import java.util.*; +import sun.awt.image.SurfaceManager; +import sun.java2d.SurfaceData; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.geom.AffineTransform; +import java.awt.image.AbstractMultiResolutionImage; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.awt.image.VolatileImage; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; /** * A base class used for icons or images that are expensive to paint. @@ -129,6 +141,22 @@ } if (image == null) { // Recreate the image + if( config != null && (w != baseHeight || h != baseWidth)) { + AffineTransform tx = config.getDefaultTransform(); + double sx = tx.getScaleX(); + double sy = tx.getScaleY(); + if ( Double.compare(sx, 1) != 0 || + Double.compare(sy, 1) != 0) { + if (Math.abs(sx * baseWidth - w) < 1 && + Math.abs(sy * baseHeight - h) < 1) { + w = baseWidth; + h = baseHeight; + } else { + w = (int)Math.ceil(w / sx); + h = (int)Math.ceil(w / sy); + } + } + } image = createImage(c, w, h, config, args); cache.setImage(key, config, w, h, args, image); draw = true; @@ -139,10 +167,24 @@ if (draw) { // Render to the Image Graphics2D g2 = (Graphics2D) image.getGraphics(); - if (volatileImage == null && (w != baseWidth || h != baseHeight)) { - g2.scale((double) w / baseWidth, (double) h / baseHeight); + if (volatileImage == null) { + if ((w != baseWidth || h != baseHeight)) { + g2.scale((double) w / baseWidth, + (double) h / baseHeight); + } + paintToImage(c, image, g2, baseWidth, baseHeight, args); + } else { + SurfaceData sd = SurfaceManager.getManager(volatileImage) + .getPrimarySurfaceData(); + double sx = sd.getDefaultScaleX(); + double sy = sd.getDefaultScaleY(); + if ( Double.compare(sx, 1) != 0 || + Double.compare(sy, 1) != 0) { + g2.scale(1 / sx, 1 / sy); + } + paintToImage(c, image, g2, (int)Math.ceil(w * sx), + (int)Math.ceil(h * sy), args); } - paintToImage(c, image, g2, baseWidth, baseHeight, args); g2.dispose(); } @@ -288,4 +330,4 @@ return Arrays.asList(getResolutionVariant(baseWidth, baseHeight)); } } -} \ No newline at end of file +}
--- a/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,7 +113,7 @@ // internal lock for synchronizing state changes and paint calls, initialized in preInit. // the order with other locks: AWTLock -> stateLock - static class StateLock extends Object { } + static class StateLock { } protected StateLock state_lock; /** @@ -315,7 +315,7 @@ * Creates window with parameters specified by {@code params} * @see #init */ - private final void create(XCreateWindowParams params) { + private void create(XCreateWindowParams params) { XToolkit.awtLock(); try { XSetWindowAttributes xattr = new XSetWindowAttributes();
--- a/src/java.desktop/unix/classes/sun/java2d/x11/X11Renderer.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11Renderer.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ : new X11Renderer()); } - private final long validate(SunGraphics2D sg2d) { + private long validate(SunGraphics2D sg2d) { // NOTE: getCompClip() will revalidateAll() if the // surfaceData is invalid. This should ensure that // the clip and pixel that we are validating against
--- a/src/java.desktop/unix/classes/sun/java2d/xr/XRRenderer.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRRenderer.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,7 @@ * Common validate method, used by all XRRender functions to validate the * destination context. */ - private final void validateSurface(SunGraphics2D sg2d) { + private void validateSurface(SunGraphics2D sg2d) { XRSurfaceData xrsd; try { xrsd = (XRSurfaceData) sg2d.surfaceData;
--- a/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java Sat Dec 02 06:51:10 2017 +0100 @@ -498,7 +498,7 @@ // set Clause and Reading Information if (clauseBoundary!=null && clauseReading!=null && clauseReading.length!=0 && clauseBoundary.length==clauseReading.length+1 && - clauseBoundary[0]==0 && clauseBoundary[clauseReading.length]==text.length() ) + clauseBoundary[0]==0 && clauseBoundary[clauseReading.length]<=text.length() ) { for (int i=0; i<clauseBoundary.length-1; i++) { attrStr.addAttribute(Attribute.INPUT_METHOD_SEGMENT,
--- a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java Sat Dec 02 06:51:10 2017 +0100 @@ -630,7 +630,7 @@ private native void nativeGrab(); private native void nativeUngrab(); - private final boolean hasWarningWindow() { + private boolean hasWarningWindow() { return ((Window)target).getWarningString() != null; } @@ -674,7 +674,7 @@ super.setBounds(x, y, width, height, op); } - private final void initScales() { + private void initScales() { if (scaleX >= 1 && scaleY >= 1) { return;
--- a/src/java.desktop/windows/classes/sun/java2d/d3d/D3DSurfaceData.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/windows/classes/sun/java2d/d3d/D3DSurfaceData.java Sat Dec 02 06:51:10 2017 +0100 @@ -58,6 +58,7 @@ import sun.java2d.pipe.PixelToParallelogramConverter; import sun.java2d.pipe.RenderBuffer; import sun.java2d.pipe.TextPipe; +import sun.java2d.pipe.Region; import static sun.java2d.pipe.BufferedOpCodes.*; import static sun.java2d.d3d.D3DContext.D3DContextCaps.*; import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*; @@ -236,8 +237,8 @@ this.width = scaledSize.width; this.height = scaledSize.height; } else { - this.width = (int) Math.ceil(width * scaleX); - this.height = (int) Math.ceil(height * scaleY); + this.width = Region.clipRound(width * scaleX); + this.height = Region.clipRound(height * scaleY); } this.offscreenImage = image; @@ -812,8 +813,8 @@ double scaleY = getDefaultScaleY(); Rectangle r = peer.getBounds(); r.x = r.y = 0; - r.width = (int) Math.ceil(r.width * scaleX); - r.height = (int) Math.ceil(r.height * scaleY); + r.width = Region.clipRound(r.width * scaleX); + r.height = Region.clipRound(r.height * scaleY); return r; } else { return new Rectangle(width, height);
--- a/src/java.desktop/windows/classes/sun/java2d/opengl/WGLSurfaceData.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/windows/classes/sun/java2d/opengl/WGLSurfaceData.java Sat Dec 02 06:51:10 2017 +0100 @@ -37,6 +37,7 @@ import sun.awt.Win32GraphicsDevice; import sun.awt.windows.WComponentPeer; import sun.java2d.SurfaceData; +import sun.java2d.pipe.Region; public abstract class WGLSurfaceData extends OGLSurfaceData { @@ -165,8 +166,8 @@ public Rectangle getBounds() { Rectangle r = peer.getBounds(); r.x = r.y = 0; - r.width = (int) Math.ceil(r.width * scaleX); - r.height = (int) Math.ceil(r.height * scaleY); + r.width = Region.clipRound(r.width * scaleX); + r.height = Region.clipRound(r.height * scaleY); return r; } @@ -227,8 +228,8 @@ { super(peer, gc, cm, type); - this.width = (int) Math.ceil(width * scaleX); - this.height = (int) Math.ceil(height * scaleY); + this.width = Region.clipRound(width * scaleX); + this.height = Region.clipRound(height * scaleY); offscreenImage = image; initSurface(this.width, this.height); @@ -241,8 +242,8 @@ public Rectangle getBounds() { if (type == FLIP_BACKBUFFER) { Rectangle r = peer.getBounds(); - r.width = (int) Math.ceil(r.width * scaleX); - r.height = (int) Math.ceil(r.height * scaleY); + r.width = Region.clipRound(r.width * scaleX); + r.height = Region.clipRound(r.height * scaleY); r.x = r.y = 0; return r; } else {
--- a/src/java.desktop/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java Sat Dec 02 06:51:10 2017 +0100 @@ -302,8 +302,8 @@ public Rectangle getBounds() { Rectangle r = peer.getBounds(); r.x = r.y = 0; - r.width = (int) Math.ceil(r.width * scaleX); - r.height = (int) Math.ceil(r.height * scaleY); + r.width = Region.clipRound(r.width * scaleX); + r.height = Region.clipRound(r.height * scaleY); return r; }
--- a/src/java.desktop/windows/native/libawt/windows/awt_InputTextInfor.cpp Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.desktop/windows/native/libawt/windows/awt_InputTextInfor.cpp Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -202,9 +202,15 @@ m_lpClauseW == NULL || m_lpReadClauseW == NULL || m_lpClauseW[0] != 0 || m_lpClauseW[m_cClauseW] != (DWORD)m_cStrW || m_lpReadClauseW[0] != 0 || m_lpReadClauseW[m_cReadClauseW] != (DWORD)m_cReadStrW) { - lpBndClauseW = NULL; - lpReadingClauseW = NULL; - return 0; + // For cases where IMM sends WM_IME_COMPOSITION with both GCS_COMPSTR and GCS_RESULTSTR + // The GCS_RESULTSTR part may have Caluse and Reading information which should not be ignored + if (NULL == m_pResultTextInfor) { + lpBndClauseW = NULL; + lpReadingClauseW = NULL; + return 0; + } else { + return m_pResultTextInfor->GetClauseInfor(lpBndClauseW, lpReadingClauseW); + } } int* bndClauseW = NULL; @@ -346,10 +352,14 @@ // int AwtInputTextInfor::GetAttributeInfor(int*& lpBndAttrW, BYTE*& lpValAttrW) { if (m_cStrW == 0 || m_cAttrW != m_cStrW) { - lpBndAttrW = NULL; - lpValAttrW = NULL; + if (NULL == m_pResultTextInfor) { + lpBndAttrW = NULL; + lpValAttrW = NULL; - return 0; + return 0; + } else { + return m_pResultTextInfor->GetAttributeInfor(lpBndAttrW, lpValAttrW); + } } int* bndAttrW = NULL;
--- a/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java Sat Dec 02 06:51:10 2017 +0100 @@ -505,7 +505,7 @@ } // add namespace declarations for (NamespaceDeclaration namespace : this.namespaceDeclarations) { - target.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri); + newElement.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri); } // add attribute declarations for (AttributeDeclaration attribute : this.attributeDeclarations) {
--- a/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java Sat Dec 02 06:51:10 2017 +0100 @@ -499,7 +499,7 @@ } // add namespace declarations for (NamespaceDeclaration namespace : this.namespaceDeclarations) { - target.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri); + newElement.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri); } // add attribute declarations for (AttributeDeclaration attribute : this.attributeDeclarations) {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java Sat Dec 02 06:51:10 2017 +0100 @@ -32,6 +32,7 @@ * * @version $Id: ConstantDouble.java 1747278 2016-06-07 17:28:43Z britter $ * @see Constant + * @LastModified: Nov 2017 */ public final class ConstantDouble extends Constant implements ConstantObject { @@ -121,6 +122,6 @@ */ @Override public Object getConstantValue( final ConstantPool cp ) { - return new Double(bytes); + return bytes; } }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java Sat Dec 02 06:51:10 2017 +0100 @@ -32,6 +32,7 @@ * * @version $Id: ConstantFloat.java 1747278 2016-06-07 17:28:43Z britter $ * @see Constant + * @LastModified: Nov 2017 */ public final class ConstantFloat extends Constant implements ConstantObject { @@ -122,6 +123,6 @@ */ @Override public Object getConstantValue( final ConstantPool cp ) { - return new Float(bytes); + return bytes; } }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java Sat Dec 02 06:51:10 2017 +0100 @@ -26,6 +26,7 @@ * <PRE>Stack: ... -> ..., </PRE> * * @version $Id: DCONST.java 1747278 2016-06-07 17:28:43Z britter $ + * @LastModified: Nov 2017 */ public class DCONST extends Instruction implements ConstantPushInstruction { @@ -55,7 +56,7 @@ @Override public Number getValue() { - return new Double(value); + return value; }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java Sat Dec 02 06:51:10 2017 +0100 @@ -26,6 +26,7 @@ * <PRE>Stack: ... -> ..., </PRE> * * @version $Id: FCONST.java 1747278 2016-06-07 17:28:43Z britter $ + * @LastModified: Nov 2017 */ public class FCONST extends Instruction implements ConstantPushInstruction { @@ -57,7 +58,7 @@ @Override public Number getValue() { - return new Float(value); + return value; }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -41,6 +40,7 @@ * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic"> * The invokedynamic instruction in The Java Virtual Machine Specification</a> * @since 6.0 + * @LastModified: Nov 2017 */ public class INVOKEDYNAMIC extends InvokeInstruction { @@ -124,8 +124,14 @@ /** * Override the parent method because our classname is held elsewhere. + * + * @param cpg the ConstantPool generator + * @deprecated in FieldOrMethod + * + * @return name of the referenced class/interface */ @Override + @Deprecated public String getClassName( final ConstantPoolGen cpg ) { final ConstantPool cp = cpg.getConstantPool(); final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(super.getIndex(), Const.CONSTANT_InvokeDynamic);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java Sat Dec 02 06:51:10 2017 +0100 @@ -32,6 +32,7 @@ * @version $Id: InstructionFactory.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Const * @see InstructionConst + * @LastModified: Nov 2017 */ public class InstructionFactory { @@ -573,7 +574,7 @@ + short_names[dest - Const.T_CHAR]; Instruction i = null; try { - i = (Instruction) java.lang.Class.forName(name).newInstance(); + i = (Instruction) java.lang.Class.forName(name).getDeclaredConstructor().newInstance(); } catch (final Exception e) { throw new RuntimeException("Could not find instruction: " + name, e); }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java Sat Dec 02 06:51:10 2017 +0100 @@ -32,6 +32,7 @@ * <PRE>Stack: ... -> ..., item</PRE> * * @version $Id: LDC.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @LastModified: Nov 2017 */ public class LDC extends CPInstruction implements PushInstruction, ExceptionThrower { @@ -104,9 +105,9 @@ c = cpg.getConstantPool().getConstant(i); return ((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes(); case com.sun.org.apache.bcel.internal.Const.CONSTANT_Float: - return new Float(((com.sun.org.apache.bcel.internal.classfile.ConstantFloat) c).getBytes()); + return ((com.sun.org.apache.bcel.internal.classfile.ConstantFloat) c).getBytes(); case com.sun.org.apache.bcel.internal.Const.CONSTANT_Integer: - return Integer.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantInteger) c).getBytes()); + return ((com.sun.org.apache.bcel.internal.classfile.ConstantInteger) c).getBytes(); case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class: final int nameIndex = ((com.sun.org.apache.bcel.internal.classfile.ConstantClass) c).getNameIndex(); c = cpg.getConstantPool().getConstant(nameIndex);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java Sat Dec 02 06:51:10 2017 +0100 @@ -26,6 +26,7 @@ * <PRE>Stack: ... -> ..., item.word1, item.word2</PRE> * * @version $Id: LDC2_W.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @LastModified: Nov 2017 */ public class LDC2_W extends CPInstruction implements PushInstruction { @@ -59,9 +60,9 @@ final com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(super.getIndex()); switch (c.getTag()) { case com.sun.org.apache.bcel.internal.Const.CONSTANT_Long: - return Long.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantLong) c).getBytes()); + return ((com.sun.org.apache.bcel.internal.classfile.ConstantLong) c).getBytes(); case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: - return new Double(((com.sun.org.apache.bcel.internal.classfile.ConstantDouble) c).getBytes()); + return ((com.sun.org.apache.bcel.internal.classfile.ConstantDouble) c).getBytes(); default: // Never reached throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex()); }
--- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/Big5_HKSCS.java.template Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/Big5_HKSCS.java.template Sat Dec 02 06:51:10 2017 +0100 @@ -31,6 +31,7 @@ import sun.nio.cs.DoubleByte; import sun.nio.cs.HKSCS; import sun.nio.cs.HistoricallyNamedCharset; +import sun.nio.cs.*; import static sun.nio.cs.CharsetMapping.*; public class Big5_HKSCS extends Charset implements HistoricallyNamedCharset
--- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/MS950_HKSCS.java Sat Dec 02 11:25:35 2017 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * 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 sun.nio.cs.ext; - -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import sun.nio.cs.HistoricallyNamedCharset; -import sun.nio.cs.*; -import static sun.nio.cs.CharsetMapping.*; - -public class MS950_HKSCS extends Charset implements HistoricallyNamedCharset -{ - public MS950_HKSCS() { - super("x-MS950-HKSCS", ExtendedCharsets.aliasesFor("x-MS950-HKSCS")); - } - - public String historicalName() { - return "MS950_HKSCS"; - } - - public boolean contains(Charset cs) { - return ((cs.name().equals("US-ASCII")) - || (cs instanceof MS950) - || (cs instanceof MS950_HKSCS)); - } - - public CharsetDecoder newDecoder() { - return new Decoder(this); - } - - public CharsetEncoder newEncoder() { - return new Encoder(this); - } - - static class Decoder extends HKSCS.Decoder { - private static DoubleByte.Decoder ms950 = - (DoubleByte.Decoder)new MS950().newDecoder(); - - private static char[][] b2cBmp = new char[0x100][]; - private static char[][] b2cSupp = new char[0x100][]; - static { - initb2c(b2cBmp, HKSCSMapping.b2cBmpStr); - initb2c(b2cSupp, HKSCSMapping.b2cSuppStr); - } - - private Decoder(Charset cs) { - super(cs, ms950, b2cBmp, b2cSupp); - } - } - - private static class Encoder extends HKSCS.Encoder { - private static DoubleByte.Encoder ms950 = - (DoubleByte.Encoder)new MS950().newEncoder(); - - static char[][] c2bBmp = new char[0x100][]; - static char[][] c2bSupp = new char[0x100][]; - static { - initc2b(c2bBmp, HKSCSMapping.b2cBmpStr, HKSCSMapping.pua); - initc2b(c2bSupp, HKSCSMapping.b2cSuppStr, null); - } - - private Encoder(Charset cs) { - super(cs, ms950, c2bBmp, c2bSupp); - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/MS950_HKSCS.java.template Sat Dec 02 06:51:10 2017 +0100 @@ -0,0 +1,90 @@ +/* + * 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 $PACKAGE$; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import sun.nio.cs.HistoricallyNamedCharset; +import sun.nio.cs.*; +import static sun.nio.cs.CharsetMapping.*; + +public class MS950_HKSCS extends Charset implements HistoricallyNamedCharset +{ + public MS950_HKSCS() { + super("x-MS950-HKSCS", $ALIASES$); + } + + public String historicalName() { + return "MS950_HKSCS"; + } + + public boolean contains(Charset cs) { + return ((cs.name().equals("US-ASCII")) + || (cs instanceof MS950) + || (cs instanceof MS950_HKSCS)); + } + + public CharsetDecoder newDecoder() { + return new Decoder(this); + } + + public CharsetEncoder newEncoder() { + return new Encoder(this); + } + + static class Decoder extends HKSCS.Decoder { + private static DoubleByte.Decoder ms950 = + (DoubleByte.Decoder)new MS950().newDecoder(); + + private static char[][] b2cBmp = new char[0x100][]; + private static char[][] b2cSupp = new char[0x100][]; + static { + initb2c(b2cBmp, HKSCSMapping.b2cBmpStr); + initb2c(b2cSupp, HKSCSMapping.b2cSuppStr); + } + + private Decoder(Charset cs) { + super(cs, ms950, b2cBmp, b2cSupp); + } + } + + private static class Encoder extends HKSCS.Encoder { + private static DoubleByte.Encoder ms950 = + (DoubleByte.Encoder)new MS950().newEncoder(); + + static char[][] c2bBmp = new char[0x100][]; + static char[][] c2bSupp = new char[0x100][]; + static { + initc2b(c2bBmp, HKSCSMapping.b2cBmpStr, HKSCSMapping.pua); + initc2b(c2bSupp, HKSCSMapping.b2cSuppStr, null); + } + + private Encoder(Charset cs) { + super(cs, ms950, c2bBmp, c2bSupp); + } + } +}
--- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocCommentTree.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocCommentTree.java Sat Dec 02 06:51:10 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.source.doctree; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -69,4 +70,39 @@ * @return the block tags of a documentation comment */ List<? extends DocTree> getBlockTags(); + + /** + * Returns a list of trees containing the content (if any) preceding + * the content of the documentation comment. + * When the {@code DocCommentTree} has been read from a documentation + * comment in a Java source file, the list will be empty. + * When the {@code DocCommentTree} has been read from an HTML file, this + * represents the content from the beginning of the file up to and + * including the {@code <body>} tag. + * + * @implSpec This implementation returns an empty list. + * + * @return the list of trees + * @since 10 + */ + default List<? extends DocTree> getPreamble() { + return Collections.emptyList(); + } + + /** + * Returns a list of trees containing the content (if any) following the + * content of the documentation comment. + * When the {@code DocCommentTree} has been read from a documentation + * comment in a Java source file, the list will be empty. + * When {@code DocCommentTree} has been read from an HTML file, this + * represents the content from the {@code </body>} tag to the end of file. + * + * @implSpec This implementation returns an empty list. + * + * @return the list of trees + * @since 10 + */ + default List<? extends DocTree> getPostamble() { + return Collections.emptyList(); + } }
--- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java Sat Dec 02 06:51:10 2017 +0100 @@ -78,6 +78,12 @@ DOC_ROOT("docRoot"), /** + * Used for instances of {@link DocTypeTree} + * representing an HTML DocType declaration. + */ + DOC_TYPE, + + /** * Used for instances of {@link EndElementTree} * representing the end of an HTML element. */
--- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java Sat Dec 02 06:51:10 2017 +0100 @@ -105,6 +105,21 @@ R visitDocRoot(DocRootTree node, P p); /** + * Visits a DocTypeTree node. + * + * @implSpec Visits a {@code DocTypeTree} node + * by calling {@code visitOther(node, p)}. + * + * @param node the node being visited + * @param p a parameter value + * @return a result value + * @since 10 + */ + default R visitDocType(DocTypeTree node, P p) { + return visitOther(node, p); + } + + /** * Visits an EndElementTree node. * @param node the node being visited * @param p a parameter value @@ -267,7 +282,9 @@ * @return a result value * @since 10 */ - default R visitSummary(SummaryTree node, P p) { return visitOther(node, p);} + default R visitSummary(SummaryTree node, P p) { + return visitOther(node, p); + } /** * Visits a TextTree node.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTypeTree.java Sat Dec 02 06:51:10 2017 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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 com.sun.source.doctree; + +/** + * A tree node for a {@code doctype} declaration. + * + * <p> + * <!doctype text> + * + * @since 10 + */ +public interface DocTypeTree extends DocTree { + /** + * Returns the text of the doctype declaration. + * @return text + */ + String getText(); +}
--- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java Sat Dec 02 06:51:10 2017 +0100 @@ -39,6 +39,7 @@ import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocRootTree; import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.DocTypeTree; import com.sun.source.doctree.EndElementTree; import com.sun.source.doctree.EntityTree; import com.sun.source.doctree.ErroneousTree; @@ -121,6 +122,20 @@ */ DocCommentTree newDocCommentTree(List<? extends DocTree> fullBody, List<? extends DocTree> tags); + + /** + * Create a new {@code DocCommentTree} object, to represent the enitire doc comment. + * @param fullBody the entire body of the doc comment + * @param tags the block tags in the doc comment + * @param preamble the meta content of an html file including the body tag + * @param postamble the meta content of an html including the closing body tag + * @return a {@code DocCommentTree} object + * @since 10 + */ + DocCommentTree newDocCommentTree(List<? extends DocTree> fullBody, + List<? extends DocTree> tags, + List<? extends DocTree> preamble, + List<? extends DocTree> postamble); /** * Create a new {@code DocRootTree} object, to represent an {@code {@docroot} } tag. * @return a {@code DocRootTree} object @@ -128,6 +143,14 @@ DocRootTree newDocRootTree(); /** + * Create a new {@code DocTypeTree}, to represent a {@code DOCTYPE} HTML declaration. + * @param text the content of the declaration + * @return a {@code CommentTree} object + * @since 10 + */ + DocTypeTree newDocTypeTree(String text); + + /** * Create a new {@code EndElement} object, to represent the end of an HTML element. * @param name the name of the HTML element * @return an {@code EndElementTree} object
--- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java Sat Dec 02 06:51:10 2017 +0100 @@ -206,6 +206,18 @@ * @return the result of scanning */ @Override + public R visitDocType(DocTypeTree node, P p) { + return null; + } + + /** + * {@inheritDoc} This implementation returns {@code null}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + */ + @Override public R visitEndElement(EndElementTree node, P p) { return null; }
--- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java Sat Dec 02 06:51:10 2017 +0100 @@ -98,13 +98,12 @@ /** * Returns the doc comment tree of the given file. The file must be * an HTML file, in which case the doc comment tree represents the - * contents of the <body> tag, and any enclosing tags are ignored. + * entire contents of the file. * Returns {@code null} if no doc comment was found. * Future releases may support additional file types. * * @param fileObject the content container * @return the doc comment tree - * * @since 9 */ public abstract DocCommentTree getDocCommentTree(FileObject fileObject);
--- a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java Sat Dec 02 06:51:10 2017 +0100 @@ -168,6 +168,19 @@ } /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + * @since 10 + */ + @Override + public R visitDocType(DocTypeTree node, P p) { return defaultAction(node, p); } + + /** * {@inheritDoc} This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} @@ -175,9 +188,7 @@ * @return the result of {@code defaultAction} */ @Override - public R visitEndElement(EndElementTree node, P p) { - return defaultAction(node, p); - } + public R visitEndElement(EndElementTree node, P p) { return defaultAction(node, p);} /** * {@inheritDoc} This implementation calls {@code defaultAction}.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Sat Dec 02 06:51:10 2017 +0100 @@ -28,9 +28,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.text.BreakIterator; -import java.util.HashMap; +import java.util.Collections; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -59,6 +58,8 @@ import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.EndElementTree; +import com.sun.source.doctree.StartElementTree; import com.sun.source.tree.CatchTree; import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.Scope; @@ -68,6 +69,7 @@ import com.sun.source.util.DocTreeScanner; import com.sun.source.util.DocTrees; import com.sun.source.util.JavacTask; +import com.sun.source.util.SimpleDocTreeVisitor; import com.sun.source.util.TreePath; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Scope.NamedImportScope; @@ -1006,16 +1008,7 @@ public String getText() { try { CharSequence rawDoc = fileObject.getCharContent(true); - Pattern bodyPat = - Pattern.compile("(?is).*?<body\\b[^>]*>(.*)</body\\b.*"); - Matcher m = bodyPat.matcher(rawDoc); - if (m.matches()) { - offset = m.end(1); - return m.group(1); - } else { - // Assume doclint will do the right thing. - return ""; - } + return rawDoc.toString(); } catch (IOException ignore) { // do nothing } @@ -1038,13 +1031,15 @@ } }; - return new DocCommentParser(parser, diagSource, comment).parse(); + return new DocCommentParser(parser, diagSource, comment, true).parse(); } @Override @DefinedBy(Api.COMPILER_TREE) public DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement) { JavaFileObject jfo = asJavaFileObject(fileObject); DocCommentTree docCommentTree = getDocCommentTree(jfo); + if (docCommentTree == null) + return null; TreePath treePath = makeTreePath((PackageSymbol)packageElement, jfo, docCommentTree); return new DocTreePath(treePath, docCommentTree); }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Sat Dec 02 06:51:10 2017 +0100 @@ -237,7 +237,7 @@ * {@code upwards(List<#CAP1>, [#CAP2]) = List<#CAP1> } * {@code downwards(List<#CAP1>, [#CAP1]) = not defined } */ - class TypeProjection extends StructuralTypeMapping<ProjectionKind> { + class TypeProjection extends TypeMapping<ProjectionKind> { List<Type> vars; Set<Type> seen = new HashSet<>(); @@ -257,13 +257,21 @@ Type outer = t.getEnclosingType(); Type outer1 = visit(outer, pkind); List<Type> typarams = t.getTypeArguments(); - List<Type> typarams1 = typarams.map(ta -> mapTypeArgument(ta, pkind)); - if (typarams1.stream().anyMatch(ta -> ta.hasTag(BOT))) { - //not defined - return syms.botType; + List<Type> formals = t.tsym.type.getTypeArguments(); + ListBuffer<Type> typarams1 = new ListBuffer<>(); + boolean changed = false; + for (Type actual : typarams) { + Type t2 = mapTypeArgument(t, formals.head.getUpperBound(), actual, pkind); + if (t2.hasTag(BOT)) { + //not defined + return syms.botType; + } + typarams1.add(t2); + changed |= actual != t2; + formals = formals.tail; } - if (outer1 == outer && typarams1 == typarams) return t; - else return new ClassType(outer1, typarams1, t.tsym, t.getMetadata()) { + if (outer1 == outer && !changed) return t; + else return new ClassType(outer1, typarams1.toList(), t.tsym, t.getMetadata()) { @Override protected boolean needsStripping() { return true; @@ -272,21 +280,23 @@ } } - protected Type makeWildcard(Type upper, Type lower) { - BoundKind bk; - Type bound; - if (upper.hasTag(BOT)) { - upper = syms.objectType; - } - boolean isUpperObject = isSameType(upper, syms.objectType); - if (!lower.hasTag(BOT) && isUpperObject) { - bound = lower; - bk = SUPER; + @Override + public Type visitArrayType(ArrayType t, ProjectionKind s) { + Type elemtype = t.elemtype; + Type elemtype1 = visit(elemtype, s); + if (elemtype1 == elemtype) { + return t; + } else if (elemtype1.hasTag(BOT)) { + //undefined + return syms.botType; } else { - bound = upper; - bk = isUpperObject ? UNBOUND : EXTENDS; - } - return new WildcardType(bound, bk, syms.boundClass); + return new ArrayType(elemtype1, t.tsym, t.metadata) { + @Override + protected boolean needsStripping() { + return true; + } + }; + } } @Override @@ -322,33 +332,79 @@ } } - @Override - public Type visitWildcardType(WildcardType wt, ProjectionKind pkind) { - switch (pkind) { - case UPWARDS: - return wt.isExtendsBound() ? - wt.type.map(this, pkind) : - syms.objectType; - case DOWNWARDS: - return wt.isSuperBound() ? - wt.type.map(this, pkind) : - syms.botType; - default: - Assert.error(); - return null; - } + private Type mapTypeArgument(Type site, Type declaredBound, Type t, ProjectionKind pkind) { + return t.containsAny(vars) ? + t.map(new TypeArgumentProjection(site, declaredBound), pkind) : + t; } - private Type mapTypeArgument(Type t, ProjectionKind pkind) { - if (!t.containsAny(vars)) { - return t; - } else if (!t.hasTag(WILDCARD) && pkind == ProjectionKind.DOWNWARDS) { - //not defined - return syms.botType; - } else { - Type upper = t.map(this, pkind); - Type lower = t.map(this, pkind.complement()); - return makeWildcard(upper, lower); + class TypeArgumentProjection extends TypeMapping<ProjectionKind> { + + Type site; + Type declaredBound; + + TypeArgumentProjection(Type site, Type declaredBound) { + this.site = site; + this.declaredBound = declaredBound; + } + + @Override + public Type visitType(Type t, ProjectionKind pkind) { + //type argument is some type containing restricted vars + if (pkind == ProjectionKind.DOWNWARDS) { + //not defined + return syms.botType; + } + Type upper = t.map(TypeProjection.this, ProjectionKind.UPWARDS); + Type lower = t.map(TypeProjection.this, ProjectionKind.DOWNWARDS); + List<Type> formals = site.tsym.type.getTypeArguments(); + BoundKind bk; + Type bound; + if (!isSameType(upper, syms.objectType) && + (declaredBound.containsAny(formals) || + !isSubtype(declaredBound, upper))) { + bound = upper; + bk = EXTENDS; + } else if (!lower.hasTag(BOT)) { + bound = lower; + bk = SUPER; + } else { + bound = syms.objectType; + bk = UNBOUND; + } + return makeWildcard(bound, bk); + } + + @Override + public Type visitWildcardType(WildcardType wt, ProjectionKind pkind) { + //type argument is some wildcard whose bound contains restricted vars + Type bound = syms.botType; + BoundKind bk = wt.kind; + switch (wt.kind) { + case EXTENDS: + bound = wt.type.map(TypeProjection.this, pkind); + if (bound.hasTag(BOT)) { + return syms.botType; + } + break; + case SUPER: + bound = wt.type.map(TypeProjection.this, pkind.complement()); + if (bound.hasTag(BOT)) { + bound = syms.objectType; + bk = UNBOUND; + } + break; + } + return makeWildcard(bound, bk); + } + + private Type makeWildcard(Type bound, BoundKind bk) { + return new WildcardType(bound, bk, syms.boundClass) { + @Override + protected boolean needsStripping() { + return true; + } + }; } } }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Sat Dec 02 06:51:10 2017 +0100 @@ -63,6 +63,7 @@ import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Options; +import com.sun.tools.javac.util.Position; import java.util.EnumSet; import java.util.HashMap; @@ -305,7 +306,7 @@ JCMethodDecl md = (JCMethodDecl)decls(oldTree.def).head; List<JCVariableDecl> params = md.params; JCBlock body = md.body; - JCLambda newTree = make.Lambda(params, body); + JCLambda newTree = make.at(oldTree).Lambda(params, body); return List.of(newTree); } @@ -418,7 +419,7 @@ List<JCEnhancedForLoop> rewrite(JCEnhancedForLoop oldTree) { JCEnhancedForLoop newTree = copier.copy(oldTree); newTree.var = rewriteVarType(oldTree.var); - newTree.body = make.Block(0, List.nil()); + newTree.body = make.at(oldTree.body).Block(0, List.nil()); return List.of(newTree); } @Override @@ -551,7 +552,8 @@ JCStatement treeToAnalyze = (JCStatement)rewriting.originalTree; if (rewriting.env.info.scope.owner.kind == Kind.TYP) { //add a block to hoist potential dangling variable declarations - treeToAnalyze = make.Block(Flags.SYNTHETIC, List.of((JCStatement)rewriting.originalTree)); + treeToAnalyze = make.at(Position.NOPOS) + .Block(Flags.SYNTHETIC, List.of((JCStatement)rewriting.originalTree)); } //TODO: to further refine the analysis, try all rewriting combinations
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java Sat Dec 02 06:51:10 2017 +0100 @@ -57,6 +57,7 @@ import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.DiagnosticSource; +import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; @@ -98,6 +99,7 @@ protected static final Context.Key<ArgumentAttr> methodAttrKey = new Context.Key<>(); private final DeferredAttr deferredAttr; + private final JCDiagnostic.Factory diags; private final Attr attr; private final Symtab syms; private final Log log; @@ -121,6 +123,7 @@ protected ArgumentAttr(Context context) { context.put(methodAttrKey, this); deferredAttr = DeferredAttr.instance(context); + diags = JCDiagnostic.Factory.instance(context); attr = Attr.instance(context); syms = Symtab.instance(context); log = Log.instance(context); @@ -482,18 +485,14 @@ List<JCReturn> returnExpressions() { return returnExpressions.orElseGet(() -> { final List<JCReturn> res; - if (speculativeTree.getBodyKind() == BodyKind.EXPRESSION) { - res = List.of(attr.make.Return((JCExpression)speculativeTree.body)); - } else { - ListBuffer<JCReturn> returnExpressions = new ListBuffer<>(); - new LambdaReturnScanner() { - @Override - public void visitReturn(JCReturn tree) { - returnExpressions.add(tree); - } - }.scan(speculativeTree.body); - res = returnExpressions.toList(); - } + ListBuffer<JCReturn> buf = new ListBuffer<>(); + new LambdaReturnScanner() { + @Override + public void visitReturn(JCReturn tree) { + buf.add(tree); + } + }.scan(speculativeTree.body); + res = buf.toList(); returnExpressions = Optional.of(res); return res; }); @@ -519,16 +518,38 @@ private void checkLambdaCompatible(Type descriptor, ResultInfo resultInfo) { CheckContext checkContext = resultInfo.checkContext; ResultInfo bodyResultInfo = attr.lambdaBodyResult(speculativeTree, descriptor, resultInfo); - for (JCReturn ret : returnExpressions()) { - Type t = getReturnType(ret); - if (speculativeTree.getBodyKind() == BodyKind.EXPRESSION || !t.hasTag(VOID)) { - checkSpeculative(ret.expr, t, bodyResultInfo); - } + switch (speculativeTree.getBodyKind()) { + case EXPRESSION: + checkSpeculative(speculativeTree.body, speculativeTree.body.type, bodyResultInfo); + break; + case STATEMENT: + for (JCReturn ret : returnExpressions()) { + checkReturnInStatementLambda(ret, bodyResultInfo); + } + break; } attr.checkLambdaCompatible(speculativeTree, descriptor, checkContext); } + /** + * This is an inlined version of {@link Attr#visitReturn(JCReturn)}. + */ + void checkReturnInStatementLambda(JCReturn ret, ResultInfo resultInfo) { + if (resultInfo.pt.hasTag(VOID) && ret.expr != null) { + //fail - if the function type's result is void, the lambda body must be a void-compatible block. + resultInfo.checkContext.report(speculativeTree.pos(), + diags.fragment("unexpected.ret.val")); + } else if (!resultInfo.pt.hasTag(VOID)) { + if (ret.expr == null) { + //fail - if the function type's result is non-void, the lambda body must be a value-compatible block. + resultInfo.checkContext.report(speculativeTree.pos(), + diags.fragment("missing.ret.val")); + } + checkSpeculative(ret.expr, ret.expr.type, resultInfo); + } + } + /** Get the type associated with given return expression. */ Type getReturnType(JCReturn ret) { if (ret.expr == null) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Sat Dec 02 06:51:10 2017 +0100 @@ -946,14 +946,17 @@ } Type checkLocalVarType(DiagnosticPosition pos, Type t, Name name) { - //upward project the initializer type - t = types.upward(t, types.captures(t)); //check that resulting type is not the null type if (t.hasTag(BOT)) { log.error(pos, Errors.CantInferLocalVarType(name, Fragments.LocalCantInferNull)); return types.createErrorType(t); + } else if (t.hasTag(VOID)) { + log.error(pos, Errors.CantInferLocalVarType(name, Fragments.LocalCantInferVoid)); + return types.createErrorType(t); } - return t; + + //upward project the initializer type + return types.upward(t, types.captures(t)); } Type checkMethod(final Type mtype, @@ -3554,18 +3557,19 @@ Scope staticallyImportedSoFar, Scope topLevelScope, Symbol sym, boolean staticImport) { Filter<Symbol> duplicates = candidate -> candidate != sym && !candidate.type.isErroneous(); - Symbol clashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates); - if (clashing == null && !staticImport) { - clashing = staticallyImportedSoFar.findFirst(sym.name, duplicates); + Symbol ordinaryClashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates); + Symbol staticClashing = null; + if (ordinaryClashing == null && !staticImport) { + staticClashing = staticallyImportedSoFar.findFirst(sym.name, duplicates); } - if (clashing != null) { - if (staticImport) - log.error(pos, Errors.AlreadyDefinedStaticSingleImport(clashing)); + if (ordinaryClashing != null || staticClashing != null) { + if (ordinaryClashing != null) + log.error(pos, Errors.AlreadyDefinedSingleImport(ordinaryClashing)); else - log.error(pos, Errors.AlreadyDefinedSingleImport(clashing)); + log.error(pos, Errors.AlreadyDefinedStaticSingleImport(staticClashing)); return false; } - clashing = topLevelScope.findFirst(sym.name, duplicates); + Symbol clashing = topLevelScope.findFirst(sym.name, duplicates); if (clashing != null) { log.error(pos, Errors.AlreadyDefinedThisUnit(clashing)); return false;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Sat Dec 02 06:51:10 2017 +0100 @@ -1548,7 +1548,8 @@ boolean allowBoxing, boolean useVarargs) { if (sym.kind == ERR || - !sym.isInheritedIn(site.tsym, types)) { + (site.tsym != sym.owner && !sym.isInheritedIn(site.tsym, types)) || + !notOverriddenIn(site, sym)) { return bestSoFar; } else if (useVarargs && (sym.flags() & VARARGS) == 0) { return bestSoFar.kind.isResolutionError() ?
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Sat Dec 02 06:51:10 2017 +0100 @@ -36,10 +36,12 @@ import com.sun.tools.javac.tree.DCTree; import com.sun.tools.javac.tree.DCTree.DCAttribute; import com.sun.tools.javac.tree.DCTree.DCDocComment; +import com.sun.tools.javac.tree.DCTree.DCEndElement; import com.sun.tools.javac.tree.DCTree.DCEndPosTree; import com.sun.tools.javac.tree.DCTree.DCErroneous; import com.sun.tools.javac.tree.DCTree.DCIdentifier; import com.sun.tools.javac.tree.DCTree.DCReference; +import com.sun.tools.javac.tree.DCTree.DCStartElement; import com.sun.tools.javac.tree.DCTree.DCText; import com.sun.tools.javac.tree.DocTreeMaker; import com.sun.tools.javac.tree.JCTree; @@ -50,6 +52,7 @@ import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Position; +import com.sun.tools.javac.util.StringUtils; import static com.sun.tools.javac.util.LayoutCharacters.*; @@ -68,11 +71,14 @@ } } + private enum Phase {PREAMBLE, BODY, POSTAMBLE}; + final ParserFactory fac; final DiagnosticSource diagSource; final Comment comment; final DocTreeMaker m; final Names names; + final boolean isFileContent; BreakIterator sentenceBreaker; @@ -93,17 +99,23 @@ Map<Name, TagParser> tagParsers; - public DocCommentParser(ParserFactory fac, DiagnosticSource diagSource, Comment comment) { + public DocCommentParser(ParserFactory fac, DiagnosticSource diagSource, + Comment comment, boolean isFileContent) { this.fac = fac; this.diagSource = diagSource; this.comment = comment; names = fac.names; + this.isFileContent = isFileContent; m = fac.docTreeMaker; initTagParsers(); } + public DocCommentParser(ParserFactory fac, DiagnosticSource diagSource, Comment comment) { + this(fac, diagSource, comment, false); + } + public DocCommentParser(ParserFactory fac) { - this(fac, null, null); + this(fac, null, null, false); } public DCDocComment parse() { @@ -115,13 +127,22 @@ bp = -1; nextChar(); - List<DCTree> body = blockContent(); + List<DCTree> preamble = isFileContent ? blockContent(Phase.PREAMBLE) : List.nil(); + List<DCTree> body = blockContent(Phase.BODY); List<DCTree> tags = blockTags(); - int pos = !body.isEmpty() - ? body.head.pos - : !tags.isEmpty() ? tags.head.pos : Position.NOPOS; + List<DCTree> postamble = isFileContent ? blockContent(Phase.POSTAMBLE) : List.nil(); - DCDocComment dc = m.at(pos).newDocCommentTree(comment, body, tags); + int pos = Position.NOPOS; + if (!preamble.isEmpty()) + pos = preamble.head.pos; + else if (!body.isEmpty()) + pos = body.head.pos; + else if (!tags.isEmpty()) + pos = tags.head.pos; + else if (!postamble.isEmpty()) + pos = postamble.head.pos; + + DCDocComment dc = m.at(pos).newDocCommentTree(comment, body, tags, preamble, postamble); return dc; } @@ -133,13 +154,17 @@ } } + protected List<DCTree> blockContent() { + return blockContent(Phase.BODY); + } + /** * Read block content, consisting of text, html and inline tags. * Terminated by the end of input, or the beginning of the next block tag: * i.e. @ as the first non-whitespace character on a line. */ @SuppressWarnings("fallthrough") - protected List<DCTree> blockContent() { + protected List<DCTree> blockContent(Phase phase) { ListBuffer<DCTree> trees = new ListBuffer<>(); textStart = -1; @@ -160,8 +185,36 @@ case '<': newline = false; + if (isFileContent) { + switch (phase) { + case PREAMBLE: + if (peek("body")) { + trees.add(html()); + if (textStart == -1) { + textStart = bp; + lastNonWhite = -1; + } + // mark this as the start, for processing purposes + newline = true; + break loop; + } + break; + case BODY: + if (peek("/body")) { + addPendingText(trees, lastNonWhite); + break loop; + } + break; + default: + // fallthrough + } + } addPendingText(trees, bp - 1); trees.add(html()); + + if (phase == Phase.PREAMBLE || phase == Phase.POSTAMBLE) { + break; // Ignore newlines after html tags, in the meta content + } if (textStart == -1) { textStart = bp; lastNonWhite = -1; @@ -734,11 +787,37 @@ } } + boolean peek(String s) { + final int savedpos = bp; + try { + if (ch == '<') + nextChar(); + + if (ch == '/') { + if (s.charAt(0) != ch) { + return false; + } else { + s = s.substring(1, s.length()); + nextChar(); + } + } + + if (isIdentifierStart(ch)) { + Name name = readIdentifier(); + return StringUtils.toLowerCase(name.toString()).equals(s); + } + return false; + } finally { + bp = savedpos; + ch = buf[bp]; + } + } + /** * Read the start or end of an HTML tag, or an HTML comment * {@literal <identifier attrs> } or {@literal </identifier> } */ - protected DCTree html() { + private DCTree html() { int p = bp; nextChar(); if (isIdentifierStart(ch)) { @@ -790,6 +869,19 @@ nextChar(); } } + } else if (isIdentifierStart(ch) && peek("doctype")) { + readIdentifier(); + nextChar(); + skipWhitespace(); + int d = bp; + while (bp < buflen) { + if (ch == '>') { + int mark = bp; + nextChar(); + return m.at(d).newDocTypeTree(newString(d, mark)); + } + nextChar(); + } } } @@ -1316,4 +1408,5 @@ tagParsers.put(names.fromString(p.getTreeKind().tagName), p); } + }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Sat Dec 02 06:51:10 2017 +0100 @@ -1319,6 +1319,9 @@ break loop; case DOT: nextToken(); + if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) { + return illegal(); + } int oldmode = mode; mode &= ~NOPARAMS; typeArgs = typeArgumentsOpt(EXPR);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Sat Dec 02 06:51:10 2017 +0100 @@ -1216,6 +1216,9 @@ compiler.misc.local.cant.infer.null=\ variable initializer is ''null'' +compiler.misc.local.cant.infer.void=\ + variable initializer is ''void'' + compiler.misc.local.missing.init=\ cannot use ''var'' on variable without initializer
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java Sat Dec 02 06:51:10 2017 +0100 @@ -109,17 +109,23 @@ public final List<DCTree> firstSentence; public final List<DCTree> body; public final List<DCTree> tags; + public final List<DCTree> preamble; + public final List<DCTree> postamble; public DCDocComment(Comment comment, List<DCTree> fullBody, List<DCTree> firstSentence, List<DCTree> body, - List<DCTree> tags) { + List<DCTree> tags, + List<DCTree> preamble, + List<DCTree> postamble) { this.comment = comment; this.firstSentence = firstSentence; this.fullBody = fullBody; this.body = body; this.tags = tags; + this.preamble = preamble; + this.postamble = postamble; } @Override @DefinedBy(Api.COMPILER_TREE) @@ -152,6 +158,15 @@ return tags; } + @Override @DefinedBy(Api.COMPILER_TREE) + public List<? extends DocTree> getPreamble() { + return preamble; + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public List<? extends DocTree> getPostamble() { + return postamble; + } } public static abstract class DCBlockTag extends DCTree implements BlockTagTree { @@ -288,6 +303,29 @@ } } + public static class DCDocType extends DCTree implements DocTypeTree { + public final String text; + + DCDocType(String text) { + this.text = text; + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public Kind getKind() { + return Kind.DOC_TYPE; + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public <R, D> R accept(DocTreeVisitor<R, D> v, D d) { + return v.visitDocType(this, d); + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public String getText() { + return text; + } + } + public static class DCEndElement extends DCTree implements EndElementTree { public final Name name;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java Sat Dec 02 06:51:10 2017 +0100 @@ -225,6 +225,16 @@ } @Override @DefinedBy(Api.COMPILER_TREE) + public Void visitDocType(DocTypeTree node, Void p) { + try { + print(node.getText()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return null; + } + + @Override @DefinedBy(Api.COMPILER_TREE) public Void visitEndElement(EndElementTree node, Void p) { try { print("</");
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java Sat Dec 02 06:51:10 2017 +0100 @@ -28,6 +28,7 @@ import java.text.BreakIterator; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.ListIterator; @@ -37,6 +38,7 @@ import javax.tools.JavaFileObject; import com.sun.source.doctree.AttributeTree.ValueKind; +import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocTree; import com.sun.source.doctree.DocTree.Kind; import com.sun.source.doctree.EndElementTree; @@ -59,6 +61,7 @@ import com.sun.tools.javac.tree.DCTree.DCDeprecated; import com.sun.tools.javac.tree.DCTree.DCDocComment; import com.sun.tools.javac.tree.DCTree.DCDocRoot; +import com.sun.tools.javac.tree.DCTree.DCDocType; import com.sun.tools.javac.tree.DCTree.DCEndElement; import com.sun.tools.javac.tree.DCTree.DCEntity; import com.sun.tools.javac.tree.DCTree.DCErroneous; @@ -195,9 +198,23 @@ return tree; } - public DCDocComment newDocCommentTree(Comment comment, List<? extends DocTree> fullBody, List<? extends DocTree> tags) { + @Override @DefinedBy(Api.COMPILER_TREE) + public DCDocComment newDocCommentTree(List<? extends DocTree> fullBody, List<? extends DocTree> tags) { Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody); - DCDocComment tree = new DCDocComment(comment, cast(fullBody), pair.fst, pair.snd, cast(tags)); + List<DCTree> preamble = Collections.emptyList(); + List<DCTree> postamble = Collections.emptyList(); + + return newDocCommentTree(fullBody, tags, preamble, postamble); + } + + public DCDocComment newDocCommentTree(Comment comment, + List<? extends DocTree> fullBody, + List<? extends DocTree> tags, + List<? extends DocTree> preamble, + List<? extends DocTree> postamble) { + Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody); + DCDocComment tree = new DCDocComment(comment, cast(fullBody), pair.fst, pair.snd, + cast(tags), cast(preamble), cast(postamble)); tree.pos = pos; return tree; } @@ -208,7 +225,10 @@ * where the trees are being synthesized by a tool. */ @Override @DefinedBy(Api.COMPILER_TREE) - public DCDocComment newDocCommentTree(List<? extends DocTree> fullBody, List<? extends DocTree> tags) { + public DCDocComment newDocCommentTree(List<? extends DocTree> fullBody, + List<? extends DocTree> tags, + List<? extends DocTree> preamble, + List<? extends DocTree> postamble) { ListBuffer<DCTree> lb = new ListBuffer<>(); lb.addAll(cast(fullBody)); List<DCTree> fBody = lb.toList(); @@ -236,7 +256,8 @@ } }; Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody); - DCDocComment tree = new DCDocComment(c, fBody, pair.fst, pair.snd, cast(tags)); + DCDocComment tree = new DCDocComment(c, fBody, pair.fst, pair.snd, cast(tags), + cast(preamble), cast(postamble)); return tree; } @@ -248,6 +269,13 @@ } @Override @DefinedBy(Api.COMPILER_TREE) + public DCDocType newDocTypeTree(String text) { + DCDocType tree = new DCDocType(text); + tree.pos = pos; + return tree; + } + + @Override @DefinedBy(Api.COMPILER_TREE) public DCEndElement newEndElementTree(Name name) { DCEndElement tree = new DCEndElement(name); tree.pos = pos;
--- a/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java Sat Dec 02 06:51:10 2017 +0100 @@ -61,6 +61,7 @@ import javax.tools.JavaCompiler; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; import javax.tools.SimpleJavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; @@ -214,7 +215,9 @@ } } - DocCommentTree docCommentTree = parseDocComment(task, docComment); + Pair<DocCommentTree, Integer> parsed = parseDocComment(task, docComment); + DocCommentTree docCommentTree = parsed.fst; + int offset = parsed.snd; IOException[] exception = new IOException[1]; Map<int[], String> replace = new TreeMap<>((span1, span2) -> span2[0] - span1[0]); @@ -349,7 +352,10 @@ if (inherited == null) { return null; } - DocCommentTree inheritedDocTree = parseDocComment(inheritedJavacTask, inherited); + Pair<DocCommentTree, Integer> parsed = + parseDocComment(inheritedJavacTask, inherited); + DocCommentTree inheritedDocTree = parsed.fst; + int offset = parsed.snd; List<List<? extends DocTree>> inheritedText = new ArrayList<>(); DocTree parent = interestingParent.peek(); switch (parent.getKind()) { @@ -391,7 +397,6 @@ break; } if (!inheritedText.isEmpty()) { - long offset = trees.getSourcePositions().getStartPosition(null, inheritedDocTree, inheritedDocTree); long start = Long.MAX_VALUE; long end = Long.MIN_VALUE; @@ -475,7 +480,6 @@ return docComment; StringBuilder replacedInheritDoc = new StringBuilder(docComment); - int offset = (int) trees.getSourcePositions().getStartPosition(null, docCommentTree, docCommentTree); for (Entry<int[], String> e : replace.entrySet()) { replacedInheritDoc.delete(e.getKey()[0] - offset, e.getKey()[1] - offset + 1); @@ -507,22 +511,28 @@ } private DocTree parseBlockTag(JavacTask task, String blockTag) { - DocCommentTree dc = parseDocComment(task, blockTag); + DocCommentTree dc = parseDocComment(task, blockTag).fst; return dc.getBlockTags().get(0); } - private DocCommentTree parseDocComment(JavacTask task, String javadoc) { + private Pair<DocCommentTree, Integer> parseDocComment(JavacTask task, String javadoc) { DocTrees trees = DocTrees.instance(task); try { - return trees.getDocCommentTree(new SimpleJavaFileObject(new URI("mem://doc.html"), javax.tools.JavaFileObject.Kind.HTML) { + SimpleJavaFileObject fo = + new SimpleJavaFileObject(new URI("mem://doc.html"), Kind.HTML) { @Override @DefinedBy(Api.COMPILER) - public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + public CharSequence getCharContent(boolean ignoreEncodingErrors) + throws IOException { return "<body>" + javadoc + "</body>"; } - }); + }; + DocCommentTree tree = trees.getDocCommentTree(fo); + int offset = (int) trees.getSourcePositions().getStartPosition(null, tree, tree); + offset += "<body>".length() + 1; + return Pair.of(tree, offset); } catch (URISyntaxException ex) { - return null; + throw new IllegalStateException(ex); } }
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanLinker.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanLinker.java Sat Dec 02 06:51:10 2017 +0100 @@ -91,6 +91,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.function.Function; import jdk.dynalink.CallSiteDescriptor; import jdk.dynalink.Namespace; import jdk.dynalink.Operation; @@ -189,85 +190,126 @@ assertParameterCount(callSiteDescriptor, isFixedKey ? 1 : 2); final LinkerServices linkerServices = req.linkerServices; final MethodType callSiteType = callSiteDescriptor.getMethodType(); - final Class<?> declaredType = callSiteType.parameterType(0); final GuardedInvocationComponent nextComponent = getNextComponent(req); + final GuardedInvocationComponentAndCollectionType gicact = guardedInvocationComponentAndCollectionType( + callSiteType, linkerServices, MethodHandles::arrayElementGetter, GET_LIST_ELEMENT, GET_MAP_ELEMENT); + + if (gicact == null) { + // Can't retrieve elements for objects that are neither arrays, nor list, nor maps. + return nextComponent; + } + + final Object typedName = getTypedName(name, gicact.collectionType == CollectionType.MAP, linkerServices); + if (typedName == INVALID_NAME) { + return nextComponent; + } + + return guardComponentWithRangeCheck(gicact, linkerServices, + callSiteDescriptor, nextComponent, new Binder(linkerServices, callSiteType, typedName), + isFixedKey ? NULL_GETTER_1 : NULL_GETTER_2); + } + + private static class GuardedInvocationComponentAndCollectionType { + final GuardedInvocationComponent gic; + final CollectionType collectionType; + + GuardedInvocationComponentAndCollectionType(final GuardedInvocationComponent gic, final CollectionType collectionType) { + this.gic = gic; + this.collectionType = collectionType; + } + } + + private GuardedInvocationComponentAndCollectionType guardedInvocationComponentAndCollectionType( + final MethodType callSiteType, final LinkerServices linkerServices, + final Function<Class<?>, MethodHandle> arrayMethod, final MethodHandle listMethod, final MethodHandle mapMethod) { + final Class<?> declaredType = callSiteType.parameterType(0); // If declared type of receiver at the call site is already an array, a list or map, bind without guard. Thing // is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance they're // dealing with an array, or a list or map, but hey... // Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers // in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices. - final GuardedInvocationComponent gic; - final CollectionType collectionType; if(declaredType.isArray()) { - gic = createInternalFilteredGuardedInvocationComponent(MethodHandles.arrayElementGetter(declaredType), linkerServices); - collectionType = CollectionType.ARRAY; + return new GuardedInvocationComponentAndCollectionType( + createInternalFilteredGuardedInvocationComponent(arrayMethod.apply(declaredType), linkerServices), + CollectionType.ARRAY); } else if(List.class.isAssignableFrom(declaredType)) { - gic = createInternalFilteredGuardedInvocationComponent(GET_LIST_ELEMENT, linkerServices); - collectionType = CollectionType.LIST; + return new GuardedInvocationComponentAndCollectionType( + createInternalFilteredGuardedInvocationComponent(listMethod, linkerServices), + CollectionType.LIST); } else if(Map.class.isAssignableFrom(declaredType)) { - gic = createInternalFilteredGuardedInvocationComponent(GET_MAP_ELEMENT, linkerServices); - collectionType = CollectionType.MAP; + return new GuardedInvocationComponentAndCollectionType( + createInternalFilteredGuardedInvocationComponent(mapMethod, linkerServices), + CollectionType.MAP); } else if(clazz.isArray()) { - gic = getClassGuardedInvocationComponent(linkerServices.filterInternalObjects(MethodHandles.arrayElementGetter(clazz)), callSiteType); - collectionType = CollectionType.ARRAY; + return new GuardedInvocationComponentAndCollectionType( + getClassGuardedInvocationComponent(linkerServices.filterInternalObjects(arrayMethod.apply(clazz)), callSiteType), + CollectionType.ARRAY); } else if(List.class.isAssignableFrom(clazz)) { - gic = createInternalFilteredGuardedInvocationComponent(GET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class, ValidationType.INSTANCE_OF, - linkerServices); - collectionType = CollectionType.LIST; + return new GuardedInvocationComponentAndCollectionType( + createInternalFilteredGuardedInvocationComponent(listMethod, Guards.asType(LIST_GUARD, callSiteType), + List.class, ValidationType.INSTANCE_OF, linkerServices), + CollectionType.LIST); } else if(Map.class.isAssignableFrom(clazz)) { - gic = createInternalFilteredGuardedInvocationComponent(GET_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), Map.class, ValidationType.INSTANCE_OF, - linkerServices); - collectionType = CollectionType.MAP; - } else { - // Can't retrieve elements for objects that are neither arrays, nor list, nor maps. - return nextComponent; + return new GuardedInvocationComponentAndCollectionType( + createInternalFilteredGuardedInvocationComponent(mapMethod, Guards.asType(MAP_GUARD, callSiteType), + Map.class, ValidationType.INSTANCE_OF, linkerServices), + CollectionType.MAP); } + return null; + } + private static final Object INVALID_NAME = new Object(); + + private static Object getTypedName(final Object name, final boolean isMap, final LinkerServices linkerServices) throws Exception { // Convert the key to a number if we're working with a list or array - final Object typedName; - if (collectionType != CollectionType.MAP && isFixedKey) { + if (!isMap && name != null) { final Integer integer = convertKeyToInteger(name, linkerServices); if (integer == null || integer.intValue() < 0) { // key is not a non-negative integer, it can never address an // array or list element - return nextComponent; + return INVALID_NAME; } - typedName = integer; - } else { - typedName = name; + return integer; + } + return name; + } + + private static GuardedInvocationComponent guardComponentWithRangeCheck( + final GuardedInvocationComponentAndCollectionType gicact, final LinkerServices linkerServices, + final CallSiteDescriptor callSiteDescriptor, final GuardedInvocationComponent nextComponent, final Binder binder, + final MethodHandle noOp) { + final MethodType callSiteType = callSiteDescriptor.getMethodType(); + + final MethodHandle checkGuard; + switch(gicact.collectionType) { + case LIST: + checkGuard = convertArgToNumber(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor); + break; + case MAP: + checkGuard = linkerServices.filterInternalObjects(CONTAINS_MAP); + break; + case ARRAY: + checkGuard = convertArgToNumber(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor); + break; + default: + throw new AssertionError(); } - final GuardedInvocation gi = gic.getGuardedInvocation(); - final Binder binder = new Binder(linkerServices, callSiteType, typedName); - final MethodHandle invocation = gi.getInvocation(); - - final MethodHandle checkGuard; - switch(collectionType) { - case LIST: - checkGuard = convertArgToNumber(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor); - break; - case MAP: - checkGuard = linkerServices.filterInternalObjects(CONTAINS_MAP); - break; - case ARRAY: - checkGuard = convertArgToNumber(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor); - break; - default: - throw new AssertionError(); - } - - // If there's no next component, produce a fixed null-returning one + // If there's no next component, produce a fixed no-op one final GuardedInvocationComponent finalNextComponent; if (nextComponent != null) { finalNextComponent = nextComponent; } else { - final MethodHandle nullGetterHandle = isFixedKey ? NULL_GETTER_1 : NULL_GETTER_2; - finalNextComponent = createGuardedInvocationComponentAsType(nullGetterHandle, callSiteType, linkerServices); + finalNextComponent = createGuardedInvocationComponentAsType(noOp, callSiteType, linkerServices); } - final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation), + final GuardedInvocationComponent gic = gicact.gic; + final GuardedInvocation gi = gic.getGuardedInvocation(); + + final MethodPair matchedInvocations = matchReturnTypes(binder.bind(gi.getInvocation()), finalNextComponent.getGuardedInvocation().getInvocation()); + return finalNextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(), gic.getValidatorClass(), gic.getValidationType()); } @@ -435,90 +477,37 @@ assertParameterCount(callSiteDescriptor, isFixedKey ? 2 : 3); final LinkerServices linkerServices = req.linkerServices; final MethodType callSiteType = callSiteDescriptor.getMethodType(); - final Class<?> declaredType = callSiteType.parameterType(0); - final GuardedInvocationComponent gic; - // If declared type of receiver at the call site is already an array, a list or map, bind without guard. Thing - // is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance they're - // dealing with an array, or a list or map, but hey... - // Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers - // in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices. - final CollectionType collectionType; - if(declaredType.isArray()) { - gic = createInternalFilteredGuardedInvocationComponent(MethodHandles.arrayElementSetter(declaredType), linkerServices); - collectionType = CollectionType.ARRAY; - } else if(List.class.isAssignableFrom(declaredType)) { - gic = createInternalFilteredGuardedInvocationComponent(SET_LIST_ELEMENT, linkerServices); - collectionType = CollectionType.LIST; - } else if(Map.class.isAssignableFrom(declaredType)) { - gic = createInternalFilteredGuardedInvocationComponent(PUT_MAP_ELEMENT, linkerServices); - collectionType = CollectionType.MAP; - } else if(clazz.isArray()) { - gic = getClassGuardedInvocationComponent(linkerServices.filterInternalObjects( - MethodHandles.arrayElementSetter(clazz)), callSiteType); - collectionType = CollectionType.ARRAY; - } else if(List.class.isAssignableFrom(clazz)) { - gic = createInternalFilteredGuardedInvocationComponent(SET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class, ValidationType.INSTANCE_OF, - linkerServices); - collectionType = CollectionType.LIST; - } else if(Map.class.isAssignableFrom(clazz)) { - gic = createInternalFilteredGuardedInvocationComponent(PUT_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), - Map.class, ValidationType.INSTANCE_OF, linkerServices); - collectionType = CollectionType.MAP; - } else { - // Can't set elements for objects that are neither arrays, nor list, nor maps. - gic = null; - collectionType = null; + final GuardedInvocationComponentAndCollectionType gicact = guardedInvocationComponentAndCollectionType( + callSiteType, linkerServices, MethodHandles::arrayElementSetter, SET_LIST_ELEMENT, PUT_MAP_ELEMENT); + + if(gicact == null) { + return getNextComponent(req); } + final boolean isMap = gicact.collectionType == CollectionType.MAP; + // In contrast to, say, getElementGetter, we only compute the nextComponent if the target object is not a map, // as maps will always succeed in setting the element and will never need to fall back to the next component // operation. - final GuardedInvocationComponent nextComponent = collectionType == CollectionType.MAP ? null : getNextComponent(req); - if(gic == null) { + final GuardedInvocationComponent nextComponent = isMap ? null : getNextComponent(req); + + final Object typedName = getTypedName(name, isMap, linkerServices); + if (typedName == INVALID_NAME) { return nextComponent; } - // Convert the key to a number if we're working with a list or array - final Object typedName; - if (collectionType != CollectionType.MAP && isFixedKey) { - final Integer integer = convertKeyToInteger(name, linkerServices); - if (integer == null || integer.intValue() < 0) { - // key is not a non-negative integer, it can never address an - // array or list element - return nextComponent; - } - typedName = integer; - } else { - typedName = name; - } - + final GuardedInvocationComponent gic = gicact.gic; final GuardedInvocation gi = gic.getGuardedInvocation(); final Binder binder = new Binder(linkerServices, callSiteType, typedName); final MethodHandle invocation = gi.getInvocation(); - if (collectionType == CollectionType.MAP) { - assert nextComponent == null; + if (isMap) { return gic.replaceInvocation(binder.bind(invocation)); } - assert collectionType == CollectionType.LIST || collectionType == CollectionType.ARRAY; - final MethodHandle checkGuard = convertArgToNumber(collectionType == CollectionType.LIST ? RANGE_CHECK_LIST : - RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor); - - // If there's no next component, produce a no-op one. - final GuardedInvocationComponent finalNextComponent; - if (nextComponent != null) { - finalNextComponent = nextComponent; - } else { - final MethodHandle noOpSetterHandle = isFixedKey ? NO_OP_SETTER_2 : NO_OP_SETTER_3; - finalNextComponent = createGuardedInvocationComponentAsType(noOpSetterHandle, callSiteType, linkerServices); - } - - final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation), - finalNextComponent.getGuardedInvocation().getInvocation()); - return finalNextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(), - gic.getValidatorClass(), gic.getValidationType()); + return guardComponentWithRangeCheck(gicact, linkerServices, callSiteDescriptor, + nextComponent, binder, isFixedKey ? NO_OP_SETTER_2 : NO_OP_SETTER_3); } private static final MethodHandle GET_COLLECTION_LENGTH = Lookup.PUBLIC.findVirtual(Collection.class, "size",
--- a/src/jdk.jartool/share/classes/sun/tools/jar/FingerPrint.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.jartool/share/classes/sun/tools/jar/FingerPrint.java Sat Dec 02 06:51:10 2017 +0100 @@ -43,7 +43,7 @@ * a class, it also contains information to (1) describe the public API; * (2) compare the public API of this class with another class; (3) determine * whether or not it's a nested class and, if so, the name of the associated - * top level class; and (4) for an canonically ordered set of classes determine + * outer class; and (4) for an canonically ordered set of classes determine * if the class versions are compatible. A set of classes is canonically * ordered if the classes in the set have the same name, and the base class * precedes the versioned classes and if each versioned class with version @@ -53,10 +53,13 @@ final class FingerPrint { private static final MessageDigest MD; + private final String basename; + private final String entryName; + private final int mrversion; + private final byte[] sha1; private final ClassAttributes attrs; private final boolean isClassEntry; - private final String entryName; static { try { @@ -67,16 +70,19 @@ } } - public FingerPrint(String entryName,byte[] bytes) throws IOException { + public FingerPrint(String basename, String entryName, int mrversion, byte[] bytes) + throws IOException { + this.basename = basename; this.entryName = entryName; - if (entryName.endsWith(".class") && isCafeBabe(bytes)) { + this.mrversion = mrversion; + if (isCafeBabe(bytes)) { isClassEntry = true; sha1 = sha1(bytes, 8); // skip magic number and major/minor version attrs = getClassAttributes(bytes); } else { isClassEntry = false; - sha1 = sha1(bytes); - attrs = new ClassAttributes(); // empty class + sha1 = null; + attrs = null; } } @@ -107,14 +113,24 @@ return attrs.equals(that.attrs); } - public String name() { - String name = attrs.name; - return name == null ? entryName : name; + public String basename() { + return basename; } - public String topLevelName() { - String name = attrs.topLevelName; - return name == null ? name() : name; + public String entryName() { + return entryName; + } + + public String className() { + return attrs.name; + } + + public int mrversion() { + return mrversion; + } + + public String outerClassName() { + return attrs.outerClassName; } private byte[] sha1(byte[] entry) { @@ -218,7 +234,7 @@ private static final class ClassAttributes extends ClassVisitor { private String name; - private String topLevelName; + private String outerClassName; private String superName; private int version; private int access; @@ -228,7 +244,7 @@ private final Set<Method> methods = new HashSet<>(); public ClassAttributes() { - super(Opcodes.ASM5); + super(Opcodes.ASM6); } private boolean isPublic(int access) { @@ -250,7 +266,7 @@ @Override public void visitOuterClass(String owner, String name, String desc) { if (!this.nestedClass) return; - this.topLevelName = owner; + this.outerClassName = owner; } @Override @@ -259,7 +275,7 @@ if (!this.nestedClass) return; if (outerName == null) return; if (!this.name.equals(name)) return; - if (this.topLevelName == null) this.topLevelName = outerName; + if (this.outerClassName == null) this.outerClassName = outerName; } @Override @@ -294,7 +310,7 @@ @Override public void visitEnd() { - this.nestedClass = this.topLevelName != null; + this.nestedClass = this.outerClassName != null; } @Override
--- a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java Sat Dec 02 06:51:10 2017 +0100 @@ -71,7 +71,6 @@ import static java.util.jar.JarFile.MANIFEST_NAME; import static java.util.stream.Collectors.joining; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; -import static sun.tools.jar.Validator.ENTRYNAME_COMPARATOR; /** * This class implements a simple utility for creating files in the JAR @@ -444,8 +443,8 @@ private void validateAndClose(File tmpfile) throws IOException { if (ok && isMultiRelease) { - try (JarFile jf = new JarFile(tmpfile)) { - ok = Validator.validate(this, jf); + try (ZipFile zf = new ZipFile(tmpfile)) { + ok = Validator.validate(this, zf); if (!ok) { error(formatMsg("error.validator.jarfile.invalid", fname)); } @@ -1784,7 +1783,7 @@ private boolean describeModule(ZipFile zipFile) throws IOException { ZipFileModuleInfoEntry[] infos = zipFile.stream() .filter(e -> isModuleInfoEntry(e.getName())) - .sorted(Validator.ENTRY_COMPARATOR) + .sorted(ENTRY_COMPARATOR) .map(e -> new ZipFileModuleInfoEntry(zipFile, e)) .toArray(ZipFileModuleInfoEntry[]::new); @@ -2216,4 +2215,48 @@ return hashesBuilder.computeHashes(Set.of(name)).get(name); } } + + // sort base entries before versioned entries, and sort entry classes with + // nested classes so that the outter class appears before the associated + // nested class + static Comparator<String> ENTRYNAME_COMPARATOR = (s1, s2) -> { + + if (s1.equals(s2)) return 0; + boolean b1 = s1.startsWith(VERSIONS_DIR); + boolean b2 = s2.startsWith(VERSIONS_DIR); + if (b1 && !b2) return 1; + if (!b1 && b2) return -1; + int n = 0; // starting char for String compare + if (b1 && b2) { + // normally strings would be sorted so "10" goes before "9", but + // version number strings need to be sorted numerically + n = VERSIONS_DIR.length(); // skip the common prefix + int i1 = s1.indexOf('/', n); + int i2 = s2.indexOf('/', n); + if (i1 == -1) throw new Validator.InvalidJarException(s1); + if (i2 == -1) throw new Validator.InvalidJarException(s2); + // shorter version numbers go first + if (i1 != i2) return i1 - i2; + // otherwise, handle equal length numbers below + } + int l1 = s1.length(); + int l2 = s2.length(); + int lim = Math.min(l1, l2); + for (int k = n; k < lim; k++) { + char c1 = s1.charAt(k); + char c2 = s2.charAt(k); + if (c1 != c2) { + // change natural ordering so '.' comes before '$' + // i.e. outer classes come before nested classes + if (c1 == '$' && c2 == '.') return 1; + if (c1 == '.' && c2 == '$') return -1; + return c1 - c2; + } + } + return l1 - l2; + }; + + static Comparator<ZipEntry> ENTRY_COMPARATOR = + Comparator.comparing(ZipEntry::getName, ENTRYNAME_COMPARATOR); + }
--- a/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java Sat Dec 02 11:25:35 2017 +0530 +++ b/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java Sat Dec 02 06:51:10 2017 +0100 @@ -28,24 +28,22 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.lang.module.InvalidModuleDescriptorException; import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleDescriptor.Exports; -import java.lang.module.InvalidModuleDescriptorException; import java.lang.module.ModuleDescriptor.Opens; import java.lang.module.ModuleDescriptor.Provides; import java.lang.module.ModuleDescriptor.Requires; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Consumer; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; +import java.util.TreeMap; +import java.util.function.Function; +import java.util.stream.Collectors; import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import static java.util.jar.JarFile.MANIFEST_NAME; import static sun.tools.jar.Main.VERSIONS_DIR; @@ -55,269 +53,176 @@ import static sun.tools.jar.Main.formatMsg; import static sun.tools.jar.Main.formatMsg2; import static sun.tools.jar.Main.toBinaryName; -import static sun.tools.jar.Main.isModuleInfoEntry; final class Validator { - private final static boolean DEBUG = Boolean.getBoolean("jar.debug"); - private final Map<String,FingerPrint> fps = new HashMap<>(); + + private final Map<String,FingerPrint> classes = new HashMap<>(); private final Main main; - private final JarFile jf; - private int oldVersion = -1; - private String currentTopLevelName; + private final ZipFile zf; private boolean isValid = true; private Set<String> concealedPkgs = Collections.emptySet(); private ModuleDescriptor md; private String mdName; - private Validator(Main main, JarFile jf) { + private Validator(Main main, ZipFile zf) { this.main = main; - this.jf = jf; + this.zf = zf; checkModuleDescriptor(MODULE_INFO); } - static boolean validate(Main main, JarFile jf) throws IOException { - return new Validator(main, jf).validate(); + static boolean validate(Main main, ZipFile zf) throws IOException { + return new Validator(main, zf).validate(); } private boolean validate() { try { - jf.stream() - .filter(e -> !e.isDirectory() && - !e.getName().equals(MANIFEST_NAME)) - .sorted(ENTRY_COMPARATOR) - .forEachOrdered(e -> validate(e)); - return isValid; + zf.stream() + .filter(e -> e.getName().endsWith(".class")) + .map(this::getFingerPrint) + .filter(FingerPrint::isClass) // skip any non-class entry + .collect(Collectors.groupingBy( + FingerPrint::mrversion, + TreeMap::new, + Collectors.toMap(FingerPrint::className, + Function.identity(), + this::sameNameFingerPrint))) + .forEach((version, entries) -> { + if (version == 0) + validateBase(entries); + else + validateVersioned(entries); + }); } catch (InvalidJarException e) { - error(formatMsg("error.validator.bad.entry.name", e.getMessage())); + errorAndInvalid(e.getMessage()); } - return false; + return isValid; } - private static class InvalidJarException extends RuntimeException { + static class InvalidJarException extends RuntimeException { private static final long serialVersionUID = -3642329147299217726L; InvalidJarException(String msg) { super(msg); } } - // sort base entries before versioned entries, and sort entry classes with - // nested classes so that the top level class appears before the associated - // nested class - static Comparator<String> ENTRYNAME_COMPARATOR = (s1, s2) -> { + private FingerPrint sameNameFingerPrint(FingerPrint fp1, FingerPrint fp2) { + checkClassName(fp1); + checkClassName(fp2); + // entries/classes with same name, return fp2 for now ? + return fp2; + } - if (s1.equals(s2)) return 0; - boolean b1 = s1.startsWith(VERSIONS_DIR); - boolean b2 = s2.startsWith(VERSIONS_DIR); - if (b1 && !b2) return 1; - if (!b1 && b2) return -1; - int n = 0; // starting char for String compare - if (b1 && b2) { - // normally strings would be sorted so "10" goes before "9", but - // version number strings need to be sorted numerically - n = VERSIONS_DIR.length(); // skip the common prefix - int i1 = s1.indexOf('/', n); - int i2 = s2.indexOf('/', n); - if (i1 == -1) throw new InvalidJarException(s1); - if (i2 == -1) throw new InvalidJarException(s2); - // shorter version numbers go first - if (i1 != i2) return i1 - i2; - // otherwise, handle equal length numbers below + private FingerPrint getFingerPrint(ZipEntry ze) { + // figure out the version and basename from the ZipEntry + String ename = ze.getName(); + String bname = ename; + int version = 0; + + if (ename.startsWith(VERSIONS_DIR)) { + int n = ename.indexOf("/", VERSIONS_DIR_LENGTH); + if (n == -1) { + throw new InvalidJarException( + formatMsg("error.validator.version.notnumber", ename)); + } + try { + version = Integer.parseInt(ename, VERSIONS_DIR_LENGTH, n, 10); + } catch (NumberFormatException x) { + throw new InvalidJarException( + formatMsg("error.validator.version.notnumber", ename)); + } + if (n == ename.length()) { + throw new InvalidJarException( + formatMsg("error.validator.entryname.tooshort", ename)); + } + bname = ename.substring(n + 1); } - int l1 = s1.length(); - int l2 = s2.length(); - int lim = Math.min(l1, l2); - for (int k = n; k < lim; k++) { - char c1 = s1.charAt(k); - char c2 = s2.charAt(k); - if (c1 != c2) { - // change natural ordering so '.' comes before '$' - // i.e. top level classes come before nested classes - if (c1 == '$' && c2 == '.') return 1; - if (c1 == '.' && c2 == '$') return -1; - return c1 - c2; - } + + // return the cooresponding fingerprint entry + try (InputStream is = zf.getInputStream(ze)) { + return new FingerPrint(bname, ename, version, is.readAllBytes()); + } catch (IOException x) { + throw new InvalidJarException(x.getMessage()); } - return l1 - l2; - }; - - static Comparator<ZipEntry> ENTRY_COMPARATOR = - Comparator.comparing(ZipEntry::getName, ENTRYNAME_COMPARATOR); + } /* - * Validator has state and assumes entries provided to accept are ordered - * from base entries first and then through the versioned entries in - * ascending version order. Also, to find isolated nested classes, - * classes must be ordered so that the top level class is before the associated - * nested class(es). - */ - public void validate(JarEntry je) { - String entryName = je.getName(); - - // directories are always accepted - if (entryName.endsWith("/")) { - debug("%s is a directory", entryName); - return; - } - - // validate the versioned module-info - if (isModuleInfoEntry(entryName)) { - if (!entryName.equals(mdName)) - checkModuleDescriptor(entryName); - return; - } - - // figure out the version and basename from the JarEntry - int version; - String basename; - String versionStr = null;; - if (entryName.startsWith(VERSIONS_DIR)) { - int n = entryName.indexOf("/", VERSIONS_DIR_LENGTH); - if (n == -1) { - error(formatMsg("error.validator.version.notnumber", entryName)); - isValid = false; + * Validates (a) if there is any isolated nested class, and (b) if the + * class name in class file (by asm) matches the entry's basename. + */ + public void validateBase(Map<String, FingerPrint> fps) { + fps.values().forEach( fp -> { + if (!checkClassName(fp)) { return; } - versionStr = entryName.substring(VERSIONS_DIR_LENGTH, n); - try { - version = Integer.parseInt(versionStr); - } catch (NumberFormatException x) { - error(formatMsg("error.validator.version.notnumber", entryName)); - isValid = false; + if (fp.isNestedClass()) { + checkNestedClass(fp, fps); + } + classes.put(fp.className(), fp); + }); + } + + public void validateVersioned(Map<String, FingerPrint> fps) { + + fps.values().forEach( fp -> { + + // validate the versioned module-info + if (MODULE_INFO.equals(fp.basename())) { + checkModuleDescriptor(fp.entryName()); return; } - if (n == entryName.length()) { - error(formatMsg("error.validator.entryname.tooshort", entryName)); - isValid = false; - return; - } - basename = entryName.substring(n + 1); - } else { - version = 0; - basename = entryName; - } - debug("\n===================\nversion %d %s", version, entryName); - - if (oldVersion != version) { - oldVersion = version; - currentTopLevelName = null; - if (md == null && versionStr != null) { - // don't have a base module-info.class yet, try to see if - // a versioned one exists - checkModuleDescriptor(VERSIONS_DIR + versionStr + "/" + MODULE_INFO); - } - } - - // analyze the entry, keeping key attributes - FingerPrint fp; - try (InputStream is = jf.getInputStream(je)) { - fp = new FingerPrint(basename, is.readAllBytes()); - } catch (IOException x) { - error(x.getMessage()); - isValid = false; - return; - } - String internalName = fp.name(); - - // process a base entry paying attention to nested classes - if (version == 0) { - debug("base entry found"); - if (fp.isNestedClass()) { - debug("nested class found"); - if (fp.topLevelName().equals(currentTopLevelName)) { - fps.put(internalName, fp); - return; - } - error(formatMsg("error.validator.isolated.nested.class", entryName)); - isValid = false; - return; - } - // top level class or resource entry - if (fp.isClass()) { - currentTopLevelName = fp.topLevelName(); - if (!checkInternalName(entryName, basename, internalName)) { - isValid = false; - return; - } - } - fps.put(internalName, fp); - return; - } - - // process a versioned entry, look for previous entry with same name - FingerPrint matchFp = fps.get(internalName); - debug("looking for match"); - if (matchFp == null) { - debug("no match found"); - if (fp.isClass()) { + // process a versioned entry, look for previous entry with same name + FingerPrint matchFp = classes.get(fp.className()); + if (matchFp == null) { + // no match found if (fp.isNestedClass()) { - if (!checkNestedClass(version, entryName, internalName, fp)) { - isValid = false; - } + checkNestedClass(fp, fps); return; } if (fp.isPublicClass()) { - if (!isConcealed(internalName)) { - error(Main.formatMsg("error.validator.new.public.class", entryName)); - isValid = false; + if (!isConcealed(fp.className())) { + errorAndInvalid(formatMsg("error.validator.new.public.class", + fp.entryName())); return; - } - warn(formatMsg("warn.validator.concealed.public.class", entryName)); - debug("%s is a public class entry in a concealed package", entryName); + } + // entry is a public class entry in a concealed package + warn(formatMsg("warn.validator.concealed.public.class", + fp.entryName())); } - debug("%s is a non-public class entry", entryName); - fps.put(internalName, fp); - currentTopLevelName = fp.topLevelName(); + classes.put(fp.className(), fp); return; } - debug("%s is a resource entry"); - fps.put(internalName, fp); - return; - } - debug("match found"); - // are the two classes/resources identical? - if (fp.isIdentical(matchFp)) { - warn(formatMsg("warn.validator.identical.entry", entryName)); - return; // it's okay, just takes up room - } - debug("sha1 not equal -- different bytes"); + // are the two classes/resources identical? + if (fp.isIdentical(matchFp)) { + warn(formatMsg("warn.validator.identical.entry", fp.entryName())); + return; // it's okay, just takes up room + } - // ok, not identical, check for compatible class version and api - if (fp.isClass()) { + // ok, not identical, check for compatible class version and api if (fp.isNestedClass()) { - if (!checkNestedClass(version, entryName, internalName, fp)) { - isValid = false; - } - return; + checkNestedClass(fp, fps); + return; // fall through, need check nested public class?? } - debug("%s is a class entry", entryName); if (!fp.isCompatibleVersion(matchFp)) { - error(formatMsg("error.validator.incompatible.class.version", entryName)); - isValid = false; + errorAndInvalid(formatMsg("error.validator.incompatible.class.version", + fp.entryName())); return; } if (!fp.isSameAPI(matchFp)) { - error(formatMsg("error.validator.different.api", entryName)); - isValid = false; + errorAndInvalid(formatMsg("error.validator.different.api", + fp.entryName())); return; } - if (!checkInternalName(entryName, basename, internalName)) { - isValid = false; + if (!checkClassName(fp)) { return; } - debug("fingerprints same -- same api"); - fps.put(internalName, fp); - currentTopLevelName = fp.topLevelName(); + classes.put(fp.className(), fp); + return; - } - debug("%s is a resource", entryName); - - warn(formatMsg("warn.validator.resources.with.same.name", entryName)); - fps.put(internalName, fp); - return; + }); } - /** + /* * Checks whether or not the given versioned module descriptor's attributes * are valid when compared against the root/base module descriptor. * @@ -326,12 +231,12 @@ * - A versioned descriptor can have different non-public `requires` * clauses of platform ( `java.*` and `jdk.*` ) modules, and * - A versioned descriptor can have different `uses` clauses, even of - * service types defined outside of the platform modules. + * service types defined outside of the platform modules. */ private void checkModuleDescriptor(String miName) { - ZipEntry je = jf.getEntry(miName); - if (je != null) { - try (InputStream jis = jf.getInputStream(je)) { + ZipEntry ze = zf.getEntry(miName); + if (ze != null) { + try (InputStream jis = zf.getInputStream(ze)) { ModuleDescriptor md = ModuleDescriptor.read(jis); // Initialize the base md if it's not yet. A "base" md can be either the // root module-info.class or the first versioned module-info.class @@ -344,7 +249,7 @@ // must have the implementation class of the services it 'provides'. if (md.provides().stream().map(Provides::providers) .flatMap(List::stream) - .filter(p -> jf.getEntry(toBinaryName(p)) == null) + .filter(p -> zf.getEntry(toBinaryName(p)) == null) .peek(p -> error(formatMsg("error.missing.provider", p))) .count() != 0) { isValid = false; @@ -356,8 +261,7 @@ } if (!base.name().equals(md.name())) { - error(getMsg("error.validator.info.name.notequal")); - isValid = false; + errorAndInvalid(getMsg("error.validator.info.name.notequal")); } if (!base.requires().equals(md.requires())) { Set<Requires> baseRequires = base.requires(); @@ -365,11 +269,9 @@ if (baseRequires.contains(r)) continue; if (r.modifiers().contains(Requires.Modifier.TRANSITIVE)) { - error(getMsg("error.validator.info.requires.transitive")); - isValid = false; + errorAndInvalid(getMsg("error.validator.info.requires.transitive")); } else if (!isPlatformModule(r.name())) { - error(getMsg("error.validator.info.requires.added")); - isValid = false; + errorAndInvalid(getMsg("error.validator.info.requires.added")); } } for (Requires r : baseRequires) { @@ -377,87 +279,79 @@ if (mdRequires.contains(r)) continue; if (!isPlatformModule(r.name())) { - error(getMsg("error.validator.info.requires.dropped")); - isValid = false; + errorAndInvalid(getMsg("error.validator.info.requires.dropped")); } } } if (!base.exports().equals(md.exports())) { - error(getMsg("error.validator.info.exports.notequal")); - isValid = false; + errorAndInvalid(getMsg("error.validator.info.exports.notequal")); } if (!base.opens().equals(md.opens())) { - error(getMsg("error.validator.info.opens.notequal")); - isValid = false; + errorAndInvalid(getMsg("error.validator.info.opens.notequal")); } if (!base.provides().equals(md.provides())) { - error(getMsg("error.validator.info.provides.notequal")); - isValid = false; + errorAndInvalid(getMsg("error.validator.info.provides.notequal")); } if (!base.mainClass().equals(md.mainClass())) { - error(formatMsg("error.validator.info.manclass.notequal", je.getName())); - isValid = false; + errorAndInvalid(formatMsg("error.validator.info.manclass.notequal", + ze.getName())); } if (!base.version().equals(md.version())) { - error(formatMsg("error.validator.info.version.notequal", je.getName())); - isValid = false; + errorAndInvalid(formatMsg("error.validator.info.version.notequal", + ze.getName())); } } catch (Exception x) { - error(x.getMessage() + " : " + miName); - this.isValid = false; + errorAndInvalid(x.getMessage() + " : " + miName); } } } + private boolean checkClassName(FingerPrint fp) { + if (fp.className().equals(className(fp.basename()))) { + return true; + } + error(formatMsg2("error.validator.names.mismatch", + fp.entryName(), fp.className().replace("/", "."))); + return isValid = false; + } + + private boolean checkNestedClass(FingerPrint fp, Map<String, FingerPrint> outerClasses) { + if (outerClasses.containsKey(fp.outerClassName())) { + return true; + } + // outer class was not available + + error(formatMsg("error.validator.isolated.nested.class", fp.entryName())); + return isValid = false; + } + + private boolean isConcealed(String className) { + if (concealedPkgs.isEmpty()) { + return false; + } + int idx = className.lastIndexOf('/'); + String pkgName = idx != -1 ? className.substring(0, idx).replace('/', '.') : ""; + return concealedPkgs.contains(pkgName); + } + private static boolean isPlatformModule(String name) { return name.startsWith("java.") || name.startsWith("jdk."); } - private boolean checkInternalName(String entryName, String basename, String internalName) { - String className = className(basename); - if (internalName.equals(className)) { - return true; - } - error(formatMsg2("error.validator.names.mismatch", - entryName, internalName.replace("/", "."))); - return false; - } - - private boolean checkNestedClass(int version, String entryName, String internalName, FingerPrint fp) { - debug("%s is a nested class entry in top level class %s", entryName, fp.topLevelName()); - if (fp.topLevelName().equals(currentTopLevelName)) { - debug("%s (top level class) was accepted", fp.topLevelName()); - fps.put(internalName, fp); - return true; - } - debug("top level class was not accepted"); - error(formatMsg("error.validator.isolated.nested.class", entryName)); - return false; - } - - private String className(String entryName) { + private static String className(String entryName) { return entryName.endsWith(".class") ? entryName.substring(0, entryName.length() - 6) : null; } - private boolean isConcealed(String internalName) { - if (concealedPkgs.isEmpty()) { - return false; - } - int idx = internalName.lastIndexOf('/'); - String pkgName = idx != -1 ? internalName.substring(0, idx).replace('/', '.') : ""; - return concealedPkgs.contains(pkgName); - } - - private void debug(String fmt, Object... args) { - if (DEBUG) System.err.format(fmt, args); - } - private void error(String msg) { main.error(msg); } + private void errorAndInvalid(String msg) { + main.error(msg); + isValid = false; + } + private void warn(String msg) { main.warn(msg); } - }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java Sat Dec 02 06:51:10 2017 +0100 @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.javadoc.internal.doclets.formats.html; + +import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.EndElementTree; +import com.sun.source.doctree.StartElementTree; +import com.sun.source.doctree.TextTree; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; +import jdk.javadoc.internal.doclets.toolkit.Content; +import jdk.javadoc.internal.doclets.toolkit.DocFileElement; +import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler; +import jdk.javadoc.internal.doclets.toolkit.util.DocFile; +import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; +import jdk.javadoc.internal.doclets.toolkit.util.DocPath; +import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; +import jdk.javadoc.internal.doclets.toolkit.util.Utils; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ModuleElement; +import javax.lang.model.element.PackageElement; +import javax.tools.FileObject; +import javax.tools.JavaFileManager.Location; +import java.util.Collections; +import java.util.List; + +public class DocFilesHandlerImpl implements DocFilesHandler { + + public final Element element; + public final Location location; + public final DocPath source; + public final HtmlConfiguration configuration; + + /** + * Constructor to construct the DocFilesWriter object. + * + * @param configuration the configuration of this doclet. + * @param element the containing element of the doc-files. + * + */ + public DocFilesHandlerImpl(HtmlConfiguration configuration, Element element) { + this.configuration = configuration; + this.element = element; + + switch (element.getKind()) { + case MODULE: + location = configuration.utils.getLocationForModule((ModuleElement)element); + source = DocPaths.DOC_FILES; + break; + case PACKAGE: + location = configuration.utils.getLocationForPackage((PackageElement)element); + source = DocPath.forPackage((PackageElement)element).resolve(DocPaths.DOC_FILES); + break; + default: + throw new AssertionError("unsupported element " + element); + } + } + + /** + * Copy doc-files directory and its contents from the source + * elements directory to the generated documentation directory. + * + * @throws DocFileIOException if there is a problem while copying + * the documentation files + */ + + public void copyDocFiles() throws DocFileIOException { + boolean first = true; + for (DocFile srcdir : DocFile.list(configuration, location, source)) { + if (!srcdir.isDirectory()) { + continue; + } + DocPath path = null; + switch (this.element.getKind()) { + case MODULE: + path = DocPath.forModule((ModuleElement)this.element); + break; + case PACKAGE: + path = DocPath.forPackage((PackageElement)this.element); + break; + default: + throw new AssertionError("unknown kind:" + this.element.getKind()); + } + copyDirectory(srcdir, path.resolve(DocPaths.DOC_FILES), first); + first = false; + } + } + + + private void copyDirectory(DocFile srcdir, final DocPath dstDocPath, + boolean first) throws DocFileIOException { + DocFile dstdir = DocFile.createFileForOutput(configuration, dstDocPath); + if (srcdir.isSameFile(dstdir)) { + return; + } + for (DocFile srcfile: srcdir.list()) { + DocFile destfile = dstdir.resolve(srcfile.getName()); + if (srcfile.isFile()) { + if (destfile.exists() && !first) { + configuration.messages.warning("doclet.Copy_Overwrite_warning", + srcfile.getPath(), dstdir.getPath()); + } else { + configuration.messages.notice("doclet.Copying_File_0_To_Dir_1",