Merge
This commit is contained in:
commit
637fc0b863
@ -375,3 +375,4 @@ f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129
|
|||||||
d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130
|
d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130
|
||||||
8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131
|
8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131
|
||||||
a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132
|
a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132
|
||||||
|
be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133
|
||||||
|
@ -535,3 +535,4 @@ e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
|
|||||||
7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130
|
7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130
|
||||||
943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131
|
943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131
|
||||||
713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132
|
713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132
|
||||||
|
a25e0fb6033245ab075136e744d362ce765464cd jdk-9+133
|
||||||
|
@ -316,12 +316,8 @@ size_t G1Analytics::predict_pending_cards() const {
|
|||||||
return get_new_size_prediction(_pending_cards_seq);
|
return get_new_size_prediction(_pending_cards_seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
double G1Analytics::oldest_known_gc_end_time_sec() const {
|
|
||||||
return _recent_prev_end_times_for_all_gcs_sec->oldest();
|
|
||||||
}
|
|
||||||
|
|
||||||
double G1Analytics::last_known_gc_end_time_sec() const {
|
double G1Analytics::last_known_gc_end_time_sec() const {
|
||||||
return _recent_prev_end_times_for_all_gcs_sec->last();
|
return _recent_prev_end_times_for_all_gcs_sec->oldest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1Analytics::update_recent_gc_times(double end_time_sec,
|
void G1Analytics::update_recent_gc_times(double end_time_sec,
|
||||||
|
@ -155,7 +155,6 @@ public:
|
|||||||
void update_recent_gc_times(double end_time_sec, double elapsed_ms);
|
void update_recent_gc_times(double end_time_sec, double elapsed_ms);
|
||||||
void compute_pause_time_ratio(double interval_ms, double pause_time_ms);
|
void compute_pause_time_ratio(double interval_ms, double pause_time_ms);
|
||||||
|
|
||||||
double oldest_known_gc_end_time_sec() const;
|
|
||||||
double last_known_gc_end_time_sec() const;
|
double last_known_gc_end_time_sec() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include "classfile/symbolTable.hpp"
|
#include "classfile/symbolTable.hpp"
|
||||||
#include "code/codeCache.hpp"
|
#include "code/codeCache.hpp"
|
||||||
#include "code/icBuffer.hpp"
|
#include "code/icBuffer.hpp"
|
||||||
#include "gc/g1/g1Analytics.hpp"
|
|
||||||
#include "gc/g1/bufferingOopClosure.hpp"
|
#include "gc/g1/bufferingOopClosure.hpp"
|
||||||
#include "gc/g1/concurrentG1Refine.hpp"
|
#include "gc/g1/concurrentG1Refine.hpp"
|
||||||
#include "gc/g1/concurrentG1RefineThread.hpp"
|
#include "gc/g1/concurrentG1RefineThread.hpp"
|
||||||
@ -2474,19 +2473,8 @@ size_t G1CollectedHeap::max_capacity() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jlong G1CollectedHeap::millis_since_last_gc() {
|
jlong G1CollectedHeap::millis_since_last_gc() {
|
||||||
jlong now = os::elapsed_counter() / NANOSECS_PER_MILLISEC;
|
// assert(false, "NYI");
|
||||||
const G1Analytics* analytics = _g1_policy->analytics();
|
return 0;
|
||||||
double last = analytics->last_known_gc_end_time_sec();
|
|
||||||
jlong ret_val = now - (last * 1000);
|
|
||||||
if (ret_val < 0) {
|
|
||||||
// See the notes in GenCollectedHeap::millis_since_last_gc()
|
|
||||||
// for more information about the implementation.
|
|
||||||
log_warning(gc)("Detected clock going backwards. "
|
|
||||||
"Milliseconds since last GC would be " JLONG_FORMAT
|
|
||||||
". returning zero instead.", ret_val);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return ret_val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1CollectedHeap::prepare_for_verify() {
|
void G1CollectedHeap::prepare_for_verify() {
|
||||||
|
@ -604,7 +604,7 @@ void G1DefaultPolicy::record_collection_pause_end(double pause_time_ms, size_t c
|
|||||||
_analytics->report_alloc_rate_ms(alloc_rate_ms);
|
_analytics->report_alloc_rate_ms(alloc_rate_ms);
|
||||||
|
|
||||||
double interval_ms =
|
double interval_ms =
|
||||||
(end_time_sec - _analytics->oldest_known_gc_end_time_sec()) * 1000.0;
|
(end_time_sec - _analytics->last_known_gc_end_time_sec()) * 1000.0;
|
||||||
_analytics->update_recent_gc_times(end_time_sec, pause_time_ms);
|
_analytics->update_recent_gc_times(end_time_sec, pause_time_ms);
|
||||||
_analytics->compute_pause_time_ratio(interval_ms, pause_time_ms);
|
_analytics->compute_pause_time_ratio(interval_ms, pause_time_ms);
|
||||||
}
|
}
|
||||||
|
@ -1256,21 +1256,21 @@ class GenTimeOfLastGCClosure: public GenCollectedHeap::GenClosure {
|
|||||||
};
|
};
|
||||||
|
|
||||||
jlong GenCollectedHeap::millis_since_last_gc() {
|
jlong GenCollectedHeap::millis_since_last_gc() {
|
||||||
// javaTimeNanos() is guaranteed to be monotonically non-decreasing
|
// We need a monotonically non-decreasing time in ms but
|
||||||
// provided the underlying platform provides such a time source
|
// os::javaTimeMillis() does not guarantee monotonicity.
|
||||||
// (and it is bug free). So we still have to guard against getting
|
|
||||||
// back a time later than 'now'.
|
|
||||||
jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
|
jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
|
||||||
GenTimeOfLastGCClosure tolgc_cl(now);
|
GenTimeOfLastGCClosure tolgc_cl(now);
|
||||||
// iterate over generations getting the oldest
|
// iterate over generations getting the oldest
|
||||||
// time that a generation was collected
|
// time that a generation was collected
|
||||||
generation_iterate(&tolgc_cl, false);
|
generation_iterate(&tolgc_cl, false);
|
||||||
|
|
||||||
|
// javaTimeNanos() is guaranteed to be monotonically non-decreasing
|
||||||
|
// provided the underlying platform provides such a time source
|
||||||
|
// (and it is bug free). So we still have to guard against getting
|
||||||
|
// back a time later than 'now'.
|
||||||
jlong retVal = now - tolgc_cl.time();
|
jlong retVal = now - tolgc_cl.time();
|
||||||
if (retVal < 0) {
|
if (retVal < 0) {
|
||||||
log_warning(gc)("Detected clock going backwards. "
|
NOT_PRODUCT(log_warning(gc)("time warp: " JLONG_FORMAT, retVal);)
|
||||||
"Milliseconds since last GC would be " JLONG_FORMAT
|
|
||||||
". returning zero instead.", retVal);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -375,3 +375,4 @@ c40c8739bcdc88892ff58ebee3fd8a3f287be94d jdk-9+123
|
|||||||
6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130
|
6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130
|
||||||
8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131
|
8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131
|
||||||
d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
|
d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
|
||||||
|
3cdae27c90b5e41afe75eab904fda19fac076330 jdk-9+133
|
||||||
|
@ -34,7 +34,7 @@ include GendataTZDB.gmk
|
|||||||
|
|
||||||
include GendataBlacklistedCerts.gmk
|
include GendataBlacklistedCerts.gmk
|
||||||
|
|
||||||
include GendataPolicyJars.gmk
|
include GendataCryptoPolicy.gmk
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
@ -64,13 +64,19 @@ TARGETS += $(GENDATA_CURDATA)
|
|||||||
GENDATA_JAVA_SECURITY_SRC := $(JDK_TOPDIR)/src/java.base/share/conf/security/java.security
|
GENDATA_JAVA_SECURITY_SRC := $(JDK_TOPDIR)/src/java.base/share/conf/security/java.security
|
||||||
GENDATA_JAVA_SECURITY := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/java.security
|
GENDATA_JAVA_SECURITY := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/java.security
|
||||||
|
|
||||||
|
ifeq ($(UNLIMITED_CRYPTO), true)
|
||||||
|
CRYPTO.POLICY := unlimited
|
||||||
|
else
|
||||||
|
CRYPTO.POLICY := limited
|
||||||
|
endif
|
||||||
|
|
||||||
# RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile
|
# RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile
|
||||||
|
|
||||||
$(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC)
|
$(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC)
|
||||||
$(call LogInfo, Generating java.security)
|
$(call LogInfo, Generating java.security)
|
||||||
$(call MakeDir, $(@D))
|
$(call MakeDir, $(@D))
|
||||||
$(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \
|
$(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \
|
||||||
$(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC)
|
$(OPENJDK_TARGET_CPU_ARCH) $(CRYPTO.POLICY) $(RESTRICTED_PKGS_SRC)
|
||||||
|
|
||||||
TARGETS += $(GENDATA_JAVA_SECURITY)
|
TARGETS += $(GENDATA_JAVA_SECURITY)
|
||||||
|
|
||||||
|
72
jdk/make/gendata/GendataCryptoPolicy.gmk
Normal file
72
jdk/make/gendata/GendataCryptoPolicy.gmk
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
#
|
||||||
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License version 2 only, as
|
||||||
|
# published by the Free Software Foundation. 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# In pre-JDK9 releases, Oracle JDK has had a separately downloadable set
|
||||||
|
# of policy files which has been a nightmare for deployment.
|
||||||
|
#
|
||||||
|
# We now create 2 complete initial sets of policy files and package into
|
||||||
|
# 2 different directories. The crypto.policy Security property will select
|
||||||
|
# the active policy.
|
||||||
|
#
|
||||||
|
# It will be up to the user/deployer to make an informed choice
|
||||||
|
# as to whether they are legally entitled to use the unlimited policy
|
||||||
|
# file in their environment. The $(UNLIMITED_CRYPTO) make variable
|
||||||
|
# determines the default directory/policy.
|
||||||
|
#
|
||||||
|
|
||||||
|
default: all
|
||||||
|
|
||||||
|
include $(SPEC)
|
||||||
|
include MakeBase.gmk
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
POLICY_DIR := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/policy
|
||||||
|
LIMITED_POLICY_DIR := $(POLICY_DIR)/limited
|
||||||
|
UNLIMITED_POLICY_DIR := $(POLICY_DIR)/unlimited
|
||||||
|
|
||||||
|
POLICY_SRC_DIR := $(JDK_TOPDIR)/src/java.base/share/conf/security/policy
|
||||||
|
LIMITED_POLICY_SRC_DIR := $(POLICY_SRC_DIR)/limited
|
||||||
|
UNLIMITED_POLICY_SRC_DIR := $(POLICY_SRC_DIR)/unlimited
|
||||||
|
|
||||||
|
$(POLICY_DIR)/README.txt: $(POLICY_SRC_DIR)/README.txt
|
||||||
|
$(install-file)
|
||||||
|
|
||||||
|
$(LIMITED_POLICY_DIR)/%: $(LIMITED_POLICY_SRC_DIR)/%
|
||||||
|
$(install-file)
|
||||||
|
|
||||||
|
$(UNLIMITED_POLICY_DIR)/%: $(UNLIMITED_POLICY_SRC_DIR)/%
|
||||||
|
$(install-file)
|
||||||
|
|
||||||
|
TARGETS += \
|
||||||
|
$(POLICY_DIR)/README.txt \
|
||||||
|
$(LIMITED_POLICY_DIR)/default_US_export.policy \
|
||||||
|
$(LIMITED_POLICY_DIR)/default_local.policy \
|
||||||
|
$(LIMITED_POLICY_DIR)/exempt_local.policy \
|
||||||
|
$(UNLIMITED_POLICY_DIR)/default_US_export.policy \
|
||||||
|
$(UNLIMITED_POLICY_DIR)/default_local.policy \
|
||||||
|
|
||||||
|
################################################################################
|
@ -1,150 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
#
|
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU General Public License version 2 only, as
|
|
||||||
# published by the Free Software Foundation. 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
|
|
||||||
include JarArchive.gmk
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
US_EXPORT_POLICY_JAR_DST := \
|
|
||||||
$(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/US_export_policy.jar
|
|
||||||
|
|
||||||
US_EXPORT_POLICY_JAR_LIMITED := \
|
|
||||||
$(SUPPORT_OUTPUTDIR)/jce/policy/limited/US_export_policy.jar
|
|
||||||
US_EXPORT_POLICY_JAR_UNLIMITED := \
|
|
||||||
$(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy.jar
|
|
||||||
|
|
||||||
#
|
|
||||||
# TODO fix so that SetupJarArchive does not write files into SRCS
|
|
||||||
# then we don't need this extra copying
|
|
||||||
#
|
|
||||||
# NOTE: We currently do not place restrictions on our limited export
|
|
||||||
# policy. This was not a typo. This means we are shipping the same file
|
|
||||||
# for both limited and unlimited US_export_policy.jar. Only the local
|
|
||||||
# policy file currently has restrictions.
|
|
||||||
#
|
|
||||||
US_EXPORT_POLICY_JAR_SRC_DIR := \
|
|
||||||
$(JDK_TOPDIR)/make/data/cryptopolicy/unlimited
|
|
||||||
US_EXPORT_POLICY_JAR_TMP := \
|
|
||||||
$(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy_jar.tmp
|
|
||||||
|
|
||||||
$(US_EXPORT_POLICY_JAR_TMP)/%: $(US_EXPORT_POLICY_JAR_SRC_DIR)/%
|
|
||||||
$(install-file)
|
|
||||||
|
|
||||||
US_EXPORT_POLICY_JAR_DEPS := \
|
|
||||||
$(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy
|
|
||||||
|
|
||||||
$(eval $(call SetupJarArchive, BUILD_US_EXPORT_POLICY_JAR, \
|
|
||||||
DEPENDENCIES := $(US_EXPORT_POLICY_JAR_DEPS), \
|
|
||||||
SRCS := $(US_EXPORT_POLICY_JAR_TMP), \
|
|
||||||
SUFFIXES := .policy, \
|
|
||||||
JAR := $(US_EXPORT_POLICY_JAR_UNLIMITED), \
|
|
||||||
EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
|
|
||||||
SKIP_METAINF := true, \
|
|
||||||
))
|
|
||||||
|
|
||||||
$(US_EXPORT_POLICY_JAR_LIMITED): \
|
|
||||||
$(US_EXPORT_POLICY_JAR_UNLIMITED)
|
|
||||||
$(call LogInfo, Copying unlimited $(patsubst $(OUTPUT_ROOT)/%,%,$@))
|
|
||||||
$(install-file)
|
|
||||||
|
|
||||||
TARGETS += $(US_EXPORT_POLICY_JAR_LIMITED) $(US_EXPORT_POLICY_JAR_UNLIMITED)
|
|
||||||
|
|
||||||
ifeq ($(UNLIMITED_CRYPTO), true)
|
|
||||||
$(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_UNLIMITED)
|
|
||||||
$(install-file)
|
|
||||||
else
|
|
||||||
$(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_LIMITED)
|
|
||||||
$(install-file)
|
|
||||||
endif
|
|
||||||
|
|
||||||
POLICY_JARS += $(US_EXPORT_POLICY_JAR_DST)
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
LOCAL_POLICY_JAR_DST := \
|
|
||||||
$(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/local_policy.jar
|
|
||||||
|
|
||||||
LOCAL_POLICY_JAR_LIMITED := \
|
|
||||||
$(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy.jar
|
|
||||||
LOCAL_POLICY_JAR_UNLIMITED := \
|
|
||||||
$(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy.jar
|
|
||||||
|
|
||||||
#
|
|
||||||
# TODO fix so that SetupJarArchive does not write files into SRCS
|
|
||||||
# then we don't need this extra copying
|
|
||||||
#
|
|
||||||
LOCAL_POLICY_JAR_LIMITED_TMP := \
|
|
||||||
$(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy_jar.tmp
|
|
||||||
LOCAL_POLICY_JAR_UNLIMITED_TMP := \
|
|
||||||
$(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy_jar.tmp
|
|
||||||
|
|
||||||
$(LOCAL_POLICY_JAR_LIMITED_TMP)/%: \
|
|
||||||
$(JDK_TOPDIR)/make/data/cryptopolicy/limited/%
|
|
||||||
$(install-file)
|
|
||||||
|
|
||||||
$(LOCAL_POLICY_JAR_UNLIMITED_TMP)/%: \
|
|
||||||
$(JDK_TOPDIR)/make/data/cryptopolicy/unlimited/%
|
|
||||||
$(install-file)
|
|
||||||
|
|
||||||
$(eval $(call SetupJarArchive, BUILD_LOCAL_POLICY_JAR_LIMITED, \
|
|
||||||
DEPENDENCIES := $(LOCAL_POLICY_JAR_LIMITED_TMP)/exempt_local.policy \
|
|
||||||
$(LOCAL_POLICY_JAR_LIMITED_TMP)/default_local.policy, \
|
|
||||||
SRCS := $(LOCAL_POLICY_JAR_LIMITED_TMP), \
|
|
||||||
SUFFIXES := .policy, \
|
|
||||||
JAR := $(LOCAL_POLICY_JAR_LIMITED), \
|
|
||||||
EXTRA_MANIFEST_ATTR := Crypto-Strength: limited, \
|
|
||||||
SKIP_METAINF := true, \
|
|
||||||
))
|
|
||||||
|
|
||||||
$(eval $(call SetupJarArchive, BUILD_LOCAL_POLICY_JAR_UNLIMITED, \
|
|
||||||
DEPENDENCIES := $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/default_local.policy, \
|
|
||||||
SRCS := $(LOCAL_POLICY_JAR_UNLIMITED_TMP), \
|
|
||||||
SUFFIXES := .policy, \
|
|
||||||
JAR := $(LOCAL_POLICY_JAR_UNLIMITED), \
|
|
||||||
EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
|
|
||||||
SKIP_METAINF := true, \
|
|
||||||
))
|
|
||||||
|
|
||||||
TARGETS += $(LOCAL_POLICY_JAR_LIMITED) $(LOCAL_POLICY_JAR_UNLIMITED)
|
|
||||||
|
|
||||||
ifeq ($(UNLIMITED_CRYPTO), true)
|
|
||||||
$(LOCAL_POLICY_JAR_DST): $(LOCAL_POLICY_JAR_UNLIMITED)
|
|
||||||
$(install-file)
|
|
||||||
else
|
|
||||||
$(LOCAL_POLICY_JAR_DST): $(LOCAL_POLICY_JAR_LIMITED)
|
|
||||||
$(install-file)
|
|
||||||
endif
|
|
||||||
|
|
||||||
POLICY_JARS += $(LOCAL_POLICY_JAR_DST)
|
|
||||||
TARGETS += $(POLICY_JARS)
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
$(eval $(call IncludeCustomExtension, jdk, gendata/GendataPolicyJars.gmk))
|
|
@ -36,3 +36,9 @@ $(eval $(call SetupBuildLauncher, jdeps, \
|
|||||||
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
|
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
|
||||||
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
|
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
|
||||||
))
|
))
|
||||||
|
|
||||||
|
$(eval $(call SetupBuildLauncher, jdeprscan, \
|
||||||
|
MAIN_CLASS := com.sun.tools.jdeprscan.Main, \
|
||||||
|
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
|
||||||
|
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
|
||||||
|
))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -38,8 +38,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
|
|||||||
CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \
|
CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \
|
||||||
$(LIBJAVA_HEADER_FLAGS) \
|
$(LIBJAVA_HEADER_FLAGS) \
|
||||||
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.pkcs11, \
|
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.pkcs11, \
|
||||||
DISABLED_WARNINGS_solstudio := E_DECLARATION_IN_CODE, \
|
|
||||||
DISABLED_WARNINGS_microsoft := 4013 4267, \
|
|
||||||
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2pkcs11/mapfile-vers, \
|
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2pkcs11/mapfile-vers, \
|
||||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -35,7 +35,8 @@ import java.util.*;
|
|||||||
*
|
*
|
||||||
* 1. Adds additional packages to the package.access and
|
* 1. Adds additional packages to the package.access and
|
||||||
* package.definition security properties.
|
* package.definition security properties.
|
||||||
* 2. Filter out platform-unrelated parts
|
* 2. Filter out platform-unrelated parts.
|
||||||
|
* 3. Set the JCE jurisdiction policy directory.
|
||||||
*
|
*
|
||||||
* In order to easily maintain platform-related entries, every item
|
* In order to easily maintain platform-related entries, every item
|
||||||
* (including the last line) in package.access and package.definition
|
* (including the last line) in package.access and package.definition
|
||||||
@ -50,12 +51,13 @@ public class MakeJavaSecurity {
|
|||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
if (args.length < 4) {
|
if (args.length < 5) {
|
||||||
System.err.println("Usage: java MakeJavaSecurity " +
|
System.err.println("Usage: java MakeJavaSecurity " +
|
||||||
"[input java.security file name] " +
|
"[input java.security file name] " +
|
||||||
"[output java.security file name] " +
|
"[output java.security file name] " +
|
||||||
"[openjdk target os] " +
|
"[openjdk target os] " +
|
||||||
"[openjdk target cpu architecture]" +
|
"[openjdk target cpu architecture]" +
|
||||||
|
"[JCE jurisdiction policy directory]" +
|
||||||
"[more restricted packages file name?]");
|
"[more restricted packages file name?]");
|
||||||
|
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
@ -63,8 +65,8 @@ public class MakeJavaSecurity {
|
|||||||
|
|
||||||
// more restricted packages
|
// more restricted packages
|
||||||
List<String> extraLines;
|
List<String> extraLines;
|
||||||
if (args.length == 5) {
|
if (args.length == 6) {
|
||||||
extraLines = Files.readAllLines(Paths.get(args[4]));
|
extraLines = Files.readAllLines(Paths.get(args[5]));
|
||||||
} else {
|
} else {
|
||||||
extraLines = Collections.emptyList();
|
extraLines = Collections.emptyList();
|
||||||
}
|
}
|
||||||
@ -135,6 +137,16 @@ public class MakeJavaSecurity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the JCE policy value
|
||||||
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
|
String line = lines.get(i);
|
||||||
|
int index = line.indexOf("crypto.policydir-tbd");
|
||||||
|
if (index >= 0) {
|
||||||
|
String prefix = line.substring(0, index);
|
||||||
|
lines.set(i, prefix + args[4]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up the last line of PKG_ACC and PKG_DEF blocks.
|
// Clean up the last line of PKG_ACC and PKG_DEF blocks.
|
||||||
// Not really necessary since a blank line follows.
|
// Not really necessary since a blank line follows.
|
||||||
boolean inBlock = false;
|
boolean inBlock = false;
|
||||||
|
@ -986,8 +986,9 @@ final class CipherCore {
|
|||||||
if (padding != null) {
|
if (padding != null) {
|
||||||
int padStart = padding.unpad(outWithPadding, 0, outLen);
|
int padStart = padding.unpad(outWithPadding, 0, outLen);
|
||||||
if (padStart < 0) {
|
if (padStart < 0) {
|
||||||
throw new BadPaddingException("Given final block not "
|
throw new BadPaddingException("Given final block not " +
|
||||||
+ "properly padded");
|
"properly padded. Such issues can arise if a bad key " +
|
||||||
|
"is used during decryption.");
|
||||||
}
|
}
|
||||||
outLen = padStart;
|
outLen = padStart;
|
||||||
}
|
}
|
||||||
|
@ -331,12 +331,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* Note that this method does not check whether the requested class
|
* Note that this method does not check whether the requested class
|
||||||
* is accessible to its caller.
|
* is accessible to its caller.
|
||||||
*
|
*
|
||||||
* <p> If the {@code loader} is {@code null}, and a security
|
|
||||||
* manager is present, and the caller's class loader is not null, then this
|
|
||||||
* method calls the security manager's {@code checkPermission} method
|
|
||||||
* with a {@code RuntimePermission("getClassLoader")} permission to
|
|
||||||
* ensure it's ok to access the bootstrap class loader.
|
|
||||||
*
|
|
||||||
* @param name fully qualified name of the desired class
|
* @param name fully qualified name of the desired class
|
||||||
* @param initialize if {@code true} the class will be initialized.
|
* @param initialize if {@code true} the class will be initialized.
|
||||||
* See Section 12.4 of <em>The Java Language Specification</em>.
|
* See Section 12.4 of <em>The Java Language Specification</em>.
|
||||||
@ -348,6 +342,11 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* by this method fails
|
* by this method fails
|
||||||
* @exception ClassNotFoundException if the class cannot be located by
|
* @exception ClassNotFoundException if the class cannot be located by
|
||||||
* the specified class loader
|
* the specified class loader
|
||||||
|
* @exception SecurityException
|
||||||
|
* if a security manager is present, and the {@code loader} is
|
||||||
|
* {@code null}, and the caller's class loader is not
|
||||||
|
* {@code null}, and the caller does not have the
|
||||||
|
* {@link RuntimePermission}{@code ("getClassLoader")}
|
||||||
*
|
*
|
||||||
* @see java.lang.Class#forName(String)
|
* @see java.lang.Class#forName(String)
|
||||||
* @see java.lang.ClassLoader
|
* @see java.lang.ClassLoader
|
||||||
@ -782,22 +781,17 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* null in such implementations if this class was loaded by the bootstrap
|
* null in such implementations if this class was loaded by the bootstrap
|
||||||
* class loader.
|
* class loader.
|
||||||
*
|
*
|
||||||
* <p> If a security manager is present, and the caller's class loader is
|
|
||||||
* not null and the caller's class loader is not the same as or an ancestor of
|
|
||||||
* the class loader for the class whose class loader is requested, then
|
|
||||||
* this method calls the security manager's {@code checkPermission}
|
|
||||||
* method with a {@code RuntimePermission("getClassLoader")}
|
|
||||||
* permission to ensure it's ok to access the class loader for the class.
|
|
||||||
*
|
|
||||||
* <p>If this object
|
* <p>If this object
|
||||||
* represents a primitive type or void, null is returned.
|
* represents a primitive type or void, null is returned.
|
||||||
*
|
*
|
||||||
* @return the class loader that loaded the class or interface
|
* @return the class loader that loaded the class or interface
|
||||||
* represented by this object.
|
* represented by this object.
|
||||||
* @throws SecurityException
|
* @throws SecurityException
|
||||||
* if a security manager exists and its
|
* if a security manager is present, and the caller's class loader
|
||||||
* {@code checkPermission} method denies
|
* is not {@code null} and is not the same as or an ancestor of the
|
||||||
* access to the class loader for the class.
|
* class loader for the class whose class loader is requested,
|
||||||
|
* and the caller does not have the
|
||||||
|
* {@link RuntimePermission}{@code ("getClassLoader")}
|
||||||
* @see java.lang.ClassLoader
|
* @see java.lang.ClassLoader
|
||||||
* @see SecurityManager#checkPermission
|
* @see SecurityManager#checkPermission
|
||||||
* @see java.lang.RuntimePermission
|
* @see java.lang.RuntimePermission
|
||||||
|
@ -1537,22 +1537,13 @@ public abstract class ClassLoader {
|
|||||||
* will return <tt>null</tt> in such implementations if this class loader's
|
* will return <tt>null</tt> in such implementations if this class loader's
|
||||||
* parent is the bootstrap class loader.
|
* parent is the bootstrap class loader.
|
||||||
*
|
*
|
||||||
* <p> If a security manager is present, and the invoker's class loader is
|
|
||||||
* not <tt>null</tt> and is not an ancestor of this class loader, then this
|
|
||||||
* method invokes the security manager's {@link
|
|
||||||
* SecurityManager#checkPermission(java.security.Permission)
|
|
||||||
* <tt>checkPermission</tt>} method with a {@link
|
|
||||||
* RuntimePermission#RuntimePermission(String)
|
|
||||||
* <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
|
|
||||||
* access to the parent class loader is permitted. If not, a
|
|
||||||
* <tt>SecurityException</tt> will be thrown. </p>
|
|
||||||
*
|
|
||||||
* @return The parent <tt>ClassLoader</tt>
|
* @return The parent <tt>ClassLoader</tt>
|
||||||
*
|
*
|
||||||
* @throws SecurityException
|
* @throws SecurityException
|
||||||
* If a security manager exists and its <tt>checkPermission</tt>
|
* If a security manager is present, and the caller's class loader
|
||||||
* method doesn't allow access to this class loader's parent class
|
* is not {@code null} and is not an ancestor of this class loader,
|
||||||
* loader.
|
* and the caller does not have the
|
||||||
|
* {@link RuntimePermission}{@code ("getClassLoader")}
|
||||||
*
|
*
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
@ -1590,12 +1581,11 @@ public abstract class ClassLoader {
|
|||||||
* @return The platform {@code ClassLoader}.
|
* @return The platform {@code ClassLoader}.
|
||||||
*
|
*
|
||||||
* @throws SecurityException
|
* @throws SecurityException
|
||||||
* If a security manager exists and the caller's class loader is
|
* If a security manager is present, and the caller's class loader is
|
||||||
* not {@code null} and the caller's class loader is not the same
|
* not {@code null}, and the caller's class loader is not the same
|
||||||
* as or an ancestor of the platform class loader,
|
* as or an ancestor of the platform class loader,
|
||||||
* and the {@link SecurityManager#checkPermission(java.security.Permission)
|
* and the caller does not have the
|
||||||
* checkPermission} method denies {@code RuntimePermission("getClassLoader")}
|
* {@link RuntimePermission}{@code ("getClassLoader")}
|
||||||
* to access the platform class loader.
|
|
||||||
*
|
*
|
||||||
* @since 9
|
* @since 9
|
||||||
*/
|
*/
|
||||||
@ -1636,17 +1626,6 @@ public abstract class ClassLoader {
|
|||||||
* If circular initialization of the system class loader is detected then
|
* If circular initialization of the system class loader is detected then
|
||||||
* an unspecified error or exception is thrown.
|
* an unspecified error or exception is thrown.
|
||||||
*
|
*
|
||||||
* <p> If a security manager is present, and the invoker's class loader is
|
|
||||||
* not <tt>null</tt> and the invoker's class loader is not the same as or
|
|
||||||
* an ancestor of the system class loader, then this method invokes the
|
|
||||||
* security manager's {@link
|
|
||||||
* SecurityManager#checkPermission(java.security.Permission)
|
|
||||||
* <tt>checkPermission</tt>} method with a {@link
|
|
||||||
* RuntimePermission#RuntimePermission(String)
|
|
||||||
* <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
|
|
||||||
* access to the system class loader. If not, a
|
|
||||||
* <tt>SecurityException</tt> will be thrown. </p>
|
|
||||||
*
|
|
||||||
* @implNote The system property to override the system class loader is not
|
* @implNote The system property to override the system class loader is not
|
||||||
* examined until the VM is almost fully initialized. Code that executes
|
* examined until the VM is almost fully initialized. Code that executes
|
||||||
* this method during startup should take care not to cache the return
|
* this method during startup should take care not to cache the return
|
||||||
@ -1656,8 +1635,10 @@ public abstract class ClassLoader {
|
|||||||
* <tt>null</tt> if none
|
* <tt>null</tt> if none
|
||||||
*
|
*
|
||||||
* @throws SecurityException
|
* @throws SecurityException
|
||||||
* If a security manager exists and its <tt>checkPermission</tt>
|
* If a security manager is present, and the caller's class loader
|
||||||
* method doesn't allow access to the system class loader.
|
* is not {@code null} and is not the same as or an ancestor of the
|
||||||
|
* system class loader, and the caller does not have the
|
||||||
|
* {@link RuntimePermission}{@code ("getClassLoader")}
|
||||||
*
|
*
|
||||||
* @throws IllegalStateException
|
* @throws IllegalStateException
|
||||||
* If invoked recursively during the construction of the class
|
* If invoked recursively during the construction of the class
|
||||||
|
@ -1370,8 +1370,13 @@ public final class Math {
|
|||||||
* result is positive zero.
|
* result is positive zero.
|
||||||
* <li>If the argument is infinite, the result is positive infinity.
|
* <li>If the argument is infinite, the result is positive infinity.
|
||||||
* <li>If the argument is NaN, the result is NaN.</ul>
|
* <li>If the argument is NaN, the result is NaN.</ul>
|
||||||
* In other words, the result is the same as the value of the expression:
|
*
|
||||||
* <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
|
* @apiNote As implied by the above, one valid implementation of
|
||||||
|
* this method is given by the expression below which computes a
|
||||||
|
* {@code float} with the same exponent and significand as the
|
||||||
|
* argument but with a guaranteed zero sign bit indicating a
|
||||||
|
* positive value:<br>
|
||||||
|
* {@code Float.intBitsToFloat(0x7fffffff & Float.floatToRawIntBits(a))}
|
||||||
*
|
*
|
||||||
* @param a the argument whose absolute value is to be determined
|
* @param a the argument whose absolute value is to be determined
|
||||||
* @return the absolute value of the argument.
|
* @return the absolute value of the argument.
|
||||||
@ -1389,8 +1394,13 @@ public final class Math {
|
|||||||
* is positive zero.
|
* is positive zero.
|
||||||
* <li>If the argument is infinite, the result is positive infinity.
|
* <li>If the argument is infinite, the result is positive infinity.
|
||||||
* <li>If the argument is NaN, the result is NaN.</ul>
|
* <li>If the argument is NaN, the result is NaN.</ul>
|
||||||
* In other words, the result is the same as the value of the expression:
|
*
|
||||||
* <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
|
* @apiNote As implied by the above, one valid implementation of
|
||||||
|
* this method is given by the expression below which computes a
|
||||||
|
* {@code double} with the same exponent and significand as the
|
||||||
|
* argument but with a guaranteed zero sign bit indicating a
|
||||||
|
* positive value:<br>
|
||||||
|
* {@code Double.longBitsToDouble((Double.doubleToRawLongBits(a)<<1)>>>1)}
|
||||||
*
|
*
|
||||||
* @param a the argument whose absolute value is to be determined
|
* @param a the argument whose absolute value is to be determined
|
||||||
* @return the absolute value of the argument.
|
* @return the absolute value of the argument.
|
||||||
|
@ -1070,8 +1070,13 @@ public final class StrictMath {
|
|||||||
* result is positive zero.
|
* result is positive zero.
|
||||||
* <li>If the argument is infinite, the result is positive infinity.
|
* <li>If the argument is infinite, the result is positive infinity.
|
||||||
* <li>If the argument is NaN, the result is NaN.</ul>
|
* <li>If the argument is NaN, the result is NaN.</ul>
|
||||||
* In other words, the result is the same as the value of the expression:
|
*
|
||||||
* <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
|
* @apiNote As implied by the above, one valid implementation of
|
||||||
|
* this method is given by the expression below which computes a
|
||||||
|
* {@code float} with the same exponent and significand as the
|
||||||
|
* argument but with a guaranteed zero sign bit indicating a
|
||||||
|
* positive value: <br>
|
||||||
|
* {@code Float.intBitsToFloat(0x7fffffff & Float.floatToRawIntBits(a))}
|
||||||
*
|
*
|
||||||
* @param a the argument whose absolute value is to be determined
|
* @param a the argument whose absolute value is to be determined
|
||||||
* @return the absolute value of the argument.
|
* @return the absolute value of the argument.
|
||||||
@ -1089,8 +1094,13 @@ public final class StrictMath {
|
|||||||
* is positive zero.
|
* is positive zero.
|
||||||
* <li>If the argument is infinite, the result is positive infinity.
|
* <li>If the argument is infinite, the result is positive infinity.
|
||||||
* <li>If the argument is NaN, the result is NaN.</ul>
|
* <li>If the argument is NaN, the result is NaN.</ul>
|
||||||
* In other words, the result is the same as the value of the expression:
|
*
|
||||||
* <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
|
* @apiNote As implied by the above, one valid implementation of
|
||||||
|
* this method is given by the expression below which computes a
|
||||||
|
* {@code double} with the same exponent and significand as the
|
||||||
|
* argument but with a guaranteed zero sign bit indicating a
|
||||||
|
* positive value: <br>
|
||||||
|
* {@code Double.longBitsToDouble((Double.doubleToRawLongBits(a)<<1)>>>1)}
|
||||||
*
|
*
|
||||||
* @param a the argument whose absolute value is to be determined
|
* @param a the argument whose absolute value is to be determined
|
||||||
* @return the absolute value of the argument.
|
* @return the absolute value of the argument.
|
||||||
|
@ -1507,28 +1507,25 @@ class Thread implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the context ClassLoader for this Thread. The context
|
* Returns the context {@code ClassLoader} for this thread. The context
|
||||||
* ClassLoader is provided by the creator of the thread for use
|
* {@code ClassLoader} is provided by the creator of the thread for use
|
||||||
* by code running in this thread when loading classes and resources.
|
* by code running in this thread when loading classes and resources.
|
||||||
* If not {@linkplain #setContextClassLoader set}, the default is the
|
* If not {@linkplain #setContextClassLoader set}, the default is the
|
||||||
* ClassLoader context of the parent Thread. The context ClassLoader of the
|
* {@code ClassLoader} context of the parent thread. The context
|
||||||
|
* {@code ClassLoader} of the
|
||||||
* primordial thread is typically set to the class loader used to load the
|
* primordial thread is typically set to the class loader used to load the
|
||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
* <p>If a security manager is present, and the invoker's class loader is not
|
|
||||||
* {@code null} and is not the same as or an ancestor of the context class
|
|
||||||
* loader, then this method invokes the security manager's {@link
|
|
||||||
* SecurityManager#checkPermission(java.security.Permission) checkPermission}
|
|
||||||
* method with a {@link RuntimePermission RuntimePermission}{@code
|
|
||||||
* ("getClassLoader")} permission to verify that retrieval of the context
|
|
||||||
* class loader is permitted.
|
|
||||||
*
|
*
|
||||||
* @return the context ClassLoader for this Thread, or {@code null}
|
* @return the context {@code ClassLoader} for this thread, or {@code null}
|
||||||
* indicating the system class loader (or, failing that, the
|
* indicating the system class loader (or, failing that, the
|
||||||
* bootstrap class loader)
|
* bootstrap class loader)
|
||||||
*
|
*
|
||||||
* @throws SecurityException
|
* @throws SecurityException
|
||||||
* if the current thread cannot get the context ClassLoader
|
* if a security manager is present, and the caller's class loader
|
||||||
|
* is not {@code null} and is not the same as or an ancestor of the
|
||||||
|
* context class loader, and the caller does not have the
|
||||||
|
* {@link RuntimePermission}{@code ("getClassLoader")}
|
||||||
*
|
*
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
|
@ -497,6 +497,10 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||||||
String shortTypes = LambdaForm.shortenSignature(types);
|
String shortTypes = LambdaForm.shortenSignature(types);
|
||||||
String className = SPECIES_CLASS_PREFIX + shortTypes;
|
String className = SPECIES_CLASS_PREFIX + shortTypes;
|
||||||
Class<?> c = BootLoader.loadClassOrNull(className);
|
Class<?> c = BootLoader.loadClassOrNull(className);
|
||||||
|
if (TRACE_RESOLVE) {
|
||||||
|
System.out.println("[BMH_RESOLVE] " + shortTypes +
|
||||||
|
(c != null ? " (success)" : " (fail)") );
|
||||||
|
}
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
return c.asSubclass(BoundMethodHandle.class);
|
return c.asSubclass(BoundMethodHandle.class);
|
||||||
} else {
|
} else {
|
||||||
|
@ -492,7 +492,7 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Caching machinery for field accessors:
|
// Caching machinery for field accessors:
|
||||||
private static final byte
|
static final byte
|
||||||
AF_GETFIELD = 0,
|
AF_GETFIELD = 0,
|
||||||
AF_PUTFIELD = 1,
|
AF_PUTFIELD = 1,
|
||||||
AF_GETSTATIC = 2,
|
AF_GETSTATIC = 2,
|
||||||
@ -502,7 +502,7 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
AF_LIMIT = 6;
|
AF_LIMIT = 6;
|
||||||
// Enumerate the different field kinds using Wrapper,
|
// Enumerate the different field kinds using Wrapper,
|
||||||
// with an extra case added for checked references.
|
// with an extra case added for checked references.
|
||||||
private static final int
|
static final int
|
||||||
FT_LAST_WRAPPER = Wrapper.COUNT-1,
|
FT_LAST_WRAPPER = Wrapper.COUNT-1,
|
||||||
FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
|
FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
|
||||||
FT_CHECKED_REF = FT_LAST_WRAPPER+1,
|
FT_CHECKED_REF = FT_LAST_WRAPPER+1,
|
||||||
@ -515,7 +515,7 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
@Stable
|
@Stable
|
||||||
private static final LambdaForm[] ACCESSOR_FORMS
|
private static final LambdaForm[] ACCESSOR_FORMS
|
||||||
= new LambdaForm[afIndex(AF_LIMIT, false, 0)];
|
= new LambdaForm[afIndex(AF_LIMIT, false, 0)];
|
||||||
private static int ftypeKind(Class<?> ftype) {
|
static int ftypeKind(Class<?> ftype) {
|
||||||
if (ftype.isPrimitive())
|
if (ftype.isPrimitive())
|
||||||
return Wrapper.forPrimitiveType(ftype).ordinal();
|
return Wrapper.forPrimitiveType(ftype).ordinal();
|
||||||
else if (VerifyType.isNullReferenceConversion(Object.class, ftype))
|
else if (VerifyType.isNullReferenceConversion(Object.class, ftype))
|
||||||
@ -566,7 +566,64 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
|
|
||||||
private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
|
private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
|
||||||
|
|
||||||
private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
|
private static Kind getFieldKind(boolean isGetter, boolean isVolatile, Wrapper wrapper) {
|
||||||
|
if (isGetter) {
|
||||||
|
if (isVolatile) {
|
||||||
|
switch (wrapper) {
|
||||||
|
case BOOLEAN: return GET_BOOLEAN_VOLATILE;
|
||||||
|
case BYTE: return GET_BYTE_VOLATILE;
|
||||||
|
case SHORT: return GET_SHORT_VOLATILE;
|
||||||
|
case CHAR: return GET_CHAR_VOLATILE;
|
||||||
|
case INT: return GET_INT_VOLATILE;
|
||||||
|
case LONG: return GET_LONG_VOLATILE;
|
||||||
|
case FLOAT: return GET_FLOAT_VOLATILE;
|
||||||
|
case DOUBLE: return GET_DOUBLE_VOLATILE;
|
||||||
|
case OBJECT: return GET_OBJECT_VOLATILE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (wrapper) {
|
||||||
|
case BOOLEAN: return GET_BOOLEAN;
|
||||||
|
case BYTE: return GET_BYTE;
|
||||||
|
case SHORT: return GET_SHORT;
|
||||||
|
case CHAR: return GET_CHAR;
|
||||||
|
case INT: return GET_INT;
|
||||||
|
case LONG: return GET_LONG;
|
||||||
|
case FLOAT: return GET_FLOAT;
|
||||||
|
case DOUBLE: return GET_DOUBLE;
|
||||||
|
case OBJECT: return GET_OBJECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isVolatile) {
|
||||||
|
switch (wrapper) {
|
||||||
|
case BOOLEAN: return PUT_BOOLEAN_VOLATILE;
|
||||||
|
case BYTE: return PUT_BYTE_VOLATILE;
|
||||||
|
case SHORT: return PUT_SHORT_VOLATILE;
|
||||||
|
case CHAR: return PUT_CHAR_VOLATILE;
|
||||||
|
case INT: return PUT_INT_VOLATILE;
|
||||||
|
case LONG: return PUT_LONG_VOLATILE;
|
||||||
|
case FLOAT: return PUT_FLOAT_VOLATILE;
|
||||||
|
case DOUBLE: return PUT_DOUBLE_VOLATILE;
|
||||||
|
case OBJECT: return PUT_OBJECT_VOLATILE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (wrapper) {
|
||||||
|
case BOOLEAN: return PUT_BOOLEAN;
|
||||||
|
case BYTE: return PUT_BYTE;
|
||||||
|
case SHORT: return PUT_SHORT;
|
||||||
|
case CHAR: return PUT_CHAR;
|
||||||
|
case INT: return PUT_INT;
|
||||||
|
case LONG: return PUT_LONG;
|
||||||
|
case FLOAT: return PUT_FLOAT;
|
||||||
|
case DOUBLE: return PUT_DOUBLE;
|
||||||
|
case OBJECT: return PUT_OBJECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AssertionError("Invalid arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
|
||||||
boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
|
boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
|
||||||
boolean isStatic = (formOp >= AF_GETSTATIC);
|
boolean isStatic = (formOp >= AF_GETSTATIC);
|
||||||
boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
|
boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
|
||||||
@ -576,24 +633,14 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
|
assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
|
||||||
|
|
||||||
// getObject, putIntVolatile, etc.
|
// getObject, putIntVolatile, etc.
|
||||||
StringBuilder nameBuilder = new StringBuilder();
|
Kind kind = getFieldKind(isGetter, isVolatile, fw);
|
||||||
if (isGetter) {
|
|
||||||
nameBuilder.append("get");
|
|
||||||
} else {
|
|
||||||
nameBuilder.append("put");
|
|
||||||
}
|
|
||||||
nameBuilder.append(fw.primitiveSimpleName());
|
|
||||||
nameBuilder.setCharAt(3, Character.toUpperCase(nameBuilder.charAt(3)));
|
|
||||||
if (isVolatile) {
|
|
||||||
nameBuilder.append("Volatile");
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodType linkerType;
|
MethodType linkerType;
|
||||||
if (isGetter)
|
if (isGetter)
|
||||||
linkerType = MethodType.methodType(ft, Object.class, long.class);
|
linkerType = MethodType.methodType(ft, Object.class, long.class);
|
||||||
else
|
else
|
||||||
linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
|
linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
|
||||||
MemberName linker = new MemberName(Unsafe.class, nameBuilder.toString(), linkerType, REF_invokeVirtual);
|
MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
|
||||||
try {
|
try {
|
||||||
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
|
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
|
||||||
} catch (ReflectiveOperationException ex) {
|
} catch (ReflectiveOperationException ex) {
|
||||||
@ -620,6 +667,7 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
|
final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
|
||||||
final int F_OFFSET = nameCursor++; // Either static offset or field offset.
|
final int F_OFFSET = nameCursor++; // Either static offset or field offset.
|
||||||
final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
|
final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
|
||||||
|
final int U_HOLDER = nameCursor++; // UNSAFE holder
|
||||||
final int INIT_BAR = (needsInit ? nameCursor++ : -1);
|
final int INIT_BAR = (needsInit ? nameCursor++ : -1);
|
||||||
final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
|
final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
|
||||||
final int LINKER_CALL = nameCursor++;
|
final int LINKER_CALL = nameCursor++;
|
||||||
@ -632,7 +680,7 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
|
names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
|
||||||
Object[] outArgs = new Object[1 + linkerType.parameterCount()];
|
Object[] outArgs = new Object[1 + linkerType.parameterCount()];
|
||||||
assert(outArgs.length == (isGetter ? 3 : 4));
|
assert(outArgs.length == (isGetter ? 3 : 4));
|
||||||
outArgs[0] = UNSAFE;
|
outArgs[0] = names[U_HOLDER] = new Name(NF_UNSAFE);
|
||||||
if (isStatic) {
|
if (isStatic) {
|
||||||
outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]);
|
outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]);
|
||||||
outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]);
|
outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]);
|
||||||
@ -650,6 +698,7 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
for (Name n : names) assert(n != null);
|
for (Name n : names) assert(n != null);
|
||||||
// add some detail to the lambdaForm debugname,
|
// add some detail to the lambdaForm debugname,
|
||||||
// significant only for debugging
|
// significant only for debugging
|
||||||
|
StringBuilder nameBuilder = new StringBuilder(kind.methodName);
|
||||||
if (isStatic) {
|
if (isStatic) {
|
||||||
nameBuilder.append("Static");
|
nameBuilder.append("Static");
|
||||||
} else {
|
} else {
|
||||||
@ -657,7 +706,12 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
}
|
}
|
||||||
if (needsCast) nameBuilder.append("Cast");
|
if (needsCast) nameBuilder.append("Cast");
|
||||||
if (needsInit) nameBuilder.append("Init");
|
if (needsInit) nameBuilder.append("Init");
|
||||||
return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
|
if (needsCast || needsInit) {
|
||||||
|
// can't use the pre-generated form when casting and/or initializing
|
||||||
|
return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
|
||||||
|
} else {
|
||||||
|
return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT, kind);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -674,7 +728,8 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
NF_staticOffset,
|
NF_staticOffset,
|
||||||
NF_checkCast,
|
NF_checkCast,
|
||||||
NF_allocateInstance,
|
NF_allocateInstance,
|
||||||
NF_constructorMethod;
|
NF_constructorMethod,
|
||||||
|
NF_UNSAFE;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
NamedFunction nfs[] = {
|
NamedFunction nfs[] = {
|
||||||
@ -697,7 +752,9 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
|
NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
|
||||||
.getDeclaredMethod("allocateInstance", Object.class)),
|
.getDeclaredMethod("allocateInstance", Object.class)),
|
||||||
NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
|
NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
|
||||||
.getDeclaredMethod("constructorMethod", Object.class))
|
.getDeclaredMethod("constructorMethod", Object.class)),
|
||||||
|
NF_UNSAFE = new NamedFunction(new MemberName(MethodHandleStatics.class
|
||||||
|
.getDeclaredField("UNSAFE")))
|
||||||
};
|
};
|
||||||
// Each nf must be statically invocable or we get tied up in our bootstraps.
|
// Each nf must be statically invocable or we get tied up in our bootstraps.
|
||||||
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
|
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
|
||||||
|
@ -28,9 +28,11 @@ package java.lang.invoke;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import sun.invoke.util.Wrapper;
|
||||||
|
|
||||||
|
import static java.lang.invoke.MethodHandleNatives.Constants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to assist the GenerateJLIClassesPlugin to get access to
|
* Helper class to assist the GenerateJLIClassesPlugin to get access to
|
||||||
@ -66,14 +68,38 @@ class GenerateJLIClassesHelper {
|
|||||||
|
|
||||||
static byte[] generateDirectMethodHandleHolderClassBytes(String className,
|
static byte[] generateDirectMethodHandleHolderClassBytes(String className,
|
||||||
MethodType[] methodTypes, int[] types) {
|
MethodType[] methodTypes, int[] types) {
|
||||||
LambdaForm[] forms = new LambdaForm[methodTypes.length];
|
ArrayList<LambdaForm> forms = new ArrayList<>();
|
||||||
String[] names = new String[methodTypes.length];
|
ArrayList<String> names = new ArrayList<>();
|
||||||
for (int i = 0; i < forms.length; i++) {
|
for (int i = 0; i < methodTypes.length; i++) {
|
||||||
forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i],
|
LambdaForm form = DirectMethodHandle
|
||||||
types[i]);
|
.makePreparedLambdaForm(methodTypes[i], types[i]);
|
||||||
names[i] = forms[i].kind.defaultLambdaName;
|
forms.add(form);
|
||||||
|
names.add(form.kind.defaultLambdaName);
|
||||||
}
|
}
|
||||||
return generateCodeBytesForLFs(className, names, forms);
|
for (Wrapper wrapper : Wrapper.values()) {
|
||||||
|
if (wrapper == Wrapper.VOID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (byte b = DirectMethodHandle.AF_GETFIELD; b < DirectMethodHandle.AF_LIMIT; b++) {
|
||||||
|
int ftype = DirectMethodHandle.ftypeKind(wrapper.primitiveType());
|
||||||
|
LambdaForm form = DirectMethodHandle
|
||||||
|
.makePreparedFieldLambdaForm(b, /*isVolatile*/false, ftype);
|
||||||
|
if (form.kind != LambdaForm.Kind.GENERIC) {
|
||||||
|
forms.add(form);
|
||||||
|
names.add(form.kind.defaultLambdaName);
|
||||||
|
}
|
||||||
|
// volatile
|
||||||
|
form = DirectMethodHandle
|
||||||
|
.makePreparedFieldLambdaForm(b, /*isVolatile*/true, ftype);
|
||||||
|
if (form.kind != LambdaForm.Kind.GENERIC) {
|
||||||
|
forms.add(form);
|
||||||
|
names.add(form.kind.defaultLambdaName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return generateCodeBytesForLFs(className,
|
||||||
|
names.toArray(new String[0]),
|
||||||
|
forms.toArray(new LambdaForm[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte[] generateDelegatingMethodHandleHolderClassBytes(String className,
|
static byte[] generateDelegatingMethodHandleHolderClassBytes(String className,
|
||||||
@ -107,6 +133,34 @@ class GenerateJLIClassesHelper {
|
|||||||
forms.toArray(new LambdaForm[0]));
|
forms.toArray(new LambdaForm[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static byte[] generateInvokersHolderClassBytes(String className,
|
||||||
|
MethodType[] methodTypes) {
|
||||||
|
|
||||||
|
HashSet<MethodType> dedupSet = new HashSet<>();
|
||||||
|
ArrayList<LambdaForm> forms = new ArrayList<>();
|
||||||
|
ArrayList<String> names = new ArrayList<>();
|
||||||
|
int[] types = {
|
||||||
|
MethodTypeForm.LF_EX_LINKER,
|
||||||
|
MethodTypeForm.LF_EX_INVOKER,
|
||||||
|
MethodTypeForm.LF_GEN_LINKER,
|
||||||
|
MethodTypeForm.LF_GEN_INVOKER
|
||||||
|
};
|
||||||
|
for (int i = 0; i < methodTypes.length; i++) {
|
||||||
|
// generate methods representing invokers of the specified type
|
||||||
|
if (dedupSet.add(methodTypes[i])) {
|
||||||
|
for (int type : types) {
|
||||||
|
LambdaForm invokerForm = Invokers.invokeHandleForm(methodTypes[i],
|
||||||
|
/*customized*/false, type);
|
||||||
|
forms.add(invokerForm);
|
||||||
|
names.add(invokerForm.kind.defaultLambdaName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return generateCodeBytesForLFs(className,
|
||||||
|
names.toArray(new String[0]),
|
||||||
|
forms.toArray(new LambdaForm[0]));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate customized code for a set of LambdaForms of specified types into
|
* Generate customized code for a set of LambdaForms of specified types into
|
||||||
* a class with a specified name.
|
* a class with a specified name.
|
||||||
@ -166,4 +220,5 @@ class GenerateJLIClassesHelper {
|
|||||||
BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
|
BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
|
||||||
shortTypes, types, className));
|
shortTypes, types, className));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -607,7 +607,10 @@ class InvokerBytecodeGenerator {
|
|||||||
private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
|
private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
|
||||||
MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
|
MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
|
||||||
MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
|
MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
|
||||||
|
if (TRACE_RESOLVE) {
|
||||||
|
System.out.println("[LF_RESOLVE] " + holder.getName() + " " + name + " " +
|
||||||
|
shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") );
|
||||||
|
}
|
||||||
return resolvedMember;
|
return resolvedMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -629,6 +632,28 @@ class InvokerBytecodeGenerator {
|
|||||||
name = name + "_" + form.returnType().basicTypeChar();
|
name = name + "_" + form.returnType().basicTypeChar();
|
||||||
return resolveFrom(name, invokerType, LambdaForm.Holder.class);
|
return resolveFrom(name, invokerType, LambdaForm.Holder.class);
|
||||||
}
|
}
|
||||||
|
case EXACT_INVOKER: // fall-through
|
||||||
|
case EXACT_LINKER: // fall-through
|
||||||
|
case GENERIC_INVOKER: // fall-through
|
||||||
|
case GENERIC_LINKER: return resolveFrom(name, invokerType.basicType(), Invokers.Holder.class);
|
||||||
|
case GET_OBJECT: // fall-through
|
||||||
|
case GET_BOOLEAN: // fall-through
|
||||||
|
case GET_BYTE: // fall-through
|
||||||
|
case GET_CHAR: // fall-through
|
||||||
|
case GET_SHORT: // fall-through
|
||||||
|
case GET_INT: // fall-through
|
||||||
|
case GET_LONG: // fall-through
|
||||||
|
case GET_FLOAT: // fall-through
|
||||||
|
case GET_DOUBLE: // fall-through
|
||||||
|
case PUT_OBJECT: // fall-through
|
||||||
|
case PUT_BOOLEAN: // fall-through
|
||||||
|
case PUT_BYTE: // fall-through
|
||||||
|
case PUT_CHAR: // fall-through
|
||||||
|
case PUT_SHORT: // fall-through
|
||||||
|
case PUT_INT: // fall-through
|
||||||
|
case PUT_LONG: // fall-through
|
||||||
|
case PUT_FLOAT: // fall-through
|
||||||
|
case PUT_DOUBLE: // fall-through
|
||||||
case DIRECT_INVOKE_INTERFACE: // fall-through
|
case DIRECT_INVOKE_INTERFACE: // fall-through
|
||||||
case DIRECT_INVOKE_SPECIAL: // fall-through
|
case DIRECT_INVOKE_SPECIAL: // fall-through
|
||||||
case DIRECT_INVOKE_STATIC: // fall-through
|
case DIRECT_INVOKE_STATIC: // fall-through
|
||||||
|
@ -36,6 +36,7 @@ import static java.lang.invoke.MethodHandleStatics.*;
|
|||||||
import static java.lang.invoke.MethodHandleNatives.Constants.*;
|
import static java.lang.invoke.MethodHandleNatives.Constants.*;
|
||||||
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||||
import static java.lang.invoke.LambdaForm.*;
|
import static java.lang.invoke.LambdaForm.*;
|
||||||
|
import static java.lang.invoke.LambdaForm.Kind.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construction and caching of often-used invokers.
|
* Construction and caching of often-used invokers.
|
||||||
@ -254,7 +255,7 @@ class Invokers {
|
|||||||
* @param which bit-encoded 0x01 whether it is a CP adapter ("linker") or MHs.invoker value ("invoker");
|
* @param which bit-encoded 0x01 whether it is a CP adapter ("linker") or MHs.invoker value ("invoker");
|
||||||
* 0x02 whether it is for invokeExact or generic invoke
|
* 0x02 whether it is for invokeExact or generic invoke
|
||||||
*/
|
*/
|
||||||
private static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) {
|
static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) {
|
||||||
boolean isCached;
|
boolean isCached;
|
||||||
if (!customized) {
|
if (!customized) {
|
||||||
mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
|
mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
|
||||||
@ -263,12 +264,12 @@ class Invokers {
|
|||||||
isCached = false; // maybe cache if mtype == mtype.basicType()
|
isCached = false; // maybe cache if mtype == mtype.basicType()
|
||||||
}
|
}
|
||||||
boolean isLinker, isGeneric;
|
boolean isLinker, isGeneric;
|
||||||
String debugName;
|
Kind kind;
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; debugName = "invokeExact_MT"; break;
|
case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; kind = EXACT_LINKER; break;
|
||||||
case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; debugName = "exactInvoker"; break;
|
case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; kind = EXACT_INVOKER; break;
|
||||||
case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; debugName = "invoke_MT"; break;
|
case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; kind = GENERIC_LINKER; break;
|
||||||
case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; debugName = "invoker"; break;
|
case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; kind = GENERIC_INVOKER; break;
|
||||||
default: throw new InternalError();
|
default: throw new InternalError();
|
||||||
}
|
}
|
||||||
LambdaForm lform;
|
LambdaForm lform;
|
||||||
@ -323,7 +324,11 @@ class Invokers {
|
|||||||
names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]);
|
names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]);
|
||||||
}
|
}
|
||||||
names[LINKER_CALL] = new Name(outCallType, outArgs);
|
names[LINKER_CALL] = new Name(outCallType, outArgs);
|
||||||
lform = new LambdaForm(debugName, INARG_LIMIT, names);
|
if (customized) {
|
||||||
|
lform = new LambdaForm(kind.defaultLambdaName, INARG_LIMIT, names);
|
||||||
|
} else {
|
||||||
|
lform = new LambdaForm(kind.defaultLambdaName, INARG_LIMIT, names, kind);
|
||||||
|
}
|
||||||
if (isLinker)
|
if (isLinker)
|
||||||
lform.compileToBytecode(); // JVM needs a real methodOop
|
lform.compileToBytecode(); // JVM needs a real methodOop
|
||||||
if (isCached)
|
if (isCached)
|
||||||
@ -614,4 +619,15 @@ class Invokers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
// The Holder class will contain pre-generated Invokers resolved
|
||||||
|
// speculatively using MemberName.getFactory().resolveOrNull. However, that
|
||||||
|
// doesn't initialize the class, which subtly breaks inlining etc. By forcing
|
||||||
|
// initialization of the Holder class we avoid these issues.
|
||||||
|
UNSAFE.ensureClassInitialized(Holder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Placeholder class for Invokers generated ahead of time */
|
||||||
|
final class Holder {}
|
||||||
}
|
}
|
||||||
|
@ -275,12 +275,52 @@ class LambdaForm {
|
|||||||
BOUND_REINVOKER("BMH.reinvoke"),
|
BOUND_REINVOKER("BMH.reinvoke"),
|
||||||
REINVOKER("MH.reinvoke"),
|
REINVOKER("MH.reinvoke"),
|
||||||
DELEGATE("MH.delegate"),
|
DELEGATE("MH.delegate"),
|
||||||
|
EXACT_LINKER("MH.invokeExact_MT"),
|
||||||
|
EXACT_INVOKER("MH.exactInvoker"),
|
||||||
|
GENERIC_LINKER("MH.invoke_MT"),
|
||||||
|
GENERIC_INVOKER("MH.invoker"),
|
||||||
DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"),
|
DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"),
|
||||||
DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"),
|
DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"),
|
||||||
DIRECT_INVOKE_STATIC("DMH.invokeStatic"),
|
DIRECT_INVOKE_STATIC("DMH.invokeStatic"),
|
||||||
DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"),
|
DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"),
|
||||||
DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"),
|
DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"),
|
||||||
DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit");
|
DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"),
|
||||||
|
GET_OBJECT("getObject"),
|
||||||
|
PUT_OBJECT("putObject"),
|
||||||
|
GET_OBJECT_VOLATILE("getObjectVolatile"),
|
||||||
|
PUT_OBJECT_VOLATILE("putObjectVolatile"),
|
||||||
|
GET_INT("getInt"),
|
||||||
|
PUT_INT("putInt"),
|
||||||
|
GET_INT_VOLATILE("getIntVolatile"),
|
||||||
|
PUT_INT_VOLATILE("putIntVolatile"),
|
||||||
|
GET_BOOLEAN("getBoolean"),
|
||||||
|
PUT_BOOLEAN("putBoolean"),
|
||||||
|
GET_BOOLEAN_VOLATILE("getBooleanVolatile"),
|
||||||
|
PUT_BOOLEAN_VOLATILE("putBooleanVolatile"),
|
||||||
|
GET_BYTE("getByte"),
|
||||||
|
PUT_BYTE("putByte"),
|
||||||
|
GET_BYTE_VOLATILE("getByteVolatile"),
|
||||||
|
PUT_BYTE_VOLATILE("putByteVolatile"),
|
||||||
|
GET_CHAR("getChar"),
|
||||||
|
PUT_CHAR("putChar"),
|
||||||
|
GET_CHAR_VOLATILE("getCharVolatile"),
|
||||||
|
PUT_CHAR_VOLATILE("putCharVolatile"),
|
||||||
|
GET_SHORT("getShort"),
|
||||||
|
PUT_SHORT("putShort"),
|
||||||
|
GET_SHORT_VOLATILE("getShortVolatile"),
|
||||||
|
PUT_SHORT_VOLATILE("putShortVolatile"),
|
||||||
|
GET_LONG("getLong"),
|
||||||
|
PUT_LONG("putLong"),
|
||||||
|
GET_LONG_VOLATILE("getLongVolatile"),
|
||||||
|
PUT_LONG_VOLATILE("putLongVolatile"),
|
||||||
|
GET_FLOAT("getFloat"),
|
||||||
|
PUT_FLOAT("putFloat"),
|
||||||
|
GET_FLOAT_VOLATILE("getFloatVolatile"),
|
||||||
|
PUT_FLOAT_VOLATILE("putFloatVolatile"),
|
||||||
|
GET_DOUBLE("getDouble"),
|
||||||
|
PUT_DOUBLE("putDouble"),
|
||||||
|
GET_DOUBLE_VOLATILE("getDoubleVolatile"),
|
||||||
|
PUT_DOUBLE_VOLATILE("putDoubleVolatile");
|
||||||
|
|
||||||
final String defaultLambdaName;
|
final String defaultLambdaName;
|
||||||
final String methodName;
|
final String methodName;
|
||||||
@ -329,6 +369,10 @@ class LambdaForm {
|
|||||||
int arity, Name[] names) {
|
int arity, Name[] names) {
|
||||||
this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
|
this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
|
||||||
}
|
}
|
||||||
|
LambdaForm(String debugName,
|
||||||
|
int arity, Name[] names, Kind kind) {
|
||||||
|
this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, kind);
|
||||||
|
}
|
||||||
LambdaForm(String debugName,
|
LambdaForm(String debugName,
|
||||||
int arity, Name[] names, boolean forceInline) {
|
int arity, Name[] names, boolean forceInline) {
|
||||||
this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC);
|
this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC);
|
||||||
@ -817,54 +861,6 @@ class LambdaForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void computeInitialPreparedForms() {
|
|
||||||
// Find all predefined invokers and associate them with canonical empty lambda forms.
|
|
||||||
for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) {
|
|
||||||
if (!m.isStatic() || !m.isPackage()) continue;
|
|
||||||
MethodType mt = m.getMethodType();
|
|
||||||
if (mt.parameterCount() > 0 &&
|
|
||||||
mt.parameterType(0) == MethodHandle.class &&
|
|
||||||
m.getName().startsWith("interpret_")) {
|
|
||||||
String sig = null;
|
|
||||||
assert((sig = basicTypeSignature(mt)) != null &&
|
|
||||||
m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
|
|
||||||
LambdaForm form = new LambdaForm(mt);
|
|
||||||
form.vmentry = m;
|
|
||||||
form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set this false to disable use of the interpret_L methods defined in this file.
|
|
||||||
private static final boolean USE_PREDEFINED_INTERPRET_METHODS = true;
|
|
||||||
|
|
||||||
// The following are predefined exact invokers. The system must build
|
|
||||||
// a separate invoker for each distinct signature.
|
|
||||||
static Object interpret_L(MethodHandle mh) throws Throwable {
|
|
||||||
Object[] av = {mh};
|
|
||||||
String sig = null;
|
|
||||||
assert(argumentTypesMatch(sig = "L_L", av));
|
|
||||||
Object res = mh.form.interpretWithArguments(av);
|
|
||||||
assert(returnTypesMatch(sig, av, res));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
static Object interpret_L(MethodHandle mh, Object x1) throws Throwable {
|
|
||||||
Object[] av = {mh, x1};
|
|
||||||
String sig = null;
|
|
||||||
assert(argumentTypesMatch(sig = "LL_L", av));
|
|
||||||
Object res = mh.form.interpretWithArguments(av);
|
|
||||||
assert(returnTypesMatch(sig, av, res));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
static Object interpret_L(MethodHandle mh, Object x1, Object x2) throws Throwable {
|
|
||||||
Object[] av = {mh, x1, x2};
|
|
||||||
String sig = null;
|
|
||||||
assert(argumentTypesMatch(sig = "LLL_L", av));
|
|
||||||
Object res = mh.form.interpretWithArguments(av);
|
|
||||||
assert(returnTypesMatch(sig, av, res));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The next few routines are called only from assert expressions
|
// The next few routines are called only from assert expressions
|
||||||
// They verify that the built-in invokers process the correct raw data types.
|
// They verify that the built-in invokers process the correct raw data types.
|
||||||
private static boolean argumentTypesMatch(String sig, Object[] av) {
|
private static boolean argumentTypesMatch(String sig, Object[] av) {
|
||||||
@ -1151,113 +1147,6 @@ class LambdaForm {
|
|||||||
return super.hashCode();
|
return super.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put the predefined NamedFunction invokers into the table.
|
|
||||||
static void initializeInvokers() {
|
|
||||||
for (MemberName m : MemberName.getFactory().getMethods(NamedFunction.class, false, null, null, null)) {
|
|
||||||
if (!m.isStatic() || !m.isPackage()) continue;
|
|
||||||
MethodType type = m.getMethodType();
|
|
||||||
if (type.equals(INVOKER_METHOD_TYPE) &&
|
|
||||||
m.getName().startsWith("invoke_")) {
|
|
||||||
String sig = m.getName().substring("invoke_".length());
|
|
||||||
int arity = LambdaForm.signatureArity(sig);
|
|
||||||
MethodType srcType = MethodType.genericMethodType(arity);
|
|
||||||
if (LambdaForm.signatureReturn(sig) == V_TYPE)
|
|
||||||
srcType = srcType.changeReturnType(void.class);
|
|
||||||
MethodTypeForm typeForm = srcType.form();
|
|
||||||
typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, DirectMethodHandle.make(m));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The following are predefined NamedFunction invokers. The system must build
|
|
||||||
// a separate invoker for each distinct signature.
|
|
||||||
/** void return type invokers. */
|
|
||||||
@Hidden
|
|
||||||
static Object invoke__V(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(0, void.class, mh, a));
|
|
||||||
mh.invokeBasic();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
@Hidden
|
|
||||||
static Object invoke_L_V(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(1, void.class, mh, a));
|
|
||||||
mh.invokeBasic(a[0]);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
@Hidden
|
|
||||||
static Object invoke_LL_V(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(2, void.class, mh, a));
|
|
||||||
mh.invokeBasic(a[0], a[1]);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
@Hidden
|
|
||||||
static Object invoke_LLL_V(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(3, void.class, mh, a));
|
|
||||||
mh.invokeBasic(a[0], a[1], a[2]);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
@Hidden
|
|
||||||
static Object invoke_LLLL_V(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(4, void.class, mh, a));
|
|
||||||
mh.invokeBasic(a[0], a[1], a[2], a[3]);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
@Hidden
|
|
||||||
static Object invoke_LLLLL_V(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(5, void.class, mh, a));
|
|
||||||
mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
/** Object return type invokers. */
|
|
||||||
@Hidden
|
|
||||||
static Object invoke__L(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(0, mh, a));
|
|
||||||
return mh.invokeBasic();
|
|
||||||
}
|
|
||||||
@Hidden
|
|
||||||
static Object invoke_L_L(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(1, mh, a));
|
|
||||||
return mh.invokeBasic(a[0]);
|
|
||||||
}
|
|
||||||
@Hidden
|
|
||||||
static Object invoke_LL_L(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(2, mh, a));
|
|
||||||
return mh.invokeBasic(a[0], a[1]);
|
|
||||||
}
|
|
||||||
@Hidden
|
|
||||||
static Object invoke_LLL_L(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(3, mh, a));
|
|
||||||
return mh.invokeBasic(a[0], a[1], a[2]);
|
|
||||||
}
|
|
||||||
@Hidden
|
|
||||||
static Object invoke_LLLL_L(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(4, mh, a));
|
|
||||||
return mh.invokeBasic(a[0], a[1], a[2], a[3]);
|
|
||||||
}
|
|
||||||
@Hidden
|
|
||||||
static Object invoke_LLLLL_L(MethodHandle mh, Object[] a) throws Throwable {
|
|
||||||
assert(arityCheck(5, mh, a));
|
|
||||||
return mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]);
|
|
||||||
}
|
|
||||||
private static boolean arityCheck(int arity, MethodHandle mh, Object[] a) {
|
|
||||||
return arityCheck(arity, Object.class, mh, a);
|
|
||||||
}
|
|
||||||
private static boolean arityCheck(int arity, Class<?> rtype, MethodHandle mh, Object[] a) {
|
|
||||||
assert(a.length == arity)
|
|
||||||
: Arrays.asList(a.length, arity);
|
|
||||||
assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype))
|
|
||||||
: Arrays.asList(mh, rtype, arity);
|
|
||||||
MemberName member = mh.internalMemberName();
|
|
||||||
if (isInvokeBasic(member)) {
|
|
||||||
assert(arity > 0);
|
|
||||||
assert(a[0] instanceof MethodHandle);
|
|
||||||
MethodHandle mh2 = (MethodHandle) a[0];
|
|
||||||
assert(mh2.type().basicType() == MethodType.genericMethodType(arity-1).changeReturnType(rtype))
|
|
||||||
: Arrays.asList(member, mh2, rtype, arity);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static final MethodType INVOKER_METHOD_TYPE =
|
static final MethodType INVOKER_METHOD_TYPE =
|
||||||
MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
|
MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
|
||||||
|
|
||||||
@ -1920,12 +1809,7 @@ class LambdaForm {
|
|||||||
DEBUG_NAME_COUNTERS = null;
|
DEBUG_NAME_COUNTERS = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put this last, so that previous static inits can run before.
|
|
||||||
static {
|
static {
|
||||||
if (USE_PREDEFINED_INTERPRET_METHODS)
|
|
||||||
computeInitialPreparedForms();
|
|
||||||
NamedFunction.initializeInvokers();
|
|
||||||
|
|
||||||
// The Holder class will contain pre-generated forms resolved
|
// The Holder class will contain pre-generated forms resolved
|
||||||
// using MemberName.getFactory(). However, that doesn't initialize the
|
// using MemberName.getFactory(). However, that doesn't initialize the
|
||||||
// class, which subtly breaks inlining etc. By forcing
|
// class, which subtly breaks inlining etc. By forcing
|
||||||
|
@ -1745,6 +1745,13 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||||||
return GenerateJLIClassesHelper
|
return GenerateJLIClassesHelper
|
||||||
.generateBasicFormsClassBytes(className);
|
.generateBasicFormsClassBytes(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] generateInvokersHolderClassBytes(final String className,
|
||||||
|
MethodType[] methodTypes) {
|
||||||
|
return GenerateJLIClassesHelper
|
||||||
|
.generateInvokersHolderClassBytes(className, methodTypes);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ import java.util.Properties;
|
|||||||
static final boolean DUMP_CLASS_FILES;
|
static final boolean DUMP_CLASS_FILES;
|
||||||
static final boolean TRACE_INTERPRETER;
|
static final boolean TRACE_INTERPRETER;
|
||||||
static final boolean TRACE_METHOD_LINKAGE;
|
static final boolean TRACE_METHOD_LINKAGE;
|
||||||
|
static final boolean TRACE_RESOLVE;
|
||||||
static final int COMPILE_THRESHOLD;
|
static final int COMPILE_THRESHOLD;
|
||||||
static final boolean LOG_LF_COMPILATION_FAILURE;
|
static final boolean LOG_LF_COMPILATION_FAILURE;
|
||||||
static final int DONT_INLINE_THRESHOLD;
|
static final int DONT_INLINE_THRESHOLD;
|
||||||
@ -65,6 +66,8 @@ import java.util.Properties;
|
|||||||
props.getProperty("java.lang.invoke.MethodHandle.TRACE_INTERPRETER"));
|
props.getProperty("java.lang.invoke.MethodHandle.TRACE_INTERPRETER"));
|
||||||
TRACE_METHOD_LINKAGE = Boolean.parseBoolean(
|
TRACE_METHOD_LINKAGE = Boolean.parseBoolean(
|
||||||
props.getProperty("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"));
|
props.getProperty("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"));
|
||||||
|
TRACE_RESOLVE = Boolean.parseBoolean(
|
||||||
|
props.getProperty("java.lang.invoke.MethodHandle.TRACE_RESOLVE"));
|
||||||
COMPILE_THRESHOLD = Integer.parseInt(
|
COMPILE_THRESHOLD = Integer.parseInt(
|
||||||
props.getProperty("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", "0"));
|
props.getProperty("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", "0"));
|
||||||
LOG_LF_COMPILATION_FAILURE = Boolean.parseBoolean(
|
LOG_LF_COMPILATION_FAILURE = Boolean.parseBoolean(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -233,7 +233,7 @@ public final class HttpCookie implements Cloneable {
|
|||||||
// if not specify max-age, this cookie should be
|
// if not specify max-age, this cookie should be
|
||||||
// discarded when user agent is to be closed, but
|
// discarded when user agent is to be closed, but
|
||||||
// it is not expired.
|
// it is not expired.
|
||||||
if (maxAge == MAX_AGE_UNSPECIFIED) return false;
|
if (maxAge < 0) return false;
|
||||||
|
|
||||||
long deltaSecond = (System.currentTimeMillis() - whenCreated) / 1000;
|
long deltaSecond = (System.currentTimeMillis() - whenCreated) / 1000;
|
||||||
if (deltaSecond > maxAge)
|
if (deltaSecond > maxAge)
|
||||||
@ -952,7 +952,8 @@ public final class HttpCookie implements Cloneable {
|
|||||||
String attrName,
|
String attrName,
|
||||||
String attrValue) {
|
String attrValue) {
|
||||||
if (cookie.getMaxAge() == MAX_AGE_UNSPECIFIED) {
|
if (cookie.getMaxAge() == MAX_AGE_UNSPECIFIED) {
|
||||||
cookie.setMaxAge(cookie.expiryDate2DeltaSeconds(attrValue));
|
long delta = cookie.expiryDate2DeltaSeconds(attrValue);
|
||||||
|
cookie.setMaxAge(delta > 0 ? delta : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -150,10 +150,12 @@ public final class Duration
|
|||||||
/**
|
/**
|
||||||
* The pattern for parsing.
|
* The pattern for parsing.
|
||||||
*/
|
*/
|
||||||
private static final Pattern PATTERN =
|
private static class Lazy {
|
||||||
|
static final Pattern PATTERN =
|
||||||
Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?" +
|
Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?" +
|
||||||
"(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?",
|
"(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?",
|
||||||
Pattern.CASE_INSENSITIVE);
|
Pattern.CASE_INSENSITIVE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of seconds in the duration.
|
* The number of seconds in the duration.
|
||||||
@ -387,7 +389,7 @@ public final class Duration
|
|||||||
*/
|
*/
|
||||||
public static Duration parse(CharSequence text) {
|
public static Duration parse(CharSequence text) {
|
||||||
Objects.requireNonNull(text, "text");
|
Objects.requireNonNull(text, "text");
|
||||||
Matcher matcher = PATTERN.matcher(text);
|
Matcher matcher = Lazy.PATTERN.matcher(text);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
// check for letter T but no time sections
|
// check for letter T but no time sections
|
||||||
if (!charMatch(text, matcher.start(3), matcher.end(3), 'T')) {
|
if (!charMatch(text, matcher.start(3), matcher.end(3), 'T')) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -375,15 +375,15 @@ public final class ZoneOffset
|
|||||||
} else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) {
|
} else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) {
|
||||||
throw new DateTimeException("Zone offset minutes and seconds must have the same sign");
|
throw new DateTimeException("Zone offset minutes and seconds must have the same sign");
|
||||||
}
|
}
|
||||||
if (Math.abs(minutes) > 59) {
|
if (minutes < -59 || minutes > 59) {
|
||||||
throw new DateTimeException("Zone offset minutes not in valid range: abs(value) " +
|
throw new DateTimeException("Zone offset minutes not in valid range: value " +
|
||||||
Math.abs(minutes) + " is not in the range 0 to 59");
|
minutes + " is not in the range -59 to 59");
|
||||||
}
|
}
|
||||||
if (Math.abs(seconds) > 59) {
|
if (seconds < -59 || seconds > 59) {
|
||||||
throw new DateTimeException("Zone offset seconds not in valid range: abs(value) " +
|
throw new DateTimeException("Zone offset seconds not in valid range: value " +
|
||||||
Math.abs(seconds) + " is not in the range 0 to 59");
|
seconds + " is not in the range -59 to 59");
|
||||||
}
|
}
|
||||||
if (Math.abs(hours) == 18 && (Math.abs(minutes) > 0 || Math.abs(seconds) > 0)) {
|
if (Math.abs(hours) == 18 && (minutes | seconds) != 0) {
|
||||||
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
|
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -411,7 +411,7 @@ public final class ZoneOffset
|
|||||||
* @throws DateTimeException if the offset is not in the required range
|
* @throws DateTimeException if the offset is not in the required range
|
||||||
*/
|
*/
|
||||||
public static ZoneOffset ofTotalSeconds(int totalSeconds) {
|
public static ZoneOffset ofTotalSeconds(int totalSeconds) {
|
||||||
if (Math.abs(totalSeconds) > MAX_SECONDS) {
|
if (totalSeconds < -MAX_SECONDS || totalSeconds > MAX_SECONDS) {
|
||||||
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
|
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
|
||||||
}
|
}
|
||||||
if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) {
|
if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) {
|
||||||
@ -696,11 +696,12 @@ public final class ZoneOffset
|
|||||||
* The comparison is "consistent with equals", as defined by {@link Comparable}.
|
* The comparison is "consistent with equals", as defined by {@link Comparable}.
|
||||||
*
|
*
|
||||||
* @param other the other date to compare to, not null
|
* @param other the other date to compare to, not null
|
||||||
* @return the comparator value, negative if less, postive if greater
|
* @return the comparator value, negative if less, positive if greater
|
||||||
* @throws NullPointerException if {@code other} is null
|
* @throws NullPointerException if {@code other} is null
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(ZoneOffset other) {
|
public int compareTo(ZoneOffset other) {
|
||||||
|
// abs(totalSeconds) <= MAX_SECONDS, so no overflow can happen here
|
||||||
return other.totalSeconds - totalSeconds;
|
return other.totalSeconds - totalSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4566,7 +4566,10 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
|
|||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
// Use (c instanceof Set) as a hint that lookup in c is as
|
// Use (c instanceof Set) as a hint that lookup in c is as
|
||||||
// efficient as this view
|
// efficient as this view
|
||||||
if (c instanceof Set<?> && c.size() > map.table.length) {
|
Node<K,V>[] t;
|
||||||
|
if ((t = map.table) == null) {
|
||||||
|
return false;
|
||||||
|
} else if (c instanceof Set<?> && c.size() > t.length) {
|
||||||
for (Iterator<?> it = iterator(); it.hasNext(); ) {
|
for (Iterator<?> it = iterator(); it.hasNext(); ) {
|
||||||
if (c.contains(it.next())) {
|
if (c.contains(it.next())) {
|
||||||
it.remove();
|
it.remove();
|
||||||
|
@ -353,7 +353,7 @@ class JarFile extends ZipFile {
|
|||||||
if (isMultiRelease) {
|
if (isMultiRelease) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) {
|
if (MULTI_RELEASE_ENABLED) {
|
||||||
try {
|
try {
|
||||||
checkForSpecialAttributes();
|
checkForSpecialAttributes();
|
||||||
} catch (IOException io) {
|
} catch (IOException io) {
|
||||||
@ -644,7 +644,7 @@ class JarFile extends ZipFile {
|
|||||||
return signers == null ? null : signers.clone();
|
return signers == null ? null : signers.clone();
|
||||||
}
|
}
|
||||||
JarFileEntry realEntry() {
|
JarFileEntry realEntry() {
|
||||||
if (isMultiRelease()) {
|
if (isMultiRelease() && versionMajor != BASE_VERSION_MAJOR) {
|
||||||
String entryName = super.getName();
|
String entryName = super.getName();
|
||||||
return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this);
|
return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this);
|
||||||
}
|
}
|
||||||
@ -960,7 +960,7 @@ class JarFile extends ZipFile {
|
|||||||
hasClassPathAttribute = match(CLASSPATH_CHARS, b,
|
hasClassPathAttribute = match(CLASSPATH_CHARS, b,
|
||||||
CLASSPATH_LASTOCC) != -1;
|
CLASSPATH_LASTOCC) != -1;
|
||||||
// is this a multi-release jar file
|
// is this a multi-release jar file
|
||||||
if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) {
|
if (MULTI_RELEASE_ENABLED) {
|
||||||
int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC);
|
int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC);
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
i += MULTIRELEASE_CHARS.length;
|
i += MULTIRELEASE_CHARS.length;
|
||||||
|
@ -29,6 +29,7 @@ import java.util.*;
|
|||||||
import java.util.jar.*;
|
import java.util.jar.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.file.*;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
|
|
||||||
import java.security.Provider.Service;
|
import java.security.Provider.Service;
|
||||||
@ -206,7 +207,7 @@ final class JceSecurity {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
NULL_URL = new URL("http://null.sun.com/");
|
NULL_URL = new URL("http://null.oracle.com/");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -243,83 +244,94 @@ final class JceSecurity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is called from within an doPrivileged block.
|
||||||
private static void setupJurisdictionPolicies() throws Exception {
|
private static void setupJurisdictionPolicies() throws Exception {
|
||||||
String javaHomeDir = System.getProperty("java.home");
|
|
||||||
String sep = File.separator;
|
|
||||||
String pathToPolicyJar = javaHomeDir + sep + "lib" + sep +
|
|
||||||
"security" + sep;
|
|
||||||
|
|
||||||
File exportJar = new File(pathToPolicyJar, "US_export_policy.jar");
|
// Sanity check the crypto.policy Security property. Single
|
||||||
File importJar = new File(pathToPolicyJar, "local_policy.jar");
|
// directory entry, no pseudo-directories (".", "..", leading/trailing
|
||||||
|
// path separators). normalize()/getParent() will help later.
|
||||||
|
String cryptoPolicyProperty = Security.getProperty("crypto.policy");
|
||||||
|
Path cpPath = Paths.get(cryptoPolicyProperty);
|
||||||
|
|
||||||
if (!exportJar.exists() || !importJar.exists()) {
|
if ((cryptoPolicyProperty == null) ||
|
||||||
throw new SecurityException
|
(cpPath.getNameCount() != 1) ||
|
||||||
("Cannot locate policy or framework files!");
|
(cpPath.compareTo(cpPath.getFileName()) != 0)) {
|
||||||
|
throw new SecurityException(
|
||||||
|
"Invalid policy directory name format: " +
|
||||||
|
cryptoPolicyProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read jurisdiction policies.
|
// Prepend java.home to get the full path. normalize() in
|
||||||
CryptoPermissions defaultExport = new CryptoPermissions();
|
// case an extra "." or ".." snuck in somehow.
|
||||||
CryptoPermissions exemptExport = new CryptoPermissions();
|
String javaHomeProperty = System.getProperty("java.home");
|
||||||
loadPolicies(exportJar, defaultExport, exemptExport);
|
Path javaHomePolicyPath = Paths.get(javaHomeProperty, "conf",
|
||||||
|
"security", "policy").normalize();
|
||||||
|
Path cryptoPolicyPath = Paths.get(javaHomeProperty, "conf", "security",
|
||||||
|
"policy", cryptoPolicyProperty).normalize();
|
||||||
|
|
||||||
CryptoPermissions defaultImport = new CryptoPermissions();
|
if (cryptoPolicyPath.getParent().compareTo(javaHomePolicyPath) != 0) {
|
||||||
CryptoPermissions exemptImport = new CryptoPermissions();
|
throw new SecurityException(
|
||||||
loadPolicies(importJar, defaultImport, exemptImport);
|
"Invalid cryptographic jurisdiction policy directory path: " +
|
||||||
|
cryptoPolicyProperty);
|
||||||
// Merge the export and import policies for default applications.
|
|
||||||
if (defaultExport.isEmpty() || defaultImport.isEmpty()) {
|
|
||||||
throw new SecurityException("Missing mandatory jurisdiction " +
|
|
||||||
"policy files");
|
|
||||||
}
|
}
|
||||||
defaultPolicy = defaultExport.getMinimum(defaultImport);
|
|
||||||
|
|
||||||
// Merge the export and import policies for exempt applications.
|
if (!Files.isDirectory(cryptoPolicyPath)
|
||||||
if (exemptExport.isEmpty()) {
|
|| !Files.isReadable(cryptoPolicyPath)) {
|
||||||
exemptPolicy = exemptImport.isEmpty() ? null : exemptImport;
|
throw new SecurityException(
|
||||||
} else {
|
"Can't read cryptographic policy directory: " +
|
||||||
exemptPolicy = exemptExport.getMinimum(exemptImport);
|
cryptoPolicyProperty);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(
|
||||||
* Load the policies from the specified file. Also checks that the
|
cryptoPolicyPath, "{default,exempt}_*.policy")) {
|
||||||
* policies are correctly signed.
|
for (Path entry : stream) {
|
||||||
*/
|
try (InputStream is = new BufferedInputStream(
|
||||||
private static void loadPolicies(File jarPathName,
|
Files.newInputStream(entry))) {
|
||||||
CryptoPermissions defaultPolicy,
|
String filename = entry.getFileName().toString();
|
||||||
CryptoPermissions exemptPolicy)
|
|
||||||
throws Exception {
|
|
||||||
|
|
||||||
JarFile jf = new JarFile(jarPathName);
|
CryptoPermissions tmpPerms = new CryptoPermissions();
|
||||||
|
tmpPerms.load(is);
|
||||||
|
|
||||||
Enumeration<JarEntry> entries = jf.entries();
|
if (filename.startsWith("default_")) {
|
||||||
while (entries.hasMoreElements()) {
|
// Did we find a default perms?
|
||||||
JarEntry je = entries.nextElement();
|
defaultPolicy = ((defaultPolicy == null) ? tmpPerms :
|
||||||
InputStream is = null;
|
defaultPolicy.getMinimum(tmpPerms));
|
||||||
try {
|
} else if (filename.startsWith("exempt_")) {
|
||||||
if (je.getName().startsWith("default_")) {
|
// Did we find a exempt perms?
|
||||||
is = jf.getInputStream(je);
|
exemptPolicy = ((exemptPolicy == null) ? tmpPerms :
|
||||||
defaultPolicy.load(is);
|
exemptPolicy.getMinimum(tmpPerms));
|
||||||
} else if (je.getName().startsWith("exempt_")) {
|
} else {
|
||||||
is = jf.getInputStream(je);
|
// This should never happen. newDirectoryStream
|
||||||
exemptPolicy.load(is);
|
// should only throw return "{default,exempt}_*.policy"
|
||||||
} else {
|
throw new SecurityException(
|
||||||
continue;
|
"Unexpected jurisdiction policy files in : " +
|
||||||
}
|
cryptoPolicyProperty);
|
||||||
} finally {
|
}
|
||||||
if (is != null) {
|
} catch (Exception e) {
|
||||||
is.close();
|
throw new SecurityException(
|
||||||
|
"Couldn't parse jurisdiction policy files in: " +
|
||||||
|
cryptoPolicyProperty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (DirectoryIteratorException ex) {
|
||||||
// Enforce the signer restraint, i.e. signer of JCE framework
|
// I/O error encountered during the iteration,
|
||||||
// jar should also be the signer of the two jurisdiction policy
|
// the cause is an IOException
|
||||||
// jar files.
|
throw new SecurityException(
|
||||||
ProviderVerifier.verifyPolicySigned(je.getCertificates());
|
"Couldn't iterate through the jurisdiction policy files: " +
|
||||||
|
cryptoPolicyProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must have a default policy
|
||||||
|
if ((defaultPolicy == null) || defaultPolicy.isEmpty()) {
|
||||||
|
throw new SecurityException(
|
||||||
|
"Missing mandatory jurisdiction policy files: " +
|
||||||
|
cryptoPolicyProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there was an empty exempt policy file, ignore it.
|
||||||
|
if ((exemptPolicy != null) && exemptPolicy.isEmpty()) {
|
||||||
|
exemptPolicy = null;
|
||||||
}
|
}
|
||||||
// Close and nullify the JarFile reference to help GC.
|
|
||||||
jf.close();
|
|
||||||
jf = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CryptoPermissions getDefaultPolicy() {
|
static CryptoPermissions getDefaultPolicy() {
|
||||||
|
@ -47,8 +47,8 @@ final class JrtDirectoryStream implements DirectoryStream<Path> {
|
|||||||
|
|
||||||
private final JrtPath dir;
|
private final JrtPath dir;
|
||||||
private final DirectoryStream.Filter<? super Path> filter;
|
private final DirectoryStream.Filter<? super Path> filter;
|
||||||
private volatile boolean isClosed;
|
private boolean isClosed;
|
||||||
private volatile Iterator<Path> itr;
|
private Iterator<Path> itr;
|
||||||
|
|
||||||
JrtDirectoryStream(JrtPath dir,
|
JrtDirectoryStream(JrtPath dir,
|
||||||
DirectoryStream.Filter<? super java.nio.file.Path> filter)
|
DirectoryStream.Filter<? super java.nio.file.Path> filter)
|
||||||
@ -73,24 +73,22 @@ final class JrtDirectoryStream implements DirectoryStream<Path> {
|
|||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
return new Iterator<Path>() {
|
return new Iterator<Path>() {
|
||||||
private Path next;
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean hasNext() {
|
public boolean hasNext() {
|
||||||
if (isClosed)
|
synchronized (JrtDirectoryStream.this) {
|
||||||
return false;
|
if (isClosed)
|
||||||
return itr.hasNext();
|
return false;
|
||||||
|
return itr.hasNext();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized Path next() {
|
public Path next() {
|
||||||
if (isClosed)
|
synchronized (JrtDirectoryStream.this) {
|
||||||
throw new NoSuchElementException();
|
if (isClosed)
|
||||||
return itr.next();
|
throw new NoSuchElementException();
|
||||||
}
|
return itr.next();
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -119,9 +119,7 @@ class JrtFileSystem extends FileSystem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Path> getRootDirectories() {
|
public Iterable<Path> getRootDirectories() {
|
||||||
ArrayList<Path> dirs = new ArrayList<>();
|
return Collections.singleton(getRootPath());
|
||||||
dirs.add(getRootPath());
|
|
||||||
return dirs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -159,9 +157,7 @@ class JrtFileSystem extends FileSystem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Iterable<FileStore> getFileStores() {
|
public final Iterable<FileStore> getFileStores() {
|
||||||
ArrayList<FileStore> list = new ArrayList<>(1);
|
return Collections.singleton(getFileStore(getRootPath()));
|
||||||
list.add(getFileStore(getRootPath()));
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Set<String> supportedFileAttributeViews
|
private static final Set<String> supportedFileAttributeViews
|
||||||
|
@ -46,7 +46,7 @@ public interface JavaLangInvokeAccess {
|
|||||||
boolean isNative(Object mname);
|
boolean isNative(Object mname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@code byte[]} containing the bytecode for a class implementing
|
* Returns a {@code byte[]} representation of a class implementing
|
||||||
* DirectMethodHandle of each pairwise combination of {@code MethodType} and
|
* DirectMethodHandle of each pairwise combination of {@code MethodType} and
|
||||||
* an {@code int} representing method type. Used by
|
* an {@code int} representing method type. Used by
|
||||||
* GenerateJLIClassesPlugin to generate such a class during the jlink phase.
|
* GenerateJLIClassesPlugin to generate such a class during the jlink phase.
|
||||||
@ -55,7 +55,7 @@ public interface JavaLangInvokeAccess {
|
|||||||
MethodType[] methodTypes, int[] types);
|
MethodType[] methodTypes, int[] types);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@code byte[]} containing the bytecode for a class implementing
|
* Returns a {@code byte[]} representation of a class implementing
|
||||||
* DelegatingMethodHandles of each {@code MethodType} kind in the
|
* DelegatingMethodHandles of each {@code MethodType} kind in the
|
||||||
* {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to
|
* {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to
|
||||||
* generate such a class during the jlink phase.
|
* generate such a class during the jlink phase.
|
||||||
@ -64,7 +64,7 @@ public interface JavaLangInvokeAccess {
|
|||||||
MethodType[] methodTypes);
|
MethodType[] methodTypes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle
|
* Returns a {@code byte[]} representation of {@code BoundMethodHandle}
|
||||||
* species class implementing the signature defined by {@code types}. Used
|
* species class implementing the signature defined by {@code types}. Used
|
||||||
* by GenerateBMHClassesPlugin to enable generation of such classes during
|
* by GenerateBMHClassesPlugin to enable generation of such classes during
|
||||||
* the jlink phase. Should do some added validation since this string may be
|
* the jlink phase. Should do some added validation since this string may be
|
||||||
@ -74,8 +74,15 @@ public interface JavaLangInvokeAccess {
|
|||||||
final String types);
|
final String types);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@code byte[]} containing the bytecode for a class implementing
|
* Returns a {@code byte[]} representation of a class implementing
|
||||||
* the zero and identity forms of all {@code LambdaForm.BasicType}s.
|
* the zero and identity forms of all {@code LambdaForm.BasicType}s.
|
||||||
*/
|
*/
|
||||||
byte[] generateBasicFormsClassBytes(final String className);
|
byte[] generateBasicFormsClassBytes(final String className);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@code byte[]} representation of a class implementing
|
||||||
|
* the invoker forms for the set of supplied {@code methodTypes}.
|
||||||
|
*/
|
||||||
|
byte[] generateInvokersHolderClassBytes(String className,
|
||||||
|
MethodType[] methodTypes);
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,8 @@ public final class RSAPadding {
|
|||||||
public byte[] pad(byte[] data) throws BadPaddingException {
|
public byte[] pad(byte[] data) throws BadPaddingException {
|
||||||
if (data.length > maxDataSize) {
|
if (data.length > maxDataSize) {
|
||||||
throw new BadPaddingException("Data must be shorter than "
|
throw new BadPaddingException("Data must be shorter than "
|
||||||
+ (maxDataSize + 1) + " bytes");
|
+ (maxDataSize + 1) + " bytes but received "
|
||||||
|
+ data.length + " bytes.");
|
||||||
}
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PAD_NONE:
|
case PAD_NONE:
|
||||||
@ -281,7 +282,9 @@ public final class RSAPadding {
|
|||||||
*/
|
*/
|
||||||
public byte[] unpad(byte[] padded) throws BadPaddingException {
|
public byte[] unpad(byte[] padded) throws BadPaddingException {
|
||||||
if (padded.length != paddedSize) {
|
if (padded.length != paddedSize) {
|
||||||
throw new BadPaddingException("Decryption error");
|
throw new BadPaddingException("Decryption error." +
|
||||||
|
"The padded array length (" + padded.length +
|
||||||
|
") is not the specified padded size (" + paddedSize + ")");
|
||||||
}
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PAD_NONE:
|
case PAD_NONE:
|
||||||
|
@ -493,7 +493,9 @@ final class CipherBox {
|
|||||||
|
|
||||||
if (protocolVersion.useTLS11PlusSpec()) {
|
if (protocolVersion.useTLS11PlusSpec()) {
|
||||||
if (newLen < blockSize) {
|
if (newLen < blockSize) {
|
||||||
throw new BadPaddingException("invalid explicit IV");
|
throw new BadPaddingException("The length after " +
|
||||||
|
"padding removal (" + newLen + ") should be larger " +
|
||||||
|
"than <" + blockSize + "> since explicit IV used");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,7 +506,6 @@ final class CipherBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decrypts a block of data, returning the size of the
|
* Decrypts a block of data, returning the size of the
|
||||||
* resulting block if padding was required. position and limit
|
* resulting block if padding was required. position and limit
|
||||||
@ -575,7 +576,9 @@ final class CipherBox {
|
|||||||
// check the explicit IV of TLS v1.1 or later
|
// check the explicit IV of TLS v1.1 or later
|
||||||
if (protocolVersion.useTLS11PlusSpec()) {
|
if (protocolVersion.useTLS11PlusSpec()) {
|
||||||
if (newLen < blockSize) {
|
if (newLen < blockSize) {
|
||||||
throw new BadPaddingException("invalid explicit IV");
|
throw new BadPaddingException("The length after " +
|
||||||
|
"padding removal (" + newLen + ") should be larger " +
|
||||||
|
"than <" + blockSize + "> since explicit IV used");
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the position to the end of the decrypted data
|
// reset the position to the end of the decrypted data
|
||||||
@ -756,7 +759,9 @@ final class CipherBox {
|
|||||||
// so accept that as well
|
// so accept that as well
|
||||||
// v3 does not require any particular value for the other bytes
|
// v3 does not require any particular value for the other bytes
|
||||||
if (padLen > blockSize) {
|
if (padLen > blockSize) {
|
||||||
throw new BadPaddingException("Invalid SSLv3 padding");
|
throw new BadPaddingException("Padding length (" +
|
||||||
|
padLen + ") of SSLv3 message should not be bigger " +
|
||||||
|
"than the block size (" + blockSize + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newLen;
|
return newLen;
|
||||||
@ -802,7 +807,9 @@ final class CipherBox {
|
|||||||
// so accept that as well
|
// so accept that as well
|
||||||
// v3 does not require any particular value for the other bytes
|
// v3 does not require any particular value for the other bytes
|
||||||
if (padLen > blockSize) {
|
if (padLen > blockSize) {
|
||||||
throw new BadPaddingException("Invalid SSLv3 padding");
|
throw new BadPaddingException("Padding length (" +
|
||||||
|
padLen + ") of SSLv3 message should not be bigger " +
|
||||||
|
"than the block size (" + blockSize + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -925,7 +932,10 @@ final class CipherBox {
|
|||||||
case AEAD_CIPHER:
|
case AEAD_CIPHER:
|
||||||
if (bb.remaining() < (recordIvSize + tagSize)) {
|
if (bb.remaining() < (recordIvSize + tagSize)) {
|
||||||
throw new BadPaddingException(
|
throw new BadPaddingException(
|
||||||
"invalid AEAD cipher fragment");
|
"Insufficient buffer remaining for AEAD cipher " +
|
||||||
|
"fragment (" + bb.remaining() + "). Needs to be " +
|
||||||
|
"more than or equal to IV size (" + recordIvSize +
|
||||||
|
") + tag size (" + tagSize + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize the AEAD cipher for the unique IV
|
// initialize the AEAD cipher for the unique IV
|
||||||
|
@ -27,15 +27,8 @@ package sun.util.calendar;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.lang.ref.SoftReference;
|
|
||||||
import java.security.AccessController;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.SimpleTimeZone;
|
import java.util.SimpleTimeZone;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
@ -80,8 +73,6 @@ public class ZoneInfo extends TimeZone {
|
|||||||
private static final long ABBR_MASK = 0xf00L;
|
private static final long ABBR_MASK = 0xf00L;
|
||||||
private static final int TRANSITION_NSHIFT = 12;
|
private static final int TRANSITION_NSHIFT = 12;
|
||||||
|
|
||||||
private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The raw GMT offset in milliseconds between this zone and GMT.
|
* The raw GMT offset in milliseconds between this zone and GMT.
|
||||||
* Negative offsets are to the west of Greenwich. To obtain local
|
* Negative offsets are to the west of Greenwich. To obtain local
|
||||||
@ -379,6 +370,7 @@ public class ZoneInfo extends TimeZone {
|
|||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Gregorian gcal = CalendarSystem.getGregorianCalendar();
|
||||||
CalendarDate date = gcal.newCalendarDate(null);
|
CalendarDate date = gcal.newCalendarDate(null);
|
||||||
date.setDate(year, month + 1, day);
|
date.setDate(year, month + 1, day);
|
||||||
if (gcal.validate(date) == false) {
|
if (gcal.validate(date) == false) {
|
||||||
|
@ -490,7 +490,7 @@ networkaddress.cache.negative.ttl=10
|
|||||||
# property is set then those two properties are ignored.
|
# property is set then those two properties are ignored.
|
||||||
#
|
#
|
||||||
# Example,
|
# Example,
|
||||||
# ocsp.responderCertSubjectName="CN=OCSP Responder, O=XYZ Corp"
|
# ocsp.responderCertSubjectName=CN=OCSP Responder, O=XYZ Corp
|
||||||
|
|
||||||
#
|
#
|
||||||
# Issuer name of the OCSP responder's certificate
|
# Issuer name of the OCSP responder's certificate
|
||||||
@ -505,7 +505,7 @@ networkaddress.cache.negative.ttl=10
|
|||||||
# property is ignored.
|
# property is ignored.
|
||||||
#
|
#
|
||||||
# Example,
|
# Example,
|
||||||
# ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp"
|
# ocsp.responderCertIssuerName=CN=Enterprise CA, O=XYZ Corp
|
||||||
|
|
||||||
#
|
#
|
||||||
# Serial number of the OCSP responder's certificate
|
# Serial number of the OCSP responder's certificate
|
||||||
@ -803,3 +803,94 @@ jdk.tls.legacyAlgorithms= \
|
|||||||
# E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \
|
# E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \
|
||||||
# EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \
|
# EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \
|
||||||
# FFFFFFFF FFFFFFFF, 2}
|
# FFFFFFFF FFFFFFFF, 2}
|
||||||
|
|
||||||
|
# Cryptographic Jurisdiction Policy defaults
|
||||||
|
#
|
||||||
|
# Due to the import control restrictions of some countries, the default
|
||||||
|
# JCE policy files allow for strong but "limited" cryptographic key
|
||||||
|
# lengths to be used. If your country's cryptographic regulations allow,
|
||||||
|
# the "unlimited" strength policy files can be used instead, which contain
|
||||||
|
# no restrictions on cryptographic strengths.
|
||||||
|
#
|
||||||
|
# If your country has restrictions that don't fit either "limited" or
|
||||||
|
# "unlimited", an appropriate set of policy files should be created and
|
||||||
|
# configured before using this distribution. The jurisdiction policy file
|
||||||
|
# configuration must reflect the cryptographic restrictions appropriate
|
||||||
|
# for your country.
|
||||||
|
#
|
||||||
|
# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY
|
||||||
|
# TO DETERMINE THE EXACT REQUIREMENTS.
|
||||||
|
#
|
||||||
|
# The policy files are flat text files organized into subdirectories of
|
||||||
|
# <java-home>/conf/security/policy. Each directory contains a complete
|
||||||
|
# set of policy files.
|
||||||
|
#
|
||||||
|
# The "crypto.policy" Security property controls the directory selection,
|
||||||
|
# and thus the effective cryptographic policy.
|
||||||
|
#
|
||||||
|
# The default set of directories is:
|
||||||
|
#
|
||||||
|
# limited | unlimited
|
||||||
|
#
|
||||||
|
# however other directories can be created and configured.
|
||||||
|
#
|
||||||
|
# Within a directory, the effective policy is the combined minimum
|
||||||
|
# permissions of the grant statements in the file(s) with the filename
|
||||||
|
# pattern "default_*.policy". At least one grant is required. For
|
||||||
|
# example:
|
||||||
|
#
|
||||||
|
# limited = Export (all) + Import (limited) = Limited
|
||||||
|
# unlimited = Export (all) + Import (all) = Unlimited
|
||||||
|
#
|
||||||
|
# The effective exemption policy is the combined minimum permissions
|
||||||
|
# of the grant statements in the file(s) with the filename pattern
|
||||||
|
# "exempt_*.policy". Exemption grants are optional.
|
||||||
|
#
|
||||||
|
# limited = grants exemption permissions, by which the
|
||||||
|
# effective policy can be circumvented.
|
||||||
|
# e.g. KeyRecovery/Escrow/Weakening.
|
||||||
|
#
|
||||||
|
# Please see the JCA documentation for additional information on these
|
||||||
|
# files and formats.
|
||||||
|
crypto.policy=crypto.policydir-tbd
|
||||||
|
|
||||||
|
#
|
||||||
|
# The policy for the XML Signature secure validation mode. The mode is
|
||||||
|
# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to
|
||||||
|
# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method,
|
||||||
|
# or by running the code with a SecurityManager.
|
||||||
|
#
|
||||||
|
# Policy:
|
||||||
|
# Constraint {"," Constraint }
|
||||||
|
# Constraint:
|
||||||
|
# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint |
|
||||||
|
# ReferenceUriSchemeConstraint | OtherConstraint
|
||||||
|
# AlgConstraint
|
||||||
|
# "disallowAlg" Uri
|
||||||
|
# MaxTransformsConstraint:
|
||||||
|
# "maxTransforms" Integer
|
||||||
|
# MaxReferencesConstraint:
|
||||||
|
# "maxReferences" Integer
|
||||||
|
# ReferenceUriSchemeConstraint:
|
||||||
|
# "disallowReferenceUriSchemes" String { String }
|
||||||
|
# OtherConstraint:
|
||||||
|
# "noDuplicateIds" | "noRetrievalMethodLoops"
|
||||||
|
#
|
||||||
|
# For AlgConstraint, Uri is the algorithm URI String that is not allowed.
|
||||||
|
# See the XML Signature Recommendation for more information on algorithm
|
||||||
|
# URI Identifiers. If the MaxTransformsConstraint or MaxReferencesConstraint is
|
||||||
|
# specified more than once, only the last entry is enforced.
|
||||||
|
#
|
||||||
|
# Note: This property is currently used by the JDK Reference implementation. It
|
||||||
|
# is not guaranteed to be examined and used by other implementations.
|
||||||
|
#
|
||||||
|
jdk.xml.dsig.secureValidationPolicy=\
|
||||||
|
disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\
|
||||||
|
disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\
|
||||||
|
disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\
|
||||||
|
disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\
|
||||||
|
maxTransforms 5,\
|
||||||
|
maxReferences 30,\
|
||||||
|
disallowReferenceUriSchemes file http https,\
|
||||||
|
noDuplicateIds,\
|
||||||
|
noRetrievalMethodLoops
|
||||||
|
35
jdk/src/java.base/share/conf/security/policy/README.txt
Normal file
35
jdk/src/java.base/share/conf/security/policy/README.txt
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
Java(TM) Cryptography Extension Policy Files
|
||||||
|
for the Java(TM) Platform, Standard Edition Runtime Environment
|
||||||
|
|
||||||
|
README
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
The JCE architecture allows flexible cryptographic strength to be
|
||||||
|
configured via the jurisdiction policy files contained within these
|
||||||
|
directories.
|
||||||
|
|
||||||
|
Due to import control restrictions of some countries, the default
|
||||||
|
JCE policy files bundled in this Java Runtime Environment allow
|
||||||
|
for strong but "limited" cryptographic strengths. For convenience,
|
||||||
|
this build also contains the "unlimited strength" policy files which
|
||||||
|
contain no restrictions on cryptographic strengths, but they must be
|
||||||
|
specifically activated by updating the "crypto.policy" Security property
|
||||||
|
(e.g. <java-home>/conf/security/java.security) to point to the appropriate
|
||||||
|
directory.
|
||||||
|
|
||||||
|
Each subdirectory contains a complete policy configuration, and additional
|
||||||
|
subdirectories can be added/removed to reflect local regulations.
|
||||||
|
|
||||||
|
JCE for Java SE has been through the U.S. export review process. The JCE
|
||||||
|
framework, along with the various JCE providers that come standard with it
|
||||||
|
(SunJCE, SunEC, SunPKCS11, SunMSCAPI, etc), is exportable from the
|
||||||
|
United States.
|
||||||
|
|
||||||
|
You are advised to consult your export/import control counsel or attorney
|
||||||
|
to determine the exact requirements of your location, and what policy
|
||||||
|
settings should be used.
|
||||||
|
|
||||||
|
Please see The Java(TM) Cryptography Architecture (JCA) Reference
|
||||||
|
Guide and the java.security file for more information.
|
@ -1,4 +1,5 @@
|
|||||||
// Manufacturing policy file.
|
// Default US Export policy file.
|
||||||
|
|
||||||
grant {
|
grant {
|
||||||
// There is no restriction to any algorithms.
|
// There is no restriction to any algorithms.
|
||||||
permission javax.crypto.CryptoAllPermission;
|
permission javax.crypto.CryptoAllPermission;
|
@ -1,5 +1,5 @@
|
|||||||
// Some countries have import limits on crypto strength. So this file
|
// Some countries have import limits on crypto strength, but may allow for
|
||||||
// will be useful.
|
// these exemptions if the exemption mechanism is used.
|
||||||
|
|
||||||
grant {
|
grant {
|
||||||
// There is no restriction to any algorithms if KeyRecovery is enforced.
|
// There is no restriction to any algorithms if KeyRecovery is enforced.
|
@ -0,0 +1,6 @@
|
|||||||
|
// Default US Export policy file.
|
||||||
|
|
||||||
|
grant {
|
||||||
|
// There is no restriction to any algorithms.
|
||||||
|
permission javax.crypto.CryptoAllPermission;
|
||||||
|
};
|
@ -1,4 +1,5 @@
|
|||||||
// Country-specific policy file for countries with no limits on crypto strength.
|
// Country-specific policy file for countries with no limits on crypto strength.
|
||||||
|
|
||||||
grant {
|
grant {
|
||||||
// There is no restriction to any algorithms.
|
// There is no restriction to any algorithms.
|
||||||
permission javax.crypto.CryptoAllPermission;
|
permission javax.crypto.CryptoAllPermission;
|
@ -72,6 +72,8 @@ grant codeBase "jrt:/java.xml.crypto" {
|
|||||||
"removeProviderProperty.XMLDSig";
|
"removeProviderProperty.XMLDSig";
|
||||||
permission java.security.SecurityPermission
|
permission java.security.SecurityPermission
|
||||||
"com.sun.org.apache.xml.internal.security.register";
|
"com.sun.org.apache.xml.internal.security.register";
|
||||||
|
permission java.security.SecurityPermission
|
||||||
|
"getProperty.jdk.xml.dsig.secureValidationPolicy";
|
||||||
};
|
};
|
||||||
|
|
||||||
grant codeBase "jrt:/java.xml.ws" {
|
grant codeBase "jrt:/java.xml.ws" {
|
||||||
|
@ -252,6 +252,21 @@ class UnixPath implements Path {
|
|||||||
return new UnixPath(getFileSystem(), new byte[0]);
|
return new UnixPath(getFileSystem(), new byte[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return true if this path has "." or ".."
|
||||||
|
private boolean hasDotOrDotDot() {
|
||||||
|
int n = getNameCount();
|
||||||
|
for (int i=0; i<n; i++) {
|
||||||
|
byte[] bytes = getName(i).path;
|
||||||
|
if ((bytes.length == 1 && bytes[0] == '.'))
|
||||||
|
return true;
|
||||||
|
if ((bytes.length == 2 && bytes[0] == '.') && bytes[1] == '.') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UnixFileSystem getFileSystem() {
|
public UnixFileSystem getFileSystem() {
|
||||||
return fs;
|
return fs;
|
||||||
@ -405,80 +420,94 @@ class UnixPath implements Path {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UnixPath relativize(Path obj) {
|
public UnixPath relativize(Path obj) {
|
||||||
UnixPath other = toUnixPath(obj);
|
UnixPath child = toUnixPath(obj);
|
||||||
if (other.equals(this))
|
if (child.equals(this))
|
||||||
return emptyPath();
|
return emptyPath();
|
||||||
|
|
||||||
// can only relativize paths of the same type
|
// can only relativize paths of the same type
|
||||||
if (this.isAbsolute() != other.isAbsolute())
|
if (this.isAbsolute() != child.isAbsolute())
|
||||||
throw new IllegalArgumentException("'other' is different type of Path");
|
throw new IllegalArgumentException("'other' is different type of Path");
|
||||||
|
|
||||||
// this path is the empty path
|
// this path is the empty path
|
||||||
if (this.isEmpty())
|
if (this.isEmpty())
|
||||||
return other;
|
return child;
|
||||||
|
|
||||||
int bn = this.getNameCount();
|
UnixPath base = this;
|
||||||
int cn = other.getNameCount();
|
if (base.hasDotOrDotDot() || child.hasDotOrDotDot()) {
|
||||||
|
base = base.normalize();
|
||||||
|
child = child.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
int baseCount = base.getNameCount();
|
||||||
|
int childCount = child.getNameCount();
|
||||||
|
|
||||||
// skip matching names
|
// skip matching names
|
||||||
int n = (bn > cn) ? cn : bn;
|
int n = Math.min(baseCount, childCount);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < n) {
|
while (i < n) {
|
||||||
if (!this.getName(i).equals(other.getName(i)))
|
if (!base.getName(i).equals(child.getName(i)))
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dotdots = bn - i;
|
// remaining elements in child
|
||||||
if (i < cn) {
|
UnixPath childRemaining;
|
||||||
// remaining name components in other
|
boolean isChildEmpty;
|
||||||
UnixPath remainder = other.subpath(i, cn);
|
if (i == childCount) {
|
||||||
if (dotdots == 0)
|
childRemaining = emptyPath();
|
||||||
return remainder;
|
isChildEmpty = true;
|
||||||
|
|
||||||
// other is the empty path
|
|
||||||
boolean isOtherEmpty = other.isEmpty();
|
|
||||||
|
|
||||||
// result is a "../" for each remaining name in base
|
|
||||||
// followed by the remaining names in other. If the remainder is
|
|
||||||
// the empty path then we don't add the final trailing slash.
|
|
||||||
int len = dotdots*3 + remainder.path.length;
|
|
||||||
if (isOtherEmpty) {
|
|
||||||
assert remainder.isEmpty();
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
byte[] result = new byte[len];
|
|
||||||
int pos = 0;
|
|
||||||
while (dotdots > 0) {
|
|
||||||
result[pos++] = (byte)'.';
|
|
||||||
result[pos++] = (byte)'.';
|
|
||||||
if (isOtherEmpty) {
|
|
||||||
if (dotdots > 1) result[pos++] = (byte)'/';
|
|
||||||
} else {
|
|
||||||
result[pos++] = (byte)'/';
|
|
||||||
}
|
|
||||||
dotdots--;
|
|
||||||
}
|
|
||||||
System.arraycopy(remainder.path, 0, result, pos, remainder.path.length);
|
|
||||||
return new UnixPath(getFileSystem(), result);
|
|
||||||
} else {
|
} else {
|
||||||
// no remaining names in other so result is simply a sequence of ".."
|
childRemaining = child.subpath(i, childCount);
|
||||||
byte[] result = new byte[dotdots*3 - 1];
|
isChildEmpty = childRemaining.isEmpty();
|
||||||
int pos = 0;
|
|
||||||
while (dotdots > 0) {
|
|
||||||
result[pos++] = (byte)'.';
|
|
||||||
result[pos++] = (byte)'.';
|
|
||||||
// no tailing slash at the end
|
|
||||||
if (dotdots > 1)
|
|
||||||
result[pos++] = (byte)'/';
|
|
||||||
dotdots--;
|
|
||||||
}
|
|
||||||
return new UnixPath(getFileSystem(), result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// matched all of base
|
||||||
|
if (i == baseCount) {
|
||||||
|
return childRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the remainder of base cannot contain ".."
|
||||||
|
UnixPath baseRemaining = base.subpath(i, baseCount);
|
||||||
|
if (baseRemaining.hasDotOrDotDot()) {
|
||||||
|
throw new IllegalArgumentException("Unable to compute relative "
|
||||||
|
+ " path from " + this + " to " + obj);
|
||||||
|
}
|
||||||
|
if (baseRemaining.isEmpty())
|
||||||
|
return childRemaining;
|
||||||
|
|
||||||
|
// number of ".." needed
|
||||||
|
int dotdots = baseRemaining.getNameCount();
|
||||||
|
if (dotdots == 0) {
|
||||||
|
return childRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
// result is a "../" for each remaining name in base followed by the
|
||||||
|
// remaining names in child. If the remainder is the empty path
|
||||||
|
// then we don't add the final trailing slash.
|
||||||
|
int len = dotdots*3 + childRemaining.path.length;
|
||||||
|
if (isChildEmpty) {
|
||||||
|
assert childRemaining.isEmpty();
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
byte[] result = new byte[len];
|
||||||
|
int pos = 0;
|
||||||
|
while (dotdots > 0) {
|
||||||
|
result[pos++] = (byte)'.';
|
||||||
|
result[pos++] = (byte)'.';
|
||||||
|
if (isChildEmpty) {
|
||||||
|
if (dotdots > 1) result[pos++] = (byte)'/';
|
||||||
|
} else {
|
||||||
|
result[pos++] = (byte)'/';
|
||||||
|
}
|
||||||
|
dotdots--;
|
||||||
|
}
|
||||||
|
System.arraycopy(childRemaining.path,0, result, pos,
|
||||||
|
childRemaining.path.length);
|
||||||
|
return new UnixPath(getFileSystem(), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path normalize() {
|
public UnixPath normalize() {
|
||||||
final int count = getNameCount();
|
final int count = getNameCount();
|
||||||
if (count == 0 || isEmpty())
|
if (count == 0 || isEmpty())
|
||||||
return this;
|
return this;
|
||||||
|
@ -375,57 +375,108 @@ class WindowsPath implements Path {
|
|||||||
return (WindowsPath)path;
|
return (WindowsPath)path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return true if this path has "." or ".."
|
||||||
|
private boolean hasDotOrDotDot() {
|
||||||
|
int n = getNameCount();
|
||||||
|
for (int i=0; i<n; i++) {
|
||||||
|
String name = elementAsString(i);
|
||||||
|
if (name.length() == 1 && name.charAt(0) == '.')
|
||||||
|
return true;
|
||||||
|
if (name.length() == 2
|
||||||
|
&& name.charAt(0) == '.' && name.charAt(1) == '.')
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WindowsPath relativize(Path obj) {
|
public WindowsPath relativize(Path obj) {
|
||||||
WindowsPath other = toWindowsPath(obj);
|
WindowsPath child = toWindowsPath(obj);
|
||||||
if (this.equals(other))
|
if (this.equals(child))
|
||||||
return emptyPath();
|
return emptyPath();
|
||||||
|
|
||||||
// can only relativize paths of the same type
|
// can only relativize paths of the same type
|
||||||
if (this.type != other.type)
|
if (this.type != child.type)
|
||||||
throw new IllegalArgumentException("'other' is different type of Path");
|
throw new IllegalArgumentException("'other' is different type of Path");
|
||||||
|
|
||||||
// can only relativize paths if root component matches
|
// can only relativize paths if root component matches
|
||||||
if (!this.root.equalsIgnoreCase(other.root))
|
if (!this.root.equalsIgnoreCase(child.root))
|
||||||
throw new IllegalArgumentException("'other' has different root");
|
throw new IllegalArgumentException("'other' has different root");
|
||||||
|
|
||||||
// this path is the empty path
|
// this path is the empty path
|
||||||
if (this.isEmpty())
|
if (this.isEmpty())
|
||||||
return other;
|
return child;
|
||||||
|
|
||||||
int bn = this.getNameCount();
|
|
||||||
int cn = other.getNameCount();
|
WindowsPath base = this;
|
||||||
|
if (base.hasDotOrDotDot() || child.hasDotOrDotDot()) {
|
||||||
|
base = base.normalize();
|
||||||
|
child = child.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
int baseCount = base.getNameCount();
|
||||||
|
int childCount = child.getNameCount();
|
||||||
|
|
||||||
// skip matching names
|
// skip matching names
|
||||||
int n = (bn > cn) ? cn : bn;
|
int n = Math.min(baseCount, childCount);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < n) {
|
while (i < n) {
|
||||||
if (!this.getName(i).equals(other.getName(i)))
|
if (!base.getName(i).equals(child.getName(i)))
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// append ..\ for remaining names in the base
|
// remaining elements in child
|
||||||
|
WindowsPath childRemaining;
|
||||||
|
boolean isChildEmpty;
|
||||||
|
if (i == childCount) {
|
||||||
|
childRemaining = emptyPath();
|
||||||
|
isChildEmpty = true;
|
||||||
|
} else {
|
||||||
|
childRemaining = child.subpath(i, childCount);
|
||||||
|
isChildEmpty = childRemaining.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// matched all of base
|
||||||
|
if (i == baseCount) {
|
||||||
|
return childRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the remainder of base cannot contain ".."
|
||||||
|
WindowsPath baseRemaining = base.subpath(i, baseCount);
|
||||||
|
if (baseRemaining.hasDotOrDotDot()) {
|
||||||
|
throw new IllegalArgumentException("Unable to compute relative "
|
||||||
|
+ " path from " + this + " to " + obj);
|
||||||
|
}
|
||||||
|
if (baseRemaining.isEmpty())
|
||||||
|
return childRemaining;
|
||||||
|
|
||||||
|
// number of ".." needed
|
||||||
|
int dotdots = baseRemaining.getNameCount();
|
||||||
|
if (dotdots == 0) {
|
||||||
|
return childRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
for (int j=i; j<bn; j++) {
|
for (int j=0; j<dotdots; j++) {
|
||||||
result.append("..\\");
|
result.append("..\\");
|
||||||
}
|
}
|
||||||
|
|
||||||
// append remaining names in child
|
// append remaining names in child
|
||||||
if (!other.isEmpty()) {
|
if (!isChildEmpty) {
|
||||||
for (int j=i; j<cn; j++) {
|
for (int j=0; j<childRemaining.getNameCount(); j++) {
|
||||||
result.append(other.getName(j).toString());
|
result.append(childRemaining.getName(j).toString());
|
||||||
result.append("\\");
|
result.append("\\");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop trailing slash in result
|
// drop trailing slash
|
||||||
result.setLength(result.length()-1);
|
result.setLength(result.length()-1);
|
||||||
return createFromNormalizedPath(getFileSystem(), result.toString());
|
return createFromNormalizedPath(getFileSystem(), result.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path normalize() {
|
public WindowsPath normalize() {
|
||||||
final int count = getNameCount();
|
final int count = getNameCount();
|
||||||
if (count == 0 || isEmpty())
|
if (count == 0 || isEmpty())
|
||||||
return this;
|
return this;
|
||||||
|
@ -390,35 +390,27 @@ public final class KdcComm {
|
|||||||
|
|
||||||
for (int i=1; i <= retries; i++) {
|
for (int i=1; i <= retries; i++) {
|
||||||
String proto = useTCP?"TCP":"UDP";
|
String proto = useTCP?"TCP":"UDP";
|
||||||
try (NetClient kdcClient = NetClient.getInstance(
|
if (DEBUG) {
|
||||||
proto, kdc, port, timeout)) {
|
System.out.println(">>> KDCCommunication: kdc=" + kdc
|
||||||
if (DEBUG) {
|
|
||||||
System.out.println(">>> KDCCommunication: kdc=" + kdc
|
|
||||||
+ " " + proto + ":"
|
+ " " + proto + ":"
|
||||||
+ port + ", timeout="
|
+ port + ", timeout="
|
||||||
+ timeout
|
+ timeout
|
||||||
+ ",Attempt =" + i
|
+ ",Attempt =" + i
|
||||||
+ ", #bytes=" + obuf.length);
|
+ ", #bytes=" + obuf.length);
|
||||||
|
}
|
||||||
|
try (NetClient kdcClient = NetClient.getInstance(
|
||||||
|
proto, kdc, port, timeout)) {
|
||||||
|
kdcClient.send(obuf);
|
||||||
|
ibuf = kdcClient.receive();
|
||||||
|
break;
|
||||||
|
} catch (SocketTimeoutException se) {
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println ("SocketTimeOutException with " +
|
||||||
|
"attempt: " + i);
|
||||||
}
|
}
|
||||||
try {
|
if (i == retries) {
|
||||||
/*
|
ibuf = null;
|
||||||
* Send the data to the kdc.
|
throw se;
|
||||||
*/
|
|
||||||
kdcClient.send(obuf);
|
|
||||||
/*
|
|
||||||
* And get a response.
|
|
||||||
*/
|
|
||||||
ibuf = kdcClient.receive();
|
|
||||||
break;
|
|
||||||
} catch (SocketTimeoutException se) {
|
|
||||||
if (DEBUG) {
|
|
||||||
System.out.println ("SocketTimeOutException with " +
|
|
||||||
"attempt: " + i);
|
|
||||||
}
|
|
||||||
if (i == retries) {
|
|
||||||
ibuf = null;
|
|
||||||
throw se;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -3204,7 +3204,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setNull(String parameterName, int sqlType) throws SQLException {
|
public void setNull(String parameterName, int sqlType) throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3240,7 +3239,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setNull (String parameterName, int sqlType, String typeName)
|
public void setNull (String parameterName, int sqlType, String typeName)
|
||||||
throws SQLException{
|
throws SQLException{
|
||||||
@ -3259,7 +3257,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setBoolean(String parameterName, boolean x) throws SQLException{
|
public void setBoolean(String parameterName, boolean x) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3277,7 +3274,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setByte(String parameterName, byte x) throws SQLException{
|
public void setByte(String parameterName, byte x) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3295,7 +3291,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setShort(String parameterName, short x) throws SQLException{
|
public void setShort(String parameterName, short x) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3313,7 +3308,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setInt(String parameterName, int x) throws SQLException{
|
public void setInt(String parameterName, int x) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3332,7 +3326,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setLong(String parameterName, long x) throws SQLException{
|
public void setLong(String parameterName, long x) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3350,7 +3343,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setFloat(String parameterName, float x) throws SQLException{
|
public void setFloat(String parameterName, float x) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3368,7 +3360,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setDouble(String parameterName, double x) throws SQLException{
|
public void setDouble(String parameterName, double x) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3387,7 +3378,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{
|
public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3408,7 +3398,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setString(String parameterName, String x) throws SQLException{
|
public void setString(String parameterName, String x) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3428,7 +3417,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setBytes(String parameterName, byte x[]) throws SQLException{
|
public void setBytes(String parameterName, byte x[]) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -3447,7 +3435,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setTimestamp(String parameterName, java.sql.Timestamp x)
|
public void setTimestamp(String parameterName, java.sql.Timestamp x)
|
||||||
throws SQLException{
|
throws SQLException{
|
||||||
@ -3474,7 +3461,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setAsciiStream(String parameterName, java.io.InputStream x, int length)
|
public void setAsciiStream(String parameterName, java.io.InputStream x, int length)
|
||||||
throws SQLException{
|
throws SQLException{
|
||||||
@ -3500,7 +3486,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setBinaryStream(String parameterName, java.io.InputStream x,
|
public void setBinaryStream(String parameterName, java.io.InputStream x,
|
||||||
int length) throws SQLException{
|
int length) throws SQLException{
|
||||||
@ -3528,7 +3513,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setCharacterStream(String parameterName,
|
public void setCharacterStream(String parameterName,
|
||||||
java.io.Reader reader,
|
java.io.Reader reader,
|
||||||
@ -3684,7 +3668,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* this data type
|
* this data type
|
||||||
* @see Types
|
* @see Types
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setObject(String parameterName, Object x, int targetSqlType, int scale)
|
public void setObject(String parameterName, Object x, int targetSqlType, int scale)
|
||||||
throws SQLException{
|
throws SQLException{
|
||||||
@ -3710,7 +3693,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* or <code>STRUCT</code> data type and the JDBC driver does not support
|
* or <code>STRUCT</code> data type and the JDBC driver does not support
|
||||||
* this data type
|
* this data type
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setObject(String parameterName, Object x, int targetSqlType)
|
public void setObject(String parameterName, Object x, int targetSqlType)
|
||||||
throws SQLException{
|
throws SQLException{
|
||||||
@ -3751,7 +3733,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setObject(String parameterName, Object x) throws SQLException{
|
public void setObject(String parameterName, Object x) throws SQLException{
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
@ -4024,7 +4005,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setDate(String parameterName, java.sql.Date x)
|
public void setDate(String parameterName, java.sql.Date x)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
@ -4050,7 +4030,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setDate(String parameterName, java.sql.Date x, Calendar cal)
|
public void setDate(String parameterName, java.sql.Date x, Calendar cal)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
@ -4069,7 +4048,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setTime(String parameterName, java.sql.Time x)
|
public void setTime(String parameterName, java.sql.Time x)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
@ -4095,7 +4073,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setTime(String parameterName, java.sql.Time x, Calendar cal)
|
public void setTime(String parameterName, java.sql.Time x, Calendar cal)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
@ -4121,7 +4098,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getParams
|
* @see #getParams
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)
|
public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
@ -4459,7 +4435,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
|||||||
* @exception SQLException if a database access error occurs or
|
* @exception SQLException if a database access error occurs or
|
||||||
* this method is called on a closed <code>PreparedStatement</code>
|
* this method is called on a closed <code>PreparedStatement</code>
|
||||||
* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
|
* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
public void setURL(int parameterIndex, java.net.URL x) throws SQLException {
|
public void setURL(int parameterIndex, java.net.URL x) throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||||
|
@ -57,7 +57,6 @@ public interface CommonDataSource {
|
|||||||
* logging is disabled
|
* logging is disabled
|
||||||
* @exception java.sql.SQLException if a database access error occurs
|
* @exception java.sql.SQLException if a database access error occurs
|
||||||
* @see #setLogWriter
|
* @see #setLogWriter
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
java.io.PrintWriter getLogWriter() throws SQLException;
|
java.io.PrintWriter getLogWriter() throws SQLException;
|
||||||
|
|
||||||
@ -79,7 +78,6 @@ public interface CommonDataSource {
|
|||||||
* @param out the new log writer; to disable logging, set to null
|
* @param out the new log writer; to disable logging, set to null
|
||||||
* @exception SQLException if a database access error occurs
|
* @exception SQLException if a database access error occurs
|
||||||
* @see #getLogWriter
|
* @see #getLogWriter
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
void setLogWriter(java.io.PrintWriter out) throws SQLException;
|
void setLogWriter(java.io.PrintWriter out) throws SQLException;
|
||||||
|
|
||||||
@ -94,7 +92,6 @@ public interface CommonDataSource {
|
|||||||
* @param seconds the data source login time limit
|
* @param seconds the data source login time limit
|
||||||
* @exception SQLException if a database access error occurs.
|
* @exception SQLException if a database access error occurs.
|
||||||
* @see #getLoginTimeout
|
* @see #getLoginTimeout
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
void setLoginTimeout(int seconds) throws SQLException;
|
void setLoginTimeout(int seconds) throws SQLException;
|
||||||
|
|
||||||
@ -109,7 +106,6 @@ public interface CommonDataSource {
|
|||||||
* @return the data source login time limit
|
* @return the data source login time limit
|
||||||
* @exception SQLException if a database access error occurs.
|
* @exception SQLException if a database access error occurs.
|
||||||
* @see #setLoginTimeout
|
* @see #setLoginTimeout
|
||||||
* @since 1.4
|
|
||||||
*/
|
*/
|
||||||
int getLoginTimeout() throws SQLException;
|
int getLoginTimeout() throws SQLException;
|
||||||
|
|
||||||
|
@ -72,6 +72,34 @@ public interface ConnectionPoolDataSource extends CommonDataSource {
|
|||||||
PooledConnection getPooledConnection(String user, String password)
|
PooledConnection getPooledConnection(String user, String password)
|
||||||
throws SQLException;
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
java.io.PrintWriter getLogWriter() throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void setLogWriter(java.io.PrintWriter out) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void setLoginTimeout(int seconds) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
int getLoginTimeout() throws SQLException;
|
||||||
|
|
||||||
//------------------------- JDBC 4.3 -----------------------------------
|
//------------------------- JDBC 4.3 -----------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,6 +109,34 @@ public interface DataSource extends CommonDataSource, Wrapper {
|
|||||||
Connection getConnection(String username, String password)
|
Connection getConnection(String username, String password)
|
||||||
throws SQLException;
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
java.io.PrintWriter getLogWriter() throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void setLogWriter(java.io.PrintWriter out) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void setLoginTimeout(int seconds) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
int getLoginTimeout() throws SQLException;
|
||||||
|
|
||||||
// JDBC 4.3
|
// JDBC 4.3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,7 +81,35 @@ public interface XADataSource extends CommonDataSource {
|
|||||||
XAConnection getXAConnection(String user, String password)
|
XAConnection getXAConnection(String user, String password)
|
||||||
throws SQLException;
|
throws SQLException;
|
||||||
|
|
||||||
// JDBC 4.3
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
java.io.PrintWriter getLogWriter() throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void setLogWriter(java.io.PrintWriter out) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void setLoginTimeout(int seconds) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
int getLoginTimeout() throws SQLException;
|
||||||
|
|
||||||
|
// JDBC 4.3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@code XAConnectionBuilder} instance
|
* Creates a new {@code XAConnectionBuilder} instance
|
||||||
|
@ -150,7 +150,7 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi {
|
|||||||
this.macAlgorithm.init(secretKey);
|
this.macAlgorithm.init(secretKey);
|
||||||
} catch (InvalidKeyException ex) {
|
} catch (InvalidKeyException ex) {
|
||||||
// reinstantiate Mac object to work around bug in JDK
|
// reinstantiate Mac object to work around bug in JDK
|
||||||
// see: http://bugs.sun.com/view_bug.do?bug_id=4953555
|
// see: http://bugs.java.com/view_bug.do?bug_id=4953555
|
||||||
Mac mac = this.macAlgorithm;
|
Mac mac = this.macAlgorithm;
|
||||||
try {
|
try {
|
||||||
this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm());
|
this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm());
|
||||||
|
@ -112,7 +112,7 @@ public abstract class SignatureBaseRSA extends SignatureAlgorithmSpi {
|
|||||||
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
|
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
|
||||||
} catch (InvalidKeyException ex) {
|
} catch (InvalidKeyException ex) {
|
||||||
// reinstantiate Signature object to work around bug in JDK
|
// reinstantiate Signature object to work around bug in JDK
|
||||||
// see: http://bugs.sun.com/view_bug.do?bug_id=4953555
|
// see: http://bugs.java.com/view_bug.do?bug_id=4953555
|
||||||
Signature sig = this.signatureAlgorithm;
|
Signature sig = this.signatureAlgorithm;
|
||||||
try {
|
try {
|
||||||
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
|
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
|
||||||
|
@ -139,7 +139,7 @@ public class SignatureDSA extends SignatureAlgorithmSpi {
|
|||||||
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
|
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
|
||||||
} catch (InvalidKeyException ex) {
|
} catch (InvalidKeyException ex) {
|
||||||
// reinstantiate Signature object to work around bug in JDK
|
// reinstantiate Signature object to work around bug in JDK
|
||||||
// see: http://bugs.sun.com/view_bug.do?bug_id=4953555
|
// see: http://bugs.java.com/view_bug.do?bug_id=4953555
|
||||||
Signature sig = this.signatureAlgorithm;
|
Signature sig = this.signatureAlgorithm;
|
||||||
try {
|
try {
|
||||||
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
|
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
|
||||||
|
@ -252,7 +252,7 @@ public abstract class SignatureECDSA extends SignatureAlgorithmSpi {
|
|||||||
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
|
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
|
||||||
} catch (InvalidKeyException ex) {
|
} catch (InvalidKeyException ex) {
|
||||||
// reinstantiate Signature object to work around bug in JDK
|
// reinstantiate Signature object to work around bug in JDK
|
||||||
// see: http://bugs.sun.com/view_bug.do?bug_id=4953555
|
// see: http://bugs.java.com/view_bug.do?bug_id=4953555
|
||||||
Signature sig = this.signatureAlgorithm;
|
Signature sig = this.signatureAlgorithm;
|
||||||
try {
|
try {
|
||||||
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
|
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* $Id: ApacheTransform.java 1333869 2012-05-04 10:42:44Z coheigea $
|
* $Id: ApacheTransform.java 1333869 2012-05-04 10:42:44Z coheigea $
|
||||||
@ -38,7 +38,6 @@ import org.w3c.dom.Node;
|
|||||||
|
|
||||||
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
|
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
|
||||||
import com.sun.org.apache.xml.internal.security.transforms.Transform;
|
import com.sun.org.apache.xml.internal.security.transforms.Transform;
|
||||||
import com.sun.org.apache.xml.internal.security.transforms.Transforms;
|
|
||||||
|
|
||||||
import javax.xml.crypto.*;
|
import javax.xml.crypto.*;
|
||||||
import javax.xml.crypto.dom.DOMCryptoContext;
|
import javax.xml.crypto.dom.DOMCryptoContext;
|
||||||
@ -150,7 +149,7 @@ public abstract class ApacheTransform extends TransformService {
|
|||||||
|
|
||||||
if (Utils.secureValidation(xc)) {
|
if (Utils.secureValidation(xc)) {
|
||||||
String algorithm = getAlgorithm();
|
String algorithm = getAlgorithm();
|
||||||
if (Transforms.TRANSFORM_XSLT.equals(algorithm)) {
|
if (Policy.restrictAlg(algorithm)) {
|
||||||
throw new TransformException(
|
throw new TransformException(
|
||||||
"Transform " + algorithm + " is forbidden when secure validation is enabled"
|
"Transform " + algorithm + " is forbidden when secure validation is enabled"
|
||||||
);
|
);
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* $Id: DOMManifest.java 1333415 2012-05-03 12:03:51Z coheigea $
|
* $Id: DOMManifest.java 1333415 2012-05-03 12:03:51Z coheigea $
|
||||||
@ -110,9 +110,10 @@ public final class DOMManifest extends DOMStructure implements Manifest {
|
|||||||
localName + ", expected Reference");
|
localName + ", expected Reference");
|
||||||
}
|
}
|
||||||
refs.add(new DOMReference(refElem, context, provider));
|
refs.add(new DOMReference(refElem, context, provider));
|
||||||
if (secVal && (refs.size() > DOMSignedInfo.MAXIMUM_REFERENCE_COUNT)) {
|
if (secVal && Policy.restrictNumReferences(refs.size())) {
|
||||||
String error = "A maxiumum of " + DOMSignedInfo.MAXIMUM_REFERENCE_COUNT + " "
|
String error = "A maximum of " + Policy.maxReferences()
|
||||||
+ "references per Manifest are allowed with secure validation";
|
+ " references per Manifest are allowed when"
|
||||||
|
+ " secure validation is enabled";
|
||||||
throw new MarshalException(error);
|
throw new MarshalException(error);
|
||||||
}
|
}
|
||||||
refElem = DOMUtils.getNextSiblingElement(refElem);
|
refElem = DOMUtils.getNextSiblingElement(refElem);
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* ===========================================================================
|
* ===========================================================================
|
||||||
@ -51,7 +51,6 @@ import org.w3c.dom.Element;
|
|||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
import org.jcp.xml.dsig.internal.DigesterOutputStream;
|
import org.jcp.xml.dsig.internal.DigesterOutputStream;
|
||||||
import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm;
|
|
||||||
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
|
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
|
||||||
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
|
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
|
||||||
import com.sun.org.apache.xml.internal.security.utils.Base64;
|
import com.sun.org.apache.xml.internal.security.utils.Base64;
|
||||||
@ -66,11 +65,6 @@ import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream
|
|||||||
public final class DOMReference extends DOMStructure
|
public final class DOMReference extends DOMStructure
|
||||||
implements Reference, DOMURIReference {
|
implements Reference, DOMURIReference {
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of transforms per reference, if secure validation is enabled.
|
|
||||||
*/
|
|
||||||
public static final int MAXIMUM_TRANSFORM_COUNT = 5;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up useC14N11 system property. If true, an explicit C14N11 transform
|
* Look up useC14N11 system property. If true, an explicit C14N11 transform
|
||||||
* will be added if necessary when generating the signature. See section
|
* will be added if necessary when generating the signature. See section
|
||||||
@ -208,9 +202,10 @@ public final class DOMReference extends DOMStructure
|
|||||||
}
|
}
|
||||||
transforms.add
|
transforms.add
|
||||||
(new DOMTransform(transformElem, context, provider));
|
(new DOMTransform(transformElem, context, provider));
|
||||||
if (secVal && (transforms.size() > MAXIMUM_TRANSFORM_COUNT)) {
|
if (secVal && Policy.restrictNumTransforms(transforms.size())) {
|
||||||
String error = "A maxiumum of " + MAXIMUM_TRANSFORM_COUNT + " "
|
String error = "A maximum of " + Policy.maxTransforms()
|
||||||
+ "transforms per Reference are allowed with secure validation";
|
+ " transforms per Reference are allowed when"
|
||||||
|
+ " secure validation is enabled";
|
||||||
throw new MarshalException(error);
|
throw new MarshalException(error);
|
||||||
}
|
}
|
||||||
transformElem = DOMUtils.getNextSiblingElement(transformElem);
|
transformElem = DOMUtils.getNextSiblingElement(transformElem);
|
||||||
@ -227,10 +222,10 @@ public final class DOMReference extends DOMStructure
|
|||||||
Element dmElem = nextSibling;
|
Element dmElem = nextSibling;
|
||||||
this.digestMethod = DOMDigestMethod.unmarshal(dmElem);
|
this.digestMethod = DOMDigestMethod.unmarshal(dmElem);
|
||||||
String digestMethodAlgorithm = this.digestMethod.getAlgorithm();
|
String digestMethodAlgorithm = this.digestMethod.getAlgorithm();
|
||||||
if (secVal
|
if (secVal && Policy.restrictAlg(digestMethodAlgorithm)) {
|
||||||
&& MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5.equals(digestMethodAlgorithm)) {
|
|
||||||
throw new MarshalException(
|
throw new MarshalException(
|
||||||
"It is forbidden to use algorithm " + digestMethod + " when secure validation is enabled"
|
"It is forbidden to use algorithm " + digestMethodAlgorithm +
|
||||||
|
" when secure validation is enabled"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* ===========================================================================
|
* ===========================================================================
|
||||||
@ -149,9 +149,10 @@ public final class DOMRetrievalMethod extends DOMStructure
|
|||||||
}
|
}
|
||||||
transforms.add
|
transforms.add
|
||||||
(new DOMTransform(transformElem, context, provider));
|
(new DOMTransform(transformElem, context, provider));
|
||||||
if (secVal && (transforms.size() > DOMReference.MAXIMUM_TRANSFORM_COUNT)) {
|
if (secVal && Policy.restrictNumTransforms(transforms.size())) {
|
||||||
String error = "A maxiumum of " + DOMReference.MAXIMUM_TRANSFORM_COUNT + " "
|
String error = "A maximum of " + Policy.maxTransforms()
|
||||||
+ "transforms per Reference are allowed with secure validation";
|
+ " transforms per Reference are allowed when"
|
||||||
|
+ " secure validation is enabled";
|
||||||
throw new MarshalException(error);
|
throw new MarshalException(error);
|
||||||
}
|
}
|
||||||
transformElem = DOMUtils.getNextSiblingElement(transformElem);
|
transformElem = DOMUtils.getNextSiblingElement(transformElem);
|
||||||
@ -238,7 +239,8 @@ public final class DOMRetrievalMethod extends DOMStructure
|
|||||||
}
|
}
|
||||||
|
|
||||||
// guard against RetrievalMethod loops
|
// guard against RetrievalMethod loops
|
||||||
if ((data instanceof NodeSetData) && Utils.secureValidation(context)) {
|
if ((data instanceof NodeSetData) && Utils.secureValidation(context)
|
||||||
|
&& Policy.restrictRetrievalMethodLoops()) {
|
||||||
NodeSetData<?> nsd = (NodeSetData<?>)data;
|
NodeSetData<?> nsd = (NodeSetData<?>)data;
|
||||||
Iterator<?> i = nsd.iterator();
|
Iterator<?> i = nsd.iterator();
|
||||||
if (i.hasNext()) {
|
if (i.hasNext()) {
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* $Id: DOMSignedInfo.java 1333415 2012-05-03 12:03:51Z coheigea $
|
* $Id: DOMSignedInfo.java 1333415 2012-05-03 12:03:51Z coheigea $
|
||||||
@ -45,7 +45,6 @@ import org.w3c.dom.Element;
|
|||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
import com.sun.org.apache.xml.internal.security.utils.Base64;
|
import com.sun.org.apache.xml.internal.security.utils.Base64;
|
||||||
import com.sun.org.apache.xml.internal.security.utils.Constants;
|
|
||||||
import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
|
import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,22 +54,9 @@ import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream
|
|||||||
*/
|
*/
|
||||||
public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
|
public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of references per Manifest, if secure validation is enabled.
|
|
||||||
*/
|
|
||||||
public static final int MAXIMUM_REFERENCE_COUNT = 30;
|
|
||||||
|
|
||||||
private static java.util.logging.Logger log =
|
private static java.util.logging.Logger log =
|
||||||
java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
|
java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
|
||||||
|
|
||||||
/** Signature - NOT Recommended RSAwithMD5 */
|
|
||||||
private static final String ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5 =
|
|
||||||
Constants.MoreAlgorithmsSpecNS + "rsa-md5";
|
|
||||||
|
|
||||||
/** HMAC - NOT Recommended HMAC-MD5 */
|
|
||||||
private static final String ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5 =
|
|
||||||
Constants.MoreAlgorithmsSpecNS + "hmac-md5";
|
|
||||||
|
|
||||||
private List<Reference> references;
|
private List<Reference> references;
|
||||||
private CanonicalizationMethod canonicalizationMethod;
|
private CanonicalizationMethod canonicalizationMethod;
|
||||||
private SignatureMethod signatureMethod;
|
private SignatureMethod signatureMethod;
|
||||||
@ -158,10 +144,10 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
|
|||||||
boolean secVal = Utils.secureValidation(context);
|
boolean secVal = Utils.secureValidation(context);
|
||||||
|
|
||||||
String signatureMethodAlgorithm = signatureMethod.getAlgorithm();
|
String signatureMethodAlgorithm = signatureMethod.getAlgorithm();
|
||||||
if (secVal && ((ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5.equals(signatureMethodAlgorithm)
|
if (secVal && Policy.restrictAlg(signatureMethodAlgorithm)) {
|
||||||
|| ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5.equals(signatureMethodAlgorithm)))) {
|
|
||||||
throw new MarshalException(
|
throw new MarshalException(
|
||||||
"It is forbidden to use algorithm " + signatureMethod + " when secure validation is enabled"
|
"It is forbidden to use algorithm " + signatureMethodAlgorithm +
|
||||||
|
" when secure validation is enabled"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,9 +165,10 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
|
|||||||
}
|
}
|
||||||
refList.add(new DOMReference(refElem, context, provider));
|
refList.add(new DOMReference(refElem, context, provider));
|
||||||
|
|
||||||
if (secVal && (refList.size() > MAXIMUM_REFERENCE_COUNT)) {
|
if (secVal && Policy.restrictNumReferences(refList.size())) {
|
||||||
String error = "A maxiumum of " + MAXIMUM_REFERENCE_COUNT + " "
|
String error = "A maximum of " + Policy.maxReferences()
|
||||||
+ "references per Manifest are allowed with secure validation";
|
+ " references per Manifest are allowed when"
|
||||||
|
+ " secure validation is enabled";
|
||||||
throw new MarshalException(error);
|
throw new MarshalException(error);
|
||||||
}
|
}
|
||||||
refElem = DOMUtils.getNextSiblingElement(refElem);
|
refElem = DOMUtils.getNextSiblingElement(refElem);
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* $Id: DOMURIDereferencer.java 1231033 2012-01-13 12:12:12Z coheigea $
|
* $Id: DOMURIDereferencer.java 1231033 2012-01-13 12:12:12Z coheigea $
|
||||||
@ -73,6 +73,11 @@ public class DOMURIDereferencer implements URIDereferencer {
|
|||||||
|
|
||||||
boolean secVal = Utils.secureValidation(context);
|
boolean secVal = Utils.secureValidation(context);
|
||||||
|
|
||||||
|
if (secVal && Policy.restrictReferenceUriScheme(uri)) {
|
||||||
|
throw new URIReferenceException(
|
||||||
|
"Uri " + uri + " is forbidden when secure validation is enabled");
|
||||||
|
}
|
||||||
|
|
||||||
// Check if same-document URI and already registered on the context
|
// Check if same-document URI and already registered on the context
|
||||||
if (uri != null && uri.length() != 0 && uri.charAt(0) == '#') {
|
if (uri != null && uri.length() != 0 && uri.charAt(0) == '#') {
|
||||||
String id = uri.substring(1);
|
String id = uri.substring(1);
|
||||||
@ -83,12 +88,19 @@ public class DOMURIDereferencer implements URIDereferencer {
|
|||||||
id = id.substring(i1+1, i2);
|
id = id.substring(i1+1, i2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node referencedElem = dcc.getElementById(id);
|
// check if element is registered by Id
|
||||||
|
Node referencedElem = uriAttr.getOwnerDocument().getElementById(id);
|
||||||
|
if (referencedElem == null) {
|
||||||
|
// see if element is registered in DOMCryptoContext
|
||||||
|
referencedElem = dcc.getElementById(id);
|
||||||
|
}
|
||||||
if (referencedElem != null) {
|
if (referencedElem != null) {
|
||||||
if (secVal) {
|
if (secVal && Policy.restrictDuplicateIds()) {
|
||||||
Element start = referencedElem.getOwnerDocument().getDocumentElement();
|
Element start = referencedElem.getOwnerDocument().getDocumentElement();
|
||||||
if (!XMLUtils.protectAgainstWrappingAttack(start, (Element)referencedElem, id)) {
|
if (!XMLUtils.protectAgainstWrappingAttack(start, (Element)referencedElem, id)) {
|
||||||
String error = "Multiple Elements with the same ID " + id + " were detected";
|
String error = "Multiple Elements with the same ID "
|
||||||
|
+ id + " detected when secure validation"
|
||||||
|
+ " is enabled";
|
||||||
throw new URIReferenceException(error);
|
throw new URIReferenceException(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,9 +122,9 @@ public class DOMURIDereferencer implements URIDereferencer {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
ResourceResolver apacheResolver =
|
ResourceResolver apacheResolver =
|
||||||
ResourceResolver.getInstance(uriAttr, baseURI, secVal);
|
ResourceResolver.getInstance(uriAttr, baseURI, false);
|
||||||
XMLSignatureInput in = apacheResolver.resolve(uriAttr,
|
XMLSignatureInput in = apacheResolver.resolve(uriAttr,
|
||||||
baseURI, secVal);
|
baseURI, false);
|
||||||
if (in.isOctetStream()) {
|
if (in.isOctetStream()) {
|
||||||
return new ApacheOctetStreamData(in);
|
return new ApacheOctetStreamData(in);
|
||||||
} else {
|
} else {
|
||||||
|
@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.jcp.xml.dsig.internal.dom;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
|
import java.security.Security;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The secure validation policy as specified by the
|
||||||
|
* jdk.xml.dsig.secureValidationPolicy security property.
|
||||||
|
*/
|
||||||
|
public final class Policy {
|
||||||
|
|
||||||
|
// all restrictions are initialized to be unconstrained
|
||||||
|
private static Set<URI> disallowedAlgs = new HashSet<>();
|
||||||
|
private static int maxTrans = Integer.MAX_VALUE;
|
||||||
|
private static int maxRefs = Integer.MAX_VALUE;
|
||||||
|
private static Set<String> disallowedRefUriSchemes = new HashSet<>();
|
||||||
|
private static boolean noDuplicateIds = false;
|
||||||
|
private static boolean noRMLoops = false;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
initialize();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SecurityException(
|
||||||
|
"Cannot initialize the secure validation policy", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Policy() {}
|
||||||
|
|
||||||
|
private static void initialize() {
|
||||||
|
String prop =
|
||||||
|
AccessController.doPrivileged((PrivilegedAction<String>) () ->
|
||||||
|
Security.getProperty("jdk.xml.dsig.secureValidationPolicy"));
|
||||||
|
if (prop == null || prop.isEmpty()) {
|
||||||
|
// no policy specified, so don't enforce any restrictions
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String[] entries = prop.split(",");
|
||||||
|
for (String entry : entries) {
|
||||||
|
String[] tokens = entry.split("\\s");
|
||||||
|
String type = tokens[0];
|
||||||
|
switch(type) {
|
||||||
|
case "disallowAlg":
|
||||||
|
if (tokens.length != 2) {
|
||||||
|
error(entry);
|
||||||
|
}
|
||||||
|
disallowedAlgs.add(URI.create(tokens[1]));
|
||||||
|
break;
|
||||||
|
case "maxTransforms":
|
||||||
|
if (tokens.length != 2) {
|
||||||
|
error(entry);
|
||||||
|
}
|
||||||
|
maxTrans = Integer.parseUnsignedInt(tokens[1]);
|
||||||
|
break;
|
||||||
|
case "maxReferences":
|
||||||
|
if (tokens.length != 2) {
|
||||||
|
error(entry);
|
||||||
|
}
|
||||||
|
maxRefs = Integer.parseUnsignedInt(tokens[1]);
|
||||||
|
break;
|
||||||
|
case "disallowReferenceUriSchemes":
|
||||||
|
if (tokens.length == 1) {
|
||||||
|
error(entry);
|
||||||
|
}
|
||||||
|
for (int i = 1; i < tokens.length; i++) {
|
||||||
|
String scheme = tokens[i];
|
||||||
|
disallowedRefUriSchemes.add(
|
||||||
|
scheme.toLowerCase(Locale.ROOT));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "noDuplicateIds":
|
||||||
|
if (tokens.length != 1) {
|
||||||
|
error(entry);
|
||||||
|
}
|
||||||
|
noDuplicateIds = true;
|
||||||
|
break;
|
||||||
|
case "noRetrievalMethodLoops":
|
||||||
|
if (tokens.length != 1) {
|
||||||
|
error(entry);
|
||||||
|
}
|
||||||
|
noRMLoops = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean restrictAlg(String alg) {
|
||||||
|
try {
|
||||||
|
URI uri = new URI(alg);
|
||||||
|
return disallowedAlgs.contains(uri);
|
||||||
|
} catch (URISyntaxException use) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean restrictNumTransforms(int numTrans) {
|
||||||
|
return (numTrans > maxTrans);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean restrictNumReferences(int numRefs) {
|
||||||
|
return (numRefs > maxRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean restrictReferenceUriScheme(String uri) {
|
||||||
|
if (uri != null) {
|
||||||
|
String scheme = java.net.URI.create(uri).getScheme();
|
||||||
|
if (scheme != null) {
|
||||||
|
return disallowedRefUriSchemes.contains(
|
||||||
|
scheme.toLowerCase(Locale.ROOT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean restrictDuplicateIds() {
|
||||||
|
return noDuplicateIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean restrictRetrievalMethodLoops() {
|
||||||
|
return noRMLoops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<URI> disabledAlgs() {
|
||||||
|
return Collections.<URI>unmodifiableSet(disallowedAlgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int maxTransforms() {
|
||||||
|
return maxTrans;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int maxReferences() {
|
||||||
|
return maxRefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<String> disabledReferenceUriSchemes() {
|
||||||
|
return Collections.<String>unmodifiableSet(disallowedRefUriSchemes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void error(String entry) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid jdk.xml.dsig.secureValidationPolicy entry: " + entry);
|
||||||
|
}
|
||||||
|
}
|
@ -358,7 +358,9 @@ final class P11RSACipher extends CipherSpi {
|
|||||||
System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs);
|
System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs);
|
||||||
tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
|
tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
|
||||||
if (tmpBuffer.length > outLen) {
|
if (tmpBuffer.length > outLen) {
|
||||||
throw new BadPaddingException("Output buffer too small");
|
throw new BadPaddingException(
|
||||||
|
"Output buffer (" + outLen + ") is too small to " +
|
||||||
|
"hold the produced data (" + tmpBuffer.length + ")");
|
||||||
}
|
}
|
||||||
System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length);
|
System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length);
|
||||||
n = tmpBuffer.length;
|
n = tmpBuffer.length;
|
||||||
|
@ -558,7 +558,7 @@ void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR
|
|||||||
pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
|
pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
|
||||||
if (pCharArray == NULL) { return; }
|
if (pCharArray == NULL) { return; }
|
||||||
|
|
||||||
*ckpLength = strlen(pCharArray);
|
*ckpLength = (CK_ULONG) strlen(pCharArray);
|
||||||
*ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
|
*ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
|
||||||
if (*ckpArray == NULL) {
|
if (*ckpArray == NULL) {
|
||||||
(*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
|
(*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -49,6 +49,7 @@ void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
|
|||||||
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
|
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
|
||||||
(JNIEnv *env, jclass thisClass, jstring jLibName)
|
(JNIEnv *env, jclass thisClass, jstring jLibName)
|
||||||
{
|
{
|
||||||
|
void *hModule;
|
||||||
const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
|
const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
|
||||||
if (libName == NULL) {
|
if (libName == NULL) {
|
||||||
return 0L;
|
return 0L;
|
||||||
@ -56,9 +57,9 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
|
|||||||
|
|
||||||
// look up existing handle only, do not load
|
// look up existing handle only, do not load
|
||||||
#if defined(AIX)
|
#if defined(AIX)
|
||||||
void *hModule = dlopen(libName, RTLD_LAZY);
|
hModule = dlopen(libName, RTLD_LAZY);
|
||||||
#else
|
#else
|
||||||
void *hModule = dlopen(libName, RTLD_NOLOAD);
|
hModule = dlopen(libName, RTLD_NOLOAD);
|
||||||
#endif
|
#endif
|
||||||
dprintf2("-handle for %s: %u\n", libName, hModule);
|
dprintf2("-handle for %s: %u\n", libName, hModule);
|
||||||
(*env)->ReleaseStringUTFChars(env, jLibName, libName);
|
(*env)->ReleaseStringUTFChars(env, jLibName, libName);
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
|
|
||||||
#include "j2secmod.h"
|
#include "j2secmod.h"
|
||||||
|
|
||||||
|
extern void throwNullPointerException(JNIEnv *env, const char *message);
|
||||||
|
extern void throwIOException(JNIEnv *env, const char *message);
|
||||||
|
|
||||||
void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
|
void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
|
||||||
HINSTANCE hModule = (HINSTANCE)jHandle;
|
HINSTANCE hModule = (HINSTANCE)jHandle;
|
||||||
void *fAddress = GetProcAddress(hModule, functionName);
|
void *fAddress = GetProcAddress(hModule, functionName);
|
||||||
|
@ -24,5 +24,5 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
module jdk.internal.opt {
|
module jdk.internal.opt {
|
||||||
exports jdk.internal.joptsimple to jdk.jlink;
|
exports jdk.internal.joptsimple to jdk.jlink, jdk.jshell;
|
||||||
}
|
}
|
||||||
|
@ -78,28 +78,21 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
|||||||
private final List<String> args;
|
private final List<String> args;
|
||||||
private final Set<String> modules;
|
private final Set<String> modules;
|
||||||
|
|
||||||
public DefaultExecutableImage(Path home, Set<String> modules) {
|
DefaultExecutableImage(Path home, Set<String> modules) {
|
||||||
this(home, modules, createArgs(home));
|
|
||||||
}
|
|
||||||
|
|
||||||
private DefaultExecutableImage(Path home, Set<String> modules,
|
|
||||||
List<String> args) {
|
|
||||||
Objects.requireNonNull(home);
|
Objects.requireNonNull(home);
|
||||||
Objects.requireNonNull(args);
|
|
||||||
if (!Files.exists(home)) {
|
if (!Files.exists(home)) {
|
||||||
throw new IllegalArgumentException("Invalid image home");
|
throw new IllegalArgumentException("Invalid image home");
|
||||||
}
|
}
|
||||||
this.home = home;
|
this.home = home;
|
||||||
this.modules = Collections.unmodifiableSet(modules);
|
this.modules = Collections.unmodifiableSet(modules);
|
||||||
this.args = Collections.unmodifiableList(args);
|
this.args = createArgs(home);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> createArgs(Path home) {
|
private static List<String> createArgs(Path home) {
|
||||||
Objects.requireNonNull(home);
|
Objects.requireNonNull(home);
|
||||||
List<String> javaArgs = new ArrayList<>();
|
Path binDir = home.resolve("bin");
|
||||||
javaArgs.add(home.resolve("bin").
|
String java = Files.exists(binDir.resolve("java"))? "java" : "java.exe";
|
||||||
resolve(getJavaProcessName()).toString());
|
return List.of(binDir.resolve(java).toString());
|
||||||
return javaArgs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -130,6 +123,7 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
|||||||
private final Path root;
|
private final Path root;
|
||||||
private final Path mdir;
|
private final Path mdir;
|
||||||
private final Set<String> modules = new HashSet<>();
|
private final Set<String> modules = new HashSet<>();
|
||||||
|
private String targetOsName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default image builder constructor.
|
* Default image builder constructor.
|
||||||
@ -171,6 +165,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
|||||||
@Override
|
@Override
|
||||||
public void storeFiles(ResourcePool files) {
|
public void storeFiles(ResourcePool files) {
|
||||||
try {
|
try {
|
||||||
|
// populate release properties up-front. targetOsName
|
||||||
|
// field is assigned from there and used elsewhere.
|
||||||
|
Properties release = releaseProperties(files);
|
||||||
|
Path bin = root.resolve("bin");
|
||||||
|
|
||||||
files.entries().forEach(f -> {
|
files.entries().forEach(f -> {
|
||||||
if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
||||||
try {
|
try {
|
||||||
@ -186,11 +185,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
|||||||
modules.add(m.name());
|
modules.add(m.name());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
storeFiles(modules, releaseProperties(files));
|
|
||||||
|
storeFiles(modules, release);
|
||||||
|
|
||||||
if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
|
if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
|
||||||
// launchers in the bin directory need execute permission
|
// launchers in the bin directory need execute permission
|
||||||
Path bin = root.resolve("bin");
|
|
||||||
if (Files.isDirectory(bin)) {
|
if (Files.isDirectory(bin)) {
|
||||||
Files.list(bin)
|
Files.list(bin)
|
||||||
.filter(f -> !f.toString().endsWith(".diz"))
|
.filter(f -> !f.toString().endsWith(".diz"))
|
||||||
@ -208,7 +207,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareApplicationFiles(files, modules);
|
// If native files are stripped completely, <root>/bin dir won't exist!
|
||||||
|
// So, don't bother generating launcher scripts.
|
||||||
|
if (Files.isDirectory(bin)) {
|
||||||
|
prepareApplicationFiles(files, modules);
|
||||||
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new PluginException(ex);
|
throw new PluginException(ex);
|
||||||
}
|
}
|
||||||
@ -226,6 +229,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
|||||||
props.setProperty("JAVA_VERSION", System.getProperty("java.version"));
|
props.setProperty("JAVA_VERSION", System.getProperty("java.version"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.targetOsName = props.getProperty("OS_NAME");
|
||||||
|
if (this.targetOsName == null) {
|
||||||
|
throw new PluginException("TargetPlatform attribute is missing for java.base module");
|
||||||
|
}
|
||||||
|
|
||||||
Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release");
|
Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release");
|
||||||
if (release.isPresent()) {
|
if (release.isPresent()) {
|
||||||
try (InputStream is = release.get().content()) {
|
try (InputStream is = release.get().content()) {
|
||||||
@ -373,7 +381,7 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
|||||||
Files.createLink(dstFile, target);
|
Files.createLink(dstFile, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String nativeDir(String filename) {
|
private String nativeDir(String filename) {
|
||||||
if (isWindows()) {
|
if (isWindows()) {
|
||||||
if (filename.endsWith(".dll") || filename.endsWith(".diz")
|
if (filename.endsWith(".dll") || filename.endsWith(".diz")
|
||||||
|| filename.endsWith(".pdb") || filename.endsWith(".map")) {
|
|| filename.endsWith(".pdb") || filename.endsWith(".map")) {
|
||||||
@ -386,8 +394,8 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isWindows() {
|
private boolean isWindows() {
|
||||||
return System.getProperty("os.name").startsWith("Windows");
|
return targetOsName.startsWith("Windows");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -452,12 +460,10 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getJavaProcessName() {
|
|
||||||
return isWindows() ? "java.exe" : "java";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ExecutableImage getExecutableImage(Path root) {
|
public static ExecutableImage getExecutableImage(Path root) {
|
||||||
if (Files.exists(root.resolve("bin").resolve(getJavaProcessName()))) {
|
Path binDir = root.resolve("bin");
|
||||||
|
if (Files.exists(binDir.resolve("java")) ||
|
||||||
|
Files.exists(binDir.resolve("java.exe"))) {
|
||||||
return new DefaultExecutableImage(root, retrieveModules(root));
|
return new DefaultExecutableImage(root, retrieveModules(root));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -172,7 +172,7 @@ public final class ImagePluginStack {
|
|||||||
private final Plugin lastSorter;
|
private final Plugin lastSorter;
|
||||||
private final List<Plugin> plugins = new ArrayList<>();
|
private final List<Plugin> plugins = new ArrayList<>();
|
||||||
private final List<ResourcePrevisitor> resourcePrevisitors = new ArrayList<>();
|
private final List<ResourcePrevisitor> resourcePrevisitors = new ArrayList<>();
|
||||||
|
private final boolean validate;
|
||||||
|
|
||||||
public ImagePluginStack() {
|
public ImagePluginStack() {
|
||||||
this(null, Collections.emptyList(), null);
|
this(null, Collections.emptyList(), null);
|
||||||
@ -181,6 +181,13 @@ public final class ImagePluginStack {
|
|||||||
public ImagePluginStack(ImageBuilder imageBuilder,
|
public ImagePluginStack(ImageBuilder imageBuilder,
|
||||||
List<Plugin> plugins,
|
List<Plugin> plugins,
|
||||||
Plugin lastSorter) {
|
Plugin lastSorter) {
|
||||||
|
this(imageBuilder, plugins, lastSorter, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImagePluginStack(ImageBuilder imageBuilder,
|
||||||
|
List<Plugin> plugins,
|
||||||
|
Plugin lastSorter,
|
||||||
|
boolean validate) {
|
||||||
this.imageBuilder = Objects.requireNonNull(imageBuilder);
|
this.imageBuilder = Objects.requireNonNull(imageBuilder);
|
||||||
this.lastSorter = lastSorter;
|
this.lastSorter = lastSorter;
|
||||||
this.plugins.addAll(Objects.requireNonNull(plugins));
|
this.plugins.addAll(Objects.requireNonNull(plugins));
|
||||||
@ -190,6 +197,7 @@ public final class ImagePluginStack {
|
|||||||
resourcePrevisitors.add((ResourcePrevisitor) p);
|
resourcePrevisitors.add((ResourcePrevisitor) p);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.validate = validate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void operate(ImageProvider provider) throws Exception {
|
public void operate(ImageProvider provider) throws Exception {
|
||||||
@ -268,6 +276,7 @@ public final class ImagePluginStack {
|
|||||||
frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList();
|
frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resPool;
|
return resPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,7 +467,11 @@ public final class ImagePluginStack {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
Objects.requireNonNull(original);
|
Objects.requireNonNull(original);
|
||||||
Objects.requireNonNull(transformed);
|
Objects.requireNonNull(transformed);
|
||||||
imageBuilder.storeFiles(new LastPoolManager(transformed).resourcePool());
|
ResourcePool lastPool = new LastPoolManager(transformed).resourcePool();
|
||||||
|
if (validate) {
|
||||||
|
ResourcePoolConfiguration.validate(lastPool);
|
||||||
|
}
|
||||||
|
imageBuilder.storeFiles(lastPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExecutableImage getExecutableImage() throws IOException {
|
public ExecutableImage getExecutableImage() throws IOException {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
* particular file as subject to the "Classfile" exception as provided
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* 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.tools.jlink.internal;
|
||||||
|
|
||||||
|
import java.lang.module.Configuration;
|
||||||
|
import java.lang.module.ModuleDescriptor;
|
||||||
|
import java.lang.module.ModuleFinder;
|
||||||
|
import java.lang.module.ModuleReference;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import jdk.tools.jlink.plugin.PluginException;
|
||||||
|
import jdk.tools.jlink.plugin.ResourcePool;
|
||||||
|
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||||
|
import jdk.tools.jlink.plugin.ResourcePoolModule;
|
||||||
|
|
||||||
|
final class ResourcePoolConfiguration {
|
||||||
|
private ResourcePoolConfiguration() {}
|
||||||
|
|
||||||
|
private static ModuleDescriptor descriptorOf(ResourcePoolModule mod) {
|
||||||
|
ModuleDescriptor md = mod.descriptor();
|
||||||
|
|
||||||
|
// drop hashes
|
||||||
|
ModuleDescriptor.Builder builder = new ModuleDescriptor.Builder(md.name());
|
||||||
|
md.requires().stream()
|
||||||
|
.forEach(builder::requires);
|
||||||
|
md.exports().stream()
|
||||||
|
.forEach(builder::exports);
|
||||||
|
md.uses().stream()
|
||||||
|
.forEach(builder::uses);
|
||||||
|
md.provides().values().stream()
|
||||||
|
.forEach(builder::provides);
|
||||||
|
|
||||||
|
// build the proper concealed packages
|
||||||
|
Set<String> exps = md.exports().stream()
|
||||||
|
.map(ModuleDescriptor.Exports::source)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
mod.packages().stream()
|
||||||
|
.filter(pn -> !exps.contains(pn))
|
||||||
|
.forEach(builder::conceals);
|
||||||
|
|
||||||
|
md.version().ifPresent(builder::version);
|
||||||
|
md.mainClass().ifPresent(builder::mainClass);
|
||||||
|
md.osName().ifPresent(builder::osName);
|
||||||
|
md.osArch().ifPresent(builder::osArch);
|
||||||
|
md.osVersion().ifPresent(builder::osVersion);
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ModuleReference moduleReference(ModuleDescriptor desc) {
|
||||||
|
return new ModuleReference(desc, null, () -> {
|
||||||
|
IOException ioe = new IOException("<module reader unsupported>");
|
||||||
|
throw new UncheckedIOException(ioe);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, ModuleReference> allModRefs(ResourcePool pool) {
|
||||||
|
return pool.moduleView().modules().
|
||||||
|
collect(Collectors.toMap(ResourcePoolModule::name,
|
||||||
|
m -> moduleReference(descriptorOf(m))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkPackages(ResourcePool pool) {
|
||||||
|
// check that each resource pool module's packages()
|
||||||
|
// returns a set that is consistent with the module
|
||||||
|
// descriptor of that module.
|
||||||
|
|
||||||
|
pool.moduleView().modules().forEach(m -> {
|
||||||
|
ModuleDescriptor desc = m.descriptor();
|
||||||
|
if (!desc.packages().equals(m.packages())) {
|
||||||
|
throw new RuntimeException("Module " + m.name() +
|
||||||
|
"'s descriptor returns inconsistent package set");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static Configuration validate(ResourcePool pool) {
|
||||||
|
checkPackages(pool);
|
||||||
|
final Map<String, ModuleReference> nameToModRef = allModRefs(pool);
|
||||||
|
final Set<ModuleReference> allRefs = new HashSet<>(nameToModRef.values());
|
||||||
|
|
||||||
|
final ModuleFinder finder = new ModuleFinder() {
|
||||||
|
@Override
|
||||||
|
public Optional<ModuleReference> find(String name) {
|
||||||
|
return Optional.ofNullable(nameToModRef.get(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<ModuleReference> findAll() {
|
||||||
|
return allRefs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Configuration.empty().resolveRequires(
|
||||||
|
finder, ModuleFinder.of(), nameToModRef.keySet());
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,11 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.tools.jlink.internal.plugins;
|
package jdk.tools.jlink.internal.plugins;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -32,6 +36,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import jdk.internal.misc.SharedSecrets;
|
import jdk.internal.misc.SharedSecrets;
|
||||||
import jdk.internal.misc.JavaLangInvokeAccess;
|
import jdk.internal.misc.JavaLangInvokeAccess;
|
||||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||||
@ -47,15 +52,9 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
|||||||
|
|
||||||
private static final String NAME = "generate-jli-classes";
|
private static final String NAME = "generate-jli-classes";
|
||||||
|
|
||||||
private static final String BMH_PARAM = "bmh";
|
|
||||||
|
|
||||||
private static final String BMH_SPECIES_PARAM = "bmh-species";
|
|
||||||
|
|
||||||
private static final String DMH_PARAM = "dmh";
|
|
||||||
|
|
||||||
private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME);
|
private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME);
|
||||||
|
|
||||||
private static final String DIRECT_METHOD_HANDLE = "java/lang/invoke/DirectMethodHandle$Holder";
|
private static final String DIRECT_HOLDER = "java/lang/invoke/DirectMethodHandle$Holder";
|
||||||
private static final String DMH_INVOKE_VIRTUAL = "invokeVirtual";
|
private static final String DMH_INVOKE_VIRTUAL = "invokeVirtual";
|
||||||
private static final String DMH_INVOKE_STATIC = "invokeStatic";
|
private static final String DMH_INVOKE_STATIC = "invokeStatic";
|
||||||
private static final String DMH_INVOKE_SPECIAL = "invokeSpecial";
|
private static final String DMH_INVOKE_SPECIAL = "invokeSpecial";
|
||||||
@ -63,15 +62,17 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
|||||||
private static final String DMH_INVOKE_INTERFACE = "invokeInterface";
|
private static final String DMH_INVOKE_INTERFACE = "invokeInterface";
|
||||||
private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit";
|
private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit";
|
||||||
|
|
||||||
private static final String DELEGATING_METHOD_HANDLE = "java/lang/invoke/DelegatingMethodHandle$Holder";
|
private static final String DELEGATING_HOLDER = "java/lang/invoke/DelegatingMethodHandle$Holder";
|
||||||
|
private static final String BASIC_FORMS_HOLDER = "java/lang/invoke/LambdaForm$Holder";
|
||||||
private static final String BASIC_FORMS_HANDLE = "java/lang/invoke/LambdaForm$Holder";
|
private static final String INVOKERS_HOLDER = "java/lang/invoke/Invokers$Holder";
|
||||||
|
|
||||||
private static final JavaLangInvokeAccess JLIA
|
private static final JavaLangInvokeAccess JLIA
|
||||||
= SharedSecrets.getJavaLangInvokeAccess();
|
= SharedSecrets.getJavaLangInvokeAccess();
|
||||||
|
|
||||||
List<String> speciesTypes;
|
List<String> speciesTypes;
|
||||||
|
|
||||||
|
List<String> invokerTypes;
|
||||||
|
|
||||||
Map<String, List<String>> dmhMethods;
|
Map<String, List<String>> dmhMethods;
|
||||||
|
|
||||||
public GenerateJLIClassesPlugin() {
|
public GenerateJLIClassesPlugin() {
|
||||||
@ -116,22 +117,30 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
|||||||
"LILL", "I", "LLILL");
|
"LILL", "I", "LLILL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the default invoker forms to generate.
|
||||||
|
*/
|
||||||
|
private static List<String> defaultInvokers() {
|
||||||
|
return List.of("LL_L", "LL_I", "LILL_I", "L6_L");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the list of default DirectMethodHandle methods to generate.
|
* @return the list of default DirectMethodHandle methods to generate.
|
||||||
*/
|
*/
|
||||||
public static Map<String, List<String>> defaultDMHMethods() {
|
private static Map<String, List<String>> defaultDMHMethods() {
|
||||||
return Map.of(
|
return Map.of(
|
||||||
DMH_INVOKE_VIRTUAL, List.of("_L", "L_L", "LI_I", "LL_V"),
|
DMH_INVOKE_VIRTUAL, List.of("L_L", "LL_L", "LLI_I", "L3_V"),
|
||||||
DMH_INVOKE_SPECIAL, List.of("L_I", "L_L", "LF_L", "LD_L", "LL_L",
|
DMH_INVOKE_SPECIAL, List.of("LL_I", "LL_L", "LLF_L", "LLD_L", "L3_L",
|
||||||
"L3_L", "L4_L", "L5_L", "L6_L", "L7_L", "LI_I", "LI_L", "LIL_I",
|
"L4_L", "L5_L", "L6_L", "L7_L", "L8_L", "LLI_I", "LLI_L",
|
||||||
"LII_I", "LII_L", "LLI_L", "LLI_I", "LILI_I", "LIIL_L",
|
"LLIL_I", "LLII_I", "LLII_L", "L3I_L", "L3I_I", "LLILI_I",
|
||||||
"LIILL_L", "LIILL_I", "LIIL_I", "LILIL_I", "LILILL_I",
|
"LLIIL_L", "LLIILL_L", "LLIILL_I", "LLIIL_I", "LLILIL_I",
|
||||||
"LILII_I", "LI3_I", "LI3L_I", "LI3LL_I", "LI3_L", "LI4_I"),
|
"LLILILL_I", "LLILII_I", "LLI3_I", "LLI3L_I", "LLI3LL_I",
|
||||||
DMH_INVOKE_STATIC, List.of("II_I", "IL_I", "ILIL_I", "ILII_I",
|
"LLI3_L", "LLI4_I"),
|
||||||
"_I", "_L", "_V", "D_L", "F_L", "I_I", "II_L", "LI_L",
|
DMH_INVOKE_STATIC, List.of("LII_I", "LIL_I", "LILIL_I", "LILII_I",
|
||||||
"L_V", "L_L", "LL_L", "L3_L", "L4_L", "L5_L", "L6_L",
|
"L_I", "L_L", "L_V", "LD_L", "LF_L", "LI_I", "LII_L", "LLI_L",
|
||||||
"L7_L", "L8_L", "L9_L", "L9I_L", "L9II_L", "L9IIL_L",
|
"LL_V", "LL_L", "L3_L", "L4_L", "L5_L", "L6_L", "L7_L",
|
||||||
"L10_L", "L11_L", "L12_L", "L13_L", "L13I_L", "L13II_L")
|
"L8_L", "L9_L", "L10_L", "L10I_L", "L10II_L", "L10IIL_L",
|
||||||
|
"L11_L", "L12_L", "L13_L", "L14_L", "L14I_L", "L14II_L")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,72 +159,91 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
|||||||
public void configure(Map<String, String> config) {
|
public void configure(Map<String, String> config) {
|
||||||
String mainArgument = config.get(NAME);
|
String mainArgument = config.get(NAME);
|
||||||
|
|
||||||
// Enable by default
|
if (mainArgument != null && mainArgument.startsWith("@")) {
|
||||||
boolean bmhEnabled = true;
|
File file = new File(mainArgument.substring(1));
|
||||||
boolean dmhEnabled = true;
|
if (file.exists()) {
|
||||||
if (mainArgument != null) {
|
speciesTypes = new ArrayList<>();
|
||||||
List<String> args = Arrays.asList(mainArgument.split(","));
|
invokerTypes = new ArrayList<>();
|
||||||
if (!args.contains(BMH_PARAM)) {
|
dmhMethods = new HashMap<>();
|
||||||
bmhEnabled = false;
|
Stream<String> lines = fileLines(file);
|
||||||
}
|
|
||||||
if (!args.contains(DMH_PARAM)) {
|
|
||||||
dmhEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bmhEnabled) {
|
lines.map(line -> line.split(" "))
|
||||||
speciesTypes = List.of();
|
.forEach(parts -> {
|
||||||
|
switch (parts[0]) {
|
||||||
|
case "[BMH_RESOLVE]":
|
||||||
|
speciesTypes.add(expandSignature(parts[1]));
|
||||||
|
break;
|
||||||
|
case "[LF_RESOLVE]":
|
||||||
|
String methodType = parts[3];
|
||||||
|
validateMethodType(methodType);
|
||||||
|
if (parts[1].contains("Invokers")) {
|
||||||
|
invokerTypes.add(methodType);
|
||||||
|
} else if (parts[1].contains("DirectMethodHandle")) {
|
||||||
|
String dmh = parts[2];
|
||||||
|
// ignore getObject etc for now (generated
|
||||||
|
// by default)
|
||||||
|
if (DMH_METHOD_TYPE_MAP.containsKey(dmh)) {
|
||||||
|
addDMHMethodType(dmh, methodType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break; // ignore
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
String args = config.get(BMH_SPECIES_PARAM);
|
List<String> bmhSpecies = defaultSpecies();
|
||||||
List<String> bmhSpecies;
|
|
||||||
if (args != null && !args.isEmpty()) {
|
|
||||||
bmhSpecies = Arrays.stream(args.split(","))
|
|
||||||
.map(String::trim)
|
|
||||||
.filter(s -> !s.isEmpty())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
} else {
|
|
||||||
bmhSpecies = defaultSpecies();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expand BMH species signatures
|
// Expand BMH species signatures
|
||||||
speciesTypes = bmhSpecies.stream()
|
speciesTypes = bmhSpecies.stream()
|
||||||
.map(type -> expandSignature(type))
|
.map(type -> expandSignature(type))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
|
||||||
|
|
||||||
// DirectMethodHandles
|
invokerTypes = defaultInvokers();
|
||||||
if (!dmhEnabled) {
|
validateMethodTypes(invokerTypes);
|
||||||
dmhMethods = Map.of();
|
|
||||||
} else {
|
dmhMethods = defaultDMHMethods();
|
||||||
dmhMethods = new HashMap<>();
|
for (List<String> dmhMethodTypes : dmhMethods.values()) {
|
||||||
for (String dmhParam : DMH_METHOD_TYPE_MAP.keySet()) {
|
validateMethodTypes(dmhMethodTypes);
|
||||||
String args = config.get(dmhParam);
|
|
||||||
if (args != null && !args.isEmpty()) {
|
|
||||||
List<String> dmhMethodTypes = Arrays.stream(args.split(","))
|
|
||||||
.map(String::trim)
|
|
||||||
.filter(s -> !s.isEmpty())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
dmhMethods.put(dmhParam, dmhMethodTypes);
|
|
||||||
// Validation check
|
|
||||||
for (String type : dmhMethodTypes) {
|
|
||||||
String[] typeParts = type.split("_");
|
|
||||||
// check return type (second part)
|
|
||||||
if (typeParts.length != 2 || typeParts[1].length() != 1
|
|
||||||
|| "LJIFDV".indexOf(typeParts[1].charAt(0)) == -1) {
|
|
||||||
throw new PluginException(
|
|
||||||
"Method type signature must be of form [LJIFD]*_[LJIFDV]");
|
|
||||||
}
|
|
||||||
// expand and check arguments (first part)
|
|
||||||
expandSignature(typeParts[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dmhMethods.isEmpty()) {
|
|
||||||
dmhMethods = defaultDMHMethods();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addDMHMethodType(String dmh, String methodType) {
|
||||||
|
validateMethodType(methodType);
|
||||||
|
List<String> methodTypes = dmhMethods.get(dmh);
|
||||||
|
if (methodTypes == null) {
|
||||||
|
methodTypes = new ArrayList<>();
|
||||||
|
dmhMethods.put(dmh, methodTypes);
|
||||||
|
}
|
||||||
|
methodTypes.add(methodType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stream<String> fileLines(File file) {
|
||||||
|
try {
|
||||||
|
return Files.lines(file.toPath());
|
||||||
|
} catch (IOException io) {
|
||||||
|
throw new PluginException("Couldn't read file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateMethodTypes(List<String> dmhMethodTypes) {
|
||||||
|
for (String type : dmhMethodTypes) {
|
||||||
|
validateMethodType(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateMethodType(String type) {
|
||||||
|
String[] typeParts = type.split("_");
|
||||||
|
// check return type (second part)
|
||||||
|
if (typeParts.length != 2 || typeParts[1].length() != 1
|
||||||
|
|| "LJIFDV".indexOf(typeParts[1].charAt(0)) == -1) {
|
||||||
|
throw new PluginException(
|
||||||
|
"Method type signature must be of form [LJIFD]*_[LJIFDV]");
|
||||||
|
}
|
||||||
|
// expand and check arguments (first part)
|
||||||
|
expandSignature(typeParts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
private static void requireBasicType(char c) {
|
private static void requireBasicType(char c) {
|
||||||
if ("LIJFD".indexOf(c) < 0) {
|
if ("LIJFD".indexOf(c) < 0) {
|
||||||
throw new PluginException(
|
throw new PluginException(
|
||||||
@ -228,9 +256,10 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
|||||||
// Copy all but DMH_ENTRY to out
|
// Copy all but DMH_ENTRY to out
|
||||||
in.transformAndCopy(entry -> {
|
in.transformAndCopy(entry -> {
|
||||||
// filter out placeholder entries
|
// filter out placeholder entries
|
||||||
if (entry.path().equals(DIRECT_METHOD_HANDLE_ENTRY) ||
|
if (entry.path().equals(DIRECT_METHOD_HOLDER_ENTRY) ||
|
||||||
entry.path().equals(DELEGATING_METHOD_HANDLE_ENTRY) ||
|
entry.path().equals(DELEGATING_METHOD_HOLDER_ENTRY) ||
|
||||||
entry.path().equals(BASIC_FORMS_HANDLE_ENTRY)) {
|
entry.path().equals(INVOKERS_HOLDER_ENTRY) ||
|
||||||
|
entry.path().equals(BASIC_FORMS_HOLDER_ENTRY)) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return entry;
|
return entry;
|
||||||
@ -265,42 +294,72 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
|||||||
for (List<String> entry : dmhMethods.values()) {
|
for (List<String> entry : dmhMethods.values()) {
|
||||||
count += entry.size();
|
count += entry.size();
|
||||||
}
|
}
|
||||||
MethodType[] methodTypes = new MethodType[count];
|
MethodType[] directMethodTypes = new MethodType[count];
|
||||||
int[] dmhTypes = new int[count];
|
int[] dmhTypes = new int[count];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (Map.Entry<String, List<String>> entry : dmhMethods.entrySet()) {
|
for (Map.Entry<String, List<String>> entry : dmhMethods.entrySet()) {
|
||||||
String dmhType = entry.getKey();
|
String dmhType = entry.getKey();
|
||||||
for (String type : entry.getValue()) {
|
for (String type : entry.getValue()) {
|
||||||
methodTypes[index] = asMethodType(type);
|
// The DMH type to actually ask for is retrieved by removing
|
||||||
|
// the first argument, which needs to be of Object.class
|
||||||
|
MethodType mt = asMethodType(type);
|
||||||
|
if (mt.parameterCount() < 1 ||
|
||||||
|
mt.parameterType(0) != Object.class) {
|
||||||
|
throw new PluginException(
|
||||||
|
"DMH type parameter must start with L");
|
||||||
|
}
|
||||||
|
directMethodTypes[index] = mt.dropParameterTypes(0, 1);
|
||||||
dmhTypes[index] = DMH_METHOD_TYPE_MAP.get(dmhType);
|
dmhTypes[index] = DMH_METHOD_TYPE_MAP.get(dmhType);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MethodType[] invokerMethodTypes = new MethodType[this.invokerTypes.size()];
|
||||||
|
for (int i = 0; i < invokerTypes.size(); i++) {
|
||||||
|
// The invoker type to ask for is retrieved by removing the first
|
||||||
|
// and the last argument, which needs to be of Object.class
|
||||||
|
MethodType mt = asMethodType(invokerTypes.get(i));
|
||||||
|
final int lastParam = mt.parameterCount() - 1;
|
||||||
|
if (mt.parameterCount() < 2 ||
|
||||||
|
mt.parameterType(0) != Object.class ||
|
||||||
|
mt.parameterType(lastParam) != Object.class) {
|
||||||
|
throw new PluginException(
|
||||||
|
"Invoker type parameter must start and end with L");
|
||||||
|
}
|
||||||
|
mt = mt.dropParameterTypes(lastParam, lastParam + 1);
|
||||||
|
invokerMethodTypes[i] = mt.dropParameterTypes(0, 1);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes(
|
byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes(
|
||||||
DIRECT_METHOD_HANDLE, methodTypes, dmhTypes);
|
DIRECT_HOLDER, directMethodTypes, dmhTypes);
|
||||||
ResourcePoolEntry ndata = ResourcePoolEntry
|
ResourcePoolEntry ndata = ResourcePoolEntry
|
||||||
.create(DIRECT_METHOD_HANDLE_ENTRY, bytes);
|
.create(DIRECT_METHOD_HOLDER_ENTRY, bytes);
|
||||||
out.add(ndata);
|
out.add(ndata);
|
||||||
|
|
||||||
bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes(
|
bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes(
|
||||||
DELEGATING_METHOD_HANDLE, methodTypes);
|
DELEGATING_HOLDER, directMethodTypes);
|
||||||
ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HANDLE_ENTRY, bytes);
|
ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HOLDER_ENTRY, bytes);
|
||||||
out.add(ndata);
|
out.add(ndata);
|
||||||
|
|
||||||
bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HANDLE);
|
bytes = JLIA.generateInvokersHolderClassBytes(INVOKERS_HOLDER,
|
||||||
ndata = ResourcePoolEntry.create(BASIC_FORMS_HANDLE_ENTRY, bytes);
|
invokerMethodTypes);
|
||||||
|
ndata = ResourcePoolEntry.create(INVOKERS_HOLDER_ENTRY, bytes);
|
||||||
|
out.add(ndata);
|
||||||
|
|
||||||
|
bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HOLDER);
|
||||||
|
ndata = ResourcePoolEntry.create(BASIC_FORMS_HOLDER_ENTRY, bytes);
|
||||||
out.add(ndata);
|
out.add(ndata);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new PluginException(ex);
|
throw new PluginException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static final String DIRECT_METHOD_HANDLE_ENTRY =
|
private static final String DIRECT_METHOD_HOLDER_ENTRY =
|
||||||
"/java.base/" + DIRECT_METHOD_HANDLE + ".class";
|
"/java.base/" + DIRECT_HOLDER + ".class";
|
||||||
private static final String DELEGATING_METHOD_HANDLE_ENTRY =
|
private static final String DELEGATING_METHOD_HOLDER_ENTRY =
|
||||||
"/java.base/" + DELEGATING_METHOD_HANDLE + ".class";
|
"/java.base/" + DELEGATING_HOLDER + ".class";
|
||||||
private static final String BASIC_FORMS_HANDLE_ENTRY =
|
private static final String BASIC_FORMS_HOLDER_ENTRY =
|
||||||
"/java.base/" + BASIC_FORMS_HANDLE + ".class";
|
"/java.base/" + BASIC_FORMS_HOLDER + ".class";
|
||||||
|
private static final String INVOKERS_HOLDER_ENTRY =
|
||||||
|
"/java.base/" + INVOKERS_HOLDER + ".class";
|
||||||
|
|
||||||
// Convert LL -> LL, L3 -> LLL
|
// Convert LL -> LL, L3 -> LLL
|
||||||
private static String expandSignature(String signature) {
|
private static String expandSignature(String signature) {
|
||||||
|
@ -56,7 +56,7 @@ copy-files.argument=<List of <file path>=<image target> to copy to the image>.
|
|||||||
|
|
||||||
copy-files.description=\
|
copy-files.description=\
|
||||||
If files to copy are not absolute path, JDK home dir is used.\n\
|
If files to copy are not absolute path, JDK home dir is used.\n\
|
||||||
e.g.: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewehere/conf.txt
|
e.g.: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewhere/conf.txt
|
||||||
|
|
||||||
exclude-files.argument=<pattern-list> of files to exclude
|
exclude-files.argument=<pattern-list> of files to exclude
|
||||||
|
|
||||||
@ -68,10 +68,12 @@ exclude-resources.argument=<pattern-list> resources to exclude
|
|||||||
exclude-resources.description=\
|
exclude-resources.description=\
|
||||||
Specify resources to exclude. e.g.: **.jcov,glob:**/META-INF/**
|
Specify resources to exclude. e.g.: **.jcov,glob:**/META-INF/**
|
||||||
|
|
||||||
generate-jli-classes.argument=<bmh[:bmh-species=LL,L3,...]>
|
generate-jli-classes.argument=<@filename>
|
||||||
|
|
||||||
generate-jli-classes.description=\
|
generate-jli-classes.description=\
|
||||||
Concrete java.lang.invoke classes to generate
|
Takes a file hinting to jlink what java.lang.invoke classes to pre-generate. If\n\
|
||||||
|
this flag is not specified a default set of classes will be generated, so to \n\
|
||||||
|
disable pre-generation supply the name of an empty or non-existing file
|
||||||
|
|
||||||
installed-modules.description=Fast loading of module descriptors (always enabled)
|
installed-modules.description=Fast loading of module descriptors (always enabled)
|
||||||
|
|
||||||
|
@ -165,8 +165,8 @@ class JarFileSystem extends ZipFileSystem {
|
|||||||
walk(inode.child, process);
|
walk(inode.child, process);
|
||||||
} else {
|
} else {
|
||||||
process.accept(inode);
|
process.accept(inode);
|
||||||
walk(inode.sibling, process);
|
|
||||||
}
|
}
|
||||||
|
walk(inode.sibling, process);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,10 +124,6 @@ java/beans/Introspector/8132566/OverrideUserDefPropertyInfoTest.java 8132565 gen
|
|||||||
# jdk_lang
|
# jdk_lang
|
||||||
|
|
||||||
java/lang/StringCoding/CheckEncodings.sh 7008363 generic-all
|
java/lang/StringCoding/CheckEncodings.sh 7008363 generic-all
|
||||||
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java 8160690 generic-all
|
|
||||||
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java 8160690 generic-all
|
|
||||||
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java 8160690 generic-all
|
|
||||||
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java 8160690 generic-all
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
@ -211,8 +207,6 @@ sun/rmi/rmic/newrmic/equivalence/run.sh 8145980 generic-
|
|||||||
|
|
||||||
java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all
|
java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all
|
||||||
|
|
||||||
sun/rmi/runtime/Log/6409194/NoConsoleOutput.java 8164124 windows-all
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
# jdk_security
|
# jdk_security
|
||||||
|
@ -205,12 +205,13 @@ public class VerifyStackTrace {
|
|||||||
.replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/")
|
.replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/")
|
||||||
.replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run")
|
.replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run")
|
||||||
.replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke")
|
.replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke")
|
||||||
// DMHs may or may not be pre-generated, making frames differ
|
// LFs may or may not be pre-generated, making frames differ
|
||||||
.replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH")
|
.replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH")
|
||||||
.replaceAll("DMH\\.invoke", "DMH/xxxxxxxx.invoke")
|
.replaceAll("Invokers\\$Holder", "LambdaForm\\$MH")
|
||||||
|
.replaceAll("MH\\.invoke", "MH/xxxxxxxx.invoke")
|
||||||
// invoke frames may or may not have basic method type
|
// invoke frames may or may not have basic method type
|
||||||
// information encoded for diagnostic purposes
|
// information encoded for diagnostic purposes
|
||||||
.replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z]+_[A-Z]", "xx.invoke$1")
|
.replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z_]+", "xx.invoke$1")
|
||||||
.replaceAll("\\$[0-9]+", "\\$??");
|
.replaceAll("\\$[0-9]+", "\\$??");
|
||||||
} else {
|
} else {
|
||||||
return produced;
|
return produced;
|
||||||
|
56
jdk/test/java/net/HttpCookie/CookieNegativeMaxAge.java
Normal file
56
jdk/test/java/net/HttpCookie/CookieNegativeMaxAge.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8005068
|
||||||
|
* @summary Check that any negative maxAge is treated as "unspecified" and
|
||||||
|
* if header contains cookie with "expires" attribute in the past then cookie
|
||||||
|
* is created with maxAge=0 meaning it is specified to be immediately expired.
|
||||||
|
* @run main CookieNegativeMaxAge
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import java.net.HttpCookie;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CookieNegativeMaxAge {
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
HttpCookie cookie = new HttpCookie("testCookie", "value");
|
||||||
|
cookie.setMaxAge(Integer.MIN_VALUE);
|
||||||
|
if (cookie.hasExpired()) {
|
||||||
|
throw new RuntimeException("Cookie has unexpectedly expired");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<HttpCookie> cookies = HttpCookie.parse("Set-Cookie: " +
|
||||||
|
"expiredCookie=value; expires=Thu, 01 Jan 1970 00:00:00 GMT");
|
||||||
|
if (cookies.size() == 1) {
|
||||||
|
if (cookies.get(0).getMaxAge() != 0) {
|
||||||
|
throw new RuntimeException("Cookie maxAge expected to be 0");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Header was incorrectly parsed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -68,6 +68,7 @@ public class NoLoopbackPackets {
|
|||||||
|
|
||||||
MulticastSocket msock = null;
|
MulticastSocket msock = null;
|
||||||
List<SocketAddress> failedGroups = new ArrayList<SocketAddress>();
|
List<SocketAddress> failedGroups = new ArrayList<SocketAddress>();
|
||||||
|
Sender sender = null;
|
||||||
try {
|
try {
|
||||||
msock = new MulticastSocket();
|
msock = new MulticastSocket();
|
||||||
int port = msock.getLocalPort();
|
int port = msock.getLocalPort();
|
||||||
@ -80,9 +81,8 @@ public class NoLoopbackPackets {
|
|||||||
groups.add(new InetSocketAddress(InetAddress.getByName("::ffff:224.1.1.2"), port));
|
groups.add(new InetSocketAddress(InetAddress.getByName("::ffff:224.1.1.2"), port));
|
||||||
groups.add(new InetSocketAddress(InetAddress.getByName("ff02::1:1"), port));
|
groups.add(new InetSocketAddress(InetAddress.getByName("ff02::1:1"), port));
|
||||||
|
|
||||||
Thread sender = new Thread(new Sender(groups));
|
sender = new Sender(groups);
|
||||||
sender.setDaemon(true); // we want sender to stop when main thread exits
|
new Thread(sender).start();
|
||||||
sender.start();
|
|
||||||
|
|
||||||
// Now try to receive multicast packets. we should not see any of them
|
// Now try to receive multicast packets. we should not see any of them
|
||||||
// since we disable loopback mode.
|
// since we disable loopback mode.
|
||||||
@ -107,6 +107,9 @@ public class NoLoopbackPackets {
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (msock != null) try { msock.close(); } catch (Exception e) {}
|
if (msock != null) try { msock.close(); } catch (Exception e) {}
|
||||||
|
if (sender != null) {
|
||||||
|
sender.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failedGroups.size() > 0) {
|
if (failedGroups.size() > 0) {
|
||||||
@ -119,6 +122,7 @@ public class NoLoopbackPackets {
|
|||||||
|
|
||||||
static class Sender implements Runnable {
|
static class Sender implements Runnable {
|
||||||
private List<SocketAddress> sendToGroups;
|
private List<SocketAddress> sendToGroups;
|
||||||
|
private volatile boolean stop;
|
||||||
|
|
||||||
public Sender(List<SocketAddress> groups) {
|
public Sender(List<SocketAddress> groups) {
|
||||||
sendToGroups = groups;
|
sendToGroups = groups;
|
||||||
@ -136,7 +140,7 @@ public class NoLoopbackPackets {
|
|||||||
|
|
||||||
MulticastSocket msock = new MulticastSocket();
|
MulticastSocket msock = new MulticastSocket();
|
||||||
msock.setLoopbackMode(true); // disable loopback mode
|
msock.setLoopbackMode(true); // disable loopback mode
|
||||||
for (;;) {
|
while (!stop) {
|
||||||
for (DatagramPacket packet : packets) {
|
for (DatagramPacket packet : packets) {
|
||||||
msock.send(packet);
|
msock.send(packet);
|
||||||
}
|
}
|
||||||
@ -147,5 +151,9 @@ public class NoLoopbackPackets {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
stop = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
174
jdk/test/java/net/httpclient/ProxyAuthTest.java
Normal file
174
jdk/test/java/net/httpclient/ProxyAuthTest.java
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8163561
|
||||||
|
* @modules java.base/sun.net.www
|
||||||
|
* @summary Verify that Proxy-Authenticate header is correctly handled
|
||||||
|
*
|
||||||
|
* @run main/othervm ProxyAuthTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.Authenticator;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.PasswordAuthentication;
|
||||||
|
import java.net.ProxySelector;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
import sun.net.www.MessageHeader;
|
||||||
|
|
||||||
|
public class ProxyAuthTest {
|
||||||
|
private static final String AUTH_USER = "user";
|
||||||
|
private static final String AUTH_PASSWORD = "password";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
try (ServerSocket ss = new ServerSocket(0)) {
|
||||||
|
int port = ss.getLocalPort();
|
||||||
|
MyProxy proxy = new MyProxy(ss);
|
||||||
|
(new Thread(proxy)).start();
|
||||||
|
System.out.println("Proxy listening port " + port);
|
||||||
|
|
||||||
|
Auth auth = new Auth();
|
||||||
|
InetSocketAddress paddr = new InetSocketAddress("localhost", port);
|
||||||
|
|
||||||
|
URI uri = new URI("http://www.google.ie/");
|
||||||
|
HttpClient client = HttpClient.create()
|
||||||
|
.proxy(ProxySelector.of(paddr))
|
||||||
|
.authenticator(auth)
|
||||||
|
.build();
|
||||||
|
HttpResponse resp = client.request(uri)
|
||||||
|
.GET()
|
||||||
|
.responseAsync()
|
||||||
|
.get();
|
||||||
|
if (resp.statusCode() != 404) {
|
||||||
|
throw new RuntimeException("Unexpected status code: " + resp.statusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auth.isCalled) {
|
||||||
|
System.out.println("Authenticator is called");
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Authenticator is not called");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!proxy.matched) {
|
||||||
|
throw new RuntimeException("Proxy authentication failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Auth extends Authenticator {
|
||||||
|
private volatile boolean isCalled;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PasswordAuthentication getPasswordAuthentication() {
|
||||||
|
System.out.println("scheme: " + this.getRequestingScheme());
|
||||||
|
isCalled = true;
|
||||||
|
return new PasswordAuthentication(AUTH_USER,
|
||||||
|
AUTH_PASSWORD.toCharArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MyProxy implements Runnable {
|
||||||
|
final ServerSocket ss;
|
||||||
|
private volatile boolean matched;
|
||||||
|
|
||||||
|
MyProxy(ServerSocket ss) {
|
||||||
|
this.ss = ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
try (Socket s = ss.accept();
|
||||||
|
InputStream in = s.getInputStream();
|
||||||
|
OutputStream os = s.getOutputStream();
|
||||||
|
BufferedWriter writer = new BufferedWriter(
|
||||||
|
new OutputStreamWriter(os));
|
||||||
|
PrintWriter out = new PrintWriter(writer);) {
|
||||||
|
MessageHeader headers = new MessageHeader(in);
|
||||||
|
System.out.println("Proxy: received " + headers);
|
||||||
|
|
||||||
|
String authInfo = headers
|
||||||
|
.findValue("Proxy-Authorization");
|
||||||
|
if (authInfo != null) {
|
||||||
|
authenticate(authInfo);
|
||||||
|
out.print("HTTP/1.1 404 Not found\r\n");
|
||||||
|
out.print("\r\n");
|
||||||
|
System.out.println("Proxy: 404");
|
||||||
|
out.flush();
|
||||||
|
} else {
|
||||||
|
out.print("HTTP/1.1 407 Proxy Authorization Required\r\n");
|
||||||
|
out.print(
|
||||||
|
"Proxy-Authenticate: Basic realm=\"a fake realm\"\r\n");
|
||||||
|
out.print("\r\n");
|
||||||
|
System.out.println("Proxy: Authorization required");
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
} catch (IOException x) {
|
||||||
|
System.err.println("Unexpected IOException from proxy.");
|
||||||
|
x.printStackTrace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void authenticate(String authInfo) throws IOException {
|
||||||
|
try {
|
||||||
|
authInfo.trim();
|
||||||
|
int ind = authInfo.indexOf(' ');
|
||||||
|
String recvdUserPlusPass = authInfo.substring(ind + 1).trim();
|
||||||
|
// extract encoded username:passwd
|
||||||
|
String value = new String(
|
||||||
|
Base64.getMimeDecoder().decode(recvdUserPlusPass));
|
||||||
|
String userPlusPassword = AUTH_USER + ":" + AUTH_PASSWORD;
|
||||||
|
if (userPlusPassword.equals(value)) {
|
||||||
|
matched = true;
|
||||||
|
System.out.println("Proxy: client authentication successful");
|
||||||
|
} else {
|
||||||
|
System.err.println(
|
||||||
|
"Proxy: client authentication failed, expected ["
|
||||||
|
+ userPlusPassword + "], actual [" + value
|
||||||
|
+ "]");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException(
|
||||||
|
"Proxy received invalid Proxy-Authorization value: "
|
||||||
|
+ authInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -119,19 +119,31 @@ public class Basic {
|
|||||||
ExecutorService pool = Executors.newCachedThreadPool();
|
ExecutorService pool = Executors.newCachedThreadPool();
|
||||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||||
.withCachedThreadPool(pool, rand.nextInt(10));
|
.withCachedThreadPool(pool, rand.nextInt(10));
|
||||||
testShutdownWithChannels(pool, group);
|
try {
|
||||||
|
testShutdownWithChannels(pool, group);
|
||||||
|
} finally {
|
||||||
|
group.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
int nThreads = 1 + rand.nextInt(8);
|
int nThreads = 1 + rand.nextInt(8);
|
||||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||||
.withFixedThreadPool(nThreads, threadFactory);
|
.withFixedThreadPool(nThreads, threadFactory);
|
||||||
testShutdownWithChannels(null, group);
|
try {
|
||||||
|
testShutdownWithChannels(null, group);
|
||||||
|
} finally {
|
||||||
|
group.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
ExecutorService pool = Executors.newCachedThreadPool();
|
ExecutorService pool = Executors.newCachedThreadPool();
|
||||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||||
.withThreadPool(pool);
|
.withThreadPool(pool);
|
||||||
testShutdownWithChannels(pool, group);
|
try {
|
||||||
|
testShutdownWithChannels(pool, group);
|
||||||
|
} finally {
|
||||||
|
group.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,19 +176,31 @@ public class Basic {
|
|||||||
ExecutorService pool = pool = Executors.newCachedThreadPool();
|
ExecutorService pool = pool = Executors.newCachedThreadPool();
|
||||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||||
.withCachedThreadPool(pool, rand.nextInt(5));
|
.withCachedThreadPool(pool, rand.nextInt(5));
|
||||||
testShutdownNow(pool, group);
|
try {
|
||||||
|
testShutdownNow(pool, group);
|
||||||
|
} finally {
|
||||||
|
group.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
int nThreads = 1 + rand.nextInt(8);
|
int nThreads = 1 + rand.nextInt(8);
|
||||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||||
.withFixedThreadPool(nThreads, threadFactory);
|
.withFixedThreadPool(nThreads, threadFactory);
|
||||||
testShutdownNow(null, group);
|
try {
|
||||||
|
testShutdownNow(null, group);
|
||||||
|
} finally {
|
||||||
|
group.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
ExecutorService pool = Executors.newCachedThreadPool();
|
ExecutorService pool = Executors.newCachedThreadPool();
|
||||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||||
.withThreadPool(pool);
|
.withThreadPool(pool);
|
||||||
testShutdownNow(pool, group);
|
try {
|
||||||
|
testShutdownNow(pool, group);
|
||||||
|
} finally {
|
||||||
|
group.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,78 +210,78 @@ public class Basic {
|
|||||||
AsynchronousChannelGroup group =
|
AsynchronousChannelGroup group =
|
||||||
AsynchronousChannelGroup.withFixedThreadPool(1, threadFactory);
|
AsynchronousChannelGroup.withFixedThreadPool(1, threadFactory);
|
||||||
|
|
||||||
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
|
try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
|
||||||
AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open(group);
|
AsynchronousServerSocketChannel listener =
|
||||||
|
AsynchronousServerSocketChannel.open(group)) {
|
||||||
|
|
||||||
// initiate accept
|
// initiate accept
|
||||||
listener.bind(new InetSocketAddress(0));
|
listener.bind(new InetSocketAddress(0));
|
||||||
Future<AsynchronousSocketChannel> result = listener.accept();
|
Future<AsynchronousSocketChannel> result = listener.accept();
|
||||||
|
|
||||||
// shutdown group
|
// shutdown group
|
||||||
group.shutdown();
|
group.shutdown();
|
||||||
if (!group.isShutdown())
|
if (!group.isShutdown())
|
||||||
throw new RuntimeException("Group should be shutdown");
|
throw new RuntimeException("Group should be shutdown");
|
||||||
|
|
||||||
// attempt to create another channel
|
// attempt to create another channel
|
||||||
try {
|
try {
|
||||||
AsynchronousSocketChannel.open(group);
|
AsynchronousSocketChannel.open(group);
|
||||||
throw new RuntimeException("ShutdownChannelGroupException expected");
|
throw new RuntimeException("ShutdownChannelGroupException expected");
|
||||||
} catch (ShutdownChannelGroupException x) {
|
} catch (ShutdownChannelGroupException x) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
AsynchronousServerSocketChannel.open(group);
|
||||||
|
throw new RuntimeException("ShutdownChannelGroupException expected");
|
||||||
|
} catch (ShutdownChannelGroupException x) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// attempt to create another channel by connecting. This should cause
|
||||||
|
// the accept operation to fail.
|
||||||
|
InetAddress lh = InetAddress.getLocalHost();
|
||||||
|
int port = ((InetSocketAddress)listener.getLocalAddress()).getPort();
|
||||||
|
InetSocketAddress isa = new InetSocketAddress(lh, port);
|
||||||
|
ch.connect(isa).get();
|
||||||
|
try {
|
||||||
|
result.get();
|
||||||
|
throw new RuntimeException("Connection was accepted");
|
||||||
|
} catch (ExecutionException x) {
|
||||||
|
Throwable cause = x.getCause();
|
||||||
|
if (!(cause instanceof IOException))
|
||||||
|
throw new RuntimeException("Cause should be IOException");
|
||||||
|
cause = cause.getCause();
|
||||||
|
if (!(cause instanceof ShutdownChannelGroupException))
|
||||||
|
throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
|
||||||
|
}
|
||||||
|
|
||||||
|
// initiate another accept even though channel group is shutdown.
|
||||||
|
Future<AsynchronousSocketChannel> res = listener.accept();
|
||||||
|
try {
|
||||||
|
res.get(3, TimeUnit.SECONDS);
|
||||||
|
throw new RuntimeException("TimeoutException expected");
|
||||||
|
} catch (TimeoutException x) {
|
||||||
|
}
|
||||||
|
// connect to the listener which should cause the accept to complete
|
||||||
|
AsynchronousSocketChannel.open().connect(isa);
|
||||||
|
try {
|
||||||
|
res.get();
|
||||||
|
throw new RuntimeException("Connection was accepted");
|
||||||
|
} catch (ExecutionException x) {
|
||||||
|
Throwable cause = x.getCause();
|
||||||
|
if (!(cause instanceof IOException))
|
||||||
|
throw new RuntimeException("Cause should be IOException");
|
||||||
|
cause = cause.getCause();
|
||||||
|
if (!(cause instanceof ShutdownChannelGroupException))
|
||||||
|
throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
|
||||||
|
}
|
||||||
|
|
||||||
|
// group should *not* terminate as channels are open
|
||||||
|
boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
|
||||||
|
if (terminated) {
|
||||||
|
throw new RuntimeException("Group should not have terminated");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
group.shutdown();
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
AsynchronousServerSocketChannel.open(group);
|
|
||||||
throw new RuntimeException("ShutdownChannelGroupException expected");
|
|
||||||
} catch (ShutdownChannelGroupException x) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// attempt to create another channel by connecting. This should cause
|
|
||||||
// the accept operation to fail.
|
|
||||||
InetAddress lh = InetAddress.getLocalHost();
|
|
||||||
int port = ((InetSocketAddress)listener.getLocalAddress()).getPort();
|
|
||||||
InetSocketAddress isa = new InetSocketAddress(lh, port);
|
|
||||||
ch.connect(isa).get();
|
|
||||||
try {
|
|
||||||
result.get();
|
|
||||||
throw new RuntimeException("Connection was accepted");
|
|
||||||
} catch (ExecutionException x) {
|
|
||||||
Throwable cause = x.getCause();
|
|
||||||
if (!(cause instanceof IOException))
|
|
||||||
throw new RuntimeException("Cause should be IOException");
|
|
||||||
cause = cause.getCause();
|
|
||||||
if (!(cause instanceof ShutdownChannelGroupException))
|
|
||||||
throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
|
|
||||||
}
|
|
||||||
|
|
||||||
// initiate another accept even though channel group is shutdown.
|
|
||||||
Future<AsynchronousSocketChannel> res = listener.accept();
|
|
||||||
try {
|
|
||||||
res.get(3, TimeUnit.SECONDS);
|
|
||||||
throw new RuntimeException("TimeoutException expected");
|
|
||||||
} catch (TimeoutException x) {
|
|
||||||
}
|
|
||||||
// connect to the listener which should cause the accept to complete
|
|
||||||
AsynchronousSocketChannel.open().connect(isa);
|
|
||||||
try {
|
|
||||||
res.get();
|
|
||||||
throw new RuntimeException("Connection was accepted");
|
|
||||||
} catch (ExecutionException x) {
|
|
||||||
Throwable cause = x.getCause();
|
|
||||||
if (!(cause instanceof IOException))
|
|
||||||
throw new RuntimeException("Cause should be IOException");
|
|
||||||
cause = cause.getCause();
|
|
||||||
if (!(cause instanceof ShutdownChannelGroupException))
|
|
||||||
throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
|
|
||||||
}
|
|
||||||
|
|
||||||
// group should *not* terminate as channels are open
|
|
||||||
boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
|
|
||||||
if (terminated)
|
|
||||||
throw new RuntimeException("Group should not have terminated");
|
|
||||||
|
|
||||||
// close channel; group should terminate quickly
|
|
||||||
ch.close();
|
|
||||||
listener.close();
|
|
||||||
awaitTermination(group);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void miscTests() throws Exception {
|
static void miscTests() throws Exception {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -41,34 +41,36 @@ import java.io.IOException;
|
|||||||
public class GroupOfOne {
|
public class GroupOfOne {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
final List<AsynchronousSocketChannel> accepted = new ArrayList<>();
|
||||||
|
|
||||||
// create listener to accept connections
|
// create listener to accept connections
|
||||||
final AsynchronousServerSocketChannel listener =
|
try (final AsynchronousServerSocketChannel listener =
|
||||||
AsynchronousServerSocketChannel.open()
|
AsynchronousServerSocketChannel.open()) {
|
||||||
.bind(new InetSocketAddress(0));
|
|
||||||
final List<AsynchronousSocketChannel> accepted = new ArrayList<AsynchronousSocketChannel>();
|
listener.bind(new InetSocketAddress(0));
|
||||||
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
|
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
|
||||||
public void completed(AsynchronousSocketChannel ch, Void att) {
|
public void completed(AsynchronousSocketChannel ch, Void att) {
|
||||||
synchronized (accepted) {
|
synchronized (accepted) {
|
||||||
accepted.add(ch);
|
accepted.add(ch);
|
||||||
|
}
|
||||||
|
listener.accept((Void)null, this);
|
||||||
}
|
}
|
||||||
listener.accept((Void)null, this);
|
public void failed(Throwable exc, Void att) {
|
||||||
}
|
}
|
||||||
public void failed(Throwable exc, Void att) {
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
|
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
|
||||||
SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
|
SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
|
||||||
|
|
||||||
test(sa, true, false);
|
test(sa, true, false);
|
||||||
test(sa, false, true);
|
test(sa, false, true);
|
||||||
test(sa, true, true);
|
test(sa, true, true);
|
||||||
|
} finally {
|
||||||
// clean-up
|
// clean-up
|
||||||
listener.close();
|
synchronized (accepted) {
|
||||||
synchronized (accepted) {
|
for (AsynchronousSocketChannel ch: accepted) {
|
||||||
for (AsynchronousSocketChannel ch: accepted) {
|
ch.close();
|
||||||
ch.close();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,60 +88,60 @@ public class GroupOfOne {
|
|||||||
return new Thread(r);
|
return new Thread(r);
|
||||||
}});
|
}});
|
||||||
final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
|
final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
|
||||||
|
try {
|
||||||
|
// the latch counts down when:
|
||||||
|
// 1. The read operation fails (expected)
|
||||||
|
// 2. the close/shutdown completes
|
||||||
|
final CountDownLatch latch = new CountDownLatch(2);
|
||||||
|
|
||||||
// the latch counts down when:
|
ch.connect(sa, (Void)null, new CompletionHandler<Void,Void>() {
|
||||||
// 1. The read operation fails (expected)
|
public void completed(Void result, Void att) {
|
||||||
// 2. the close/shutdown completes
|
System.out.println("Connected");
|
||||||
final CountDownLatch latch = new CountDownLatch(2);
|
|
||||||
|
|
||||||
ch.connect(sa, (Void)null, new CompletionHandler<Void,Void>() {
|
// initiate I/O operation that does not complete (successfully)
|
||||||
public void completed(Void result, Void att) {
|
ByteBuffer buf = ByteBuffer.allocate(100);
|
||||||
System.out.println("Connected");
|
ch.read(buf, (Void)null, new CompletionHandler<Integer,Void>() {
|
||||||
|
public void completed(Integer bytesRead, Void att) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
public void failed(Throwable exc, Void att) {
|
||||||
|
if (!(exc instanceof AsynchronousCloseException))
|
||||||
|
throw new RuntimeException(exc);
|
||||||
|
System.out.println("Read failed (expected)");
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// initiate I/O operation that does not complete (successfully)
|
// close channel or shutdown group
|
||||||
ByteBuffer buf = ByteBuffer.allocate(100);
|
try {
|
||||||
ch.read(buf, (Void)null, new CompletionHandler<Integer,Void>() {
|
if (closeChannel) {
|
||||||
public void completed(Integer bytesRead, Void att) {
|
System.out.print("Close channel ...");
|
||||||
|
ch.close();
|
||||||
|
System.out.println(" done.");
|
||||||
|
}
|
||||||
|
if (shutdownGroup) {
|
||||||
|
System.out.print("Shutdown group ...");
|
||||||
|
group.shutdownNow();
|
||||||
|
System.out.println(" done.");
|
||||||
|
}
|
||||||
|
latch.countDown();
|
||||||
|
} catch (IOException e) {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
}
|
}
|
||||||
public void failed(Throwable exc, Void att) {
|
|
||||||
if (!(exc instanceof AsynchronousCloseException))
|
|
||||||
throw new RuntimeException(exc);
|
|
||||||
System.out.println("Read failed (expected)");
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// close channel or shutdown group
|
|
||||||
try {
|
|
||||||
if (closeChannel) {
|
|
||||||
System.out.print("Close channel ...");
|
|
||||||
ch.close();
|
|
||||||
System.out.println(" done.");
|
|
||||||
}
|
|
||||||
if (shutdownGroup) {
|
|
||||||
System.out.print("Shutdown group ...");
|
|
||||||
group.shutdownNow();
|
|
||||||
System.out.println(" done.");
|
|
||||||
}
|
|
||||||
latch.countDown();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException();
|
|
||||||
}
|
}
|
||||||
}
|
public void failed(Throwable exc, Void att) {
|
||||||
public void failed(Throwable exc, Void att) {
|
throw new RuntimeException(exc);
|
||||||
throw new RuntimeException(exc);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
latch.await();
|
|
||||||
|
|
||||||
// clean-up
|
|
||||||
group.shutdown();
|
|
||||||
boolean terminated = group.awaitTermination(20, TimeUnit.SECONDS);
|
|
||||||
if (!terminated)
|
|
||||||
throw new RuntimeException("Group did not terminate");
|
|
||||||
|
|
||||||
|
latch.await();
|
||||||
|
} finally {
|
||||||
|
// clean-up
|
||||||
|
group.shutdown();
|
||||||
|
boolean terminated = group.awaitTermination(20, TimeUnit.SECONDS);
|
||||||
|
if (!terminated)
|
||||||
|
throw new RuntimeException("Group did not terminate");
|
||||||
|
}
|
||||||
System.out.println("TEST OKAY");
|
System.out.println("TEST OKAY");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -76,89 +76,91 @@ public class Identity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
// create listener to accept connections
|
|
||||||
final AsynchronousServerSocketChannel listener =
|
|
||||||
AsynchronousServerSocketChannel.open()
|
|
||||||
.bind(new InetSocketAddress(0));
|
|
||||||
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
|
|
||||||
public void completed(final AsynchronousSocketChannel ch, Void att) {
|
|
||||||
listener.accept((Void)null, this);
|
|
||||||
final ByteBuffer buf = ByteBuffer.allocate(100);
|
|
||||||
ch.read(buf, ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
|
|
||||||
public void completed(Integer bytesRead, AsynchronousSocketChannel ch) {
|
|
||||||
if (bytesRead < 0) {
|
|
||||||
try { ch.close(); } catch (IOException ignore) { }
|
|
||||||
} else {
|
|
||||||
buf.clear();
|
|
||||||
ch.read(buf, ch, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void failed(Throwable exc, AsynchronousSocketChannel ch) {
|
|
||||||
try { ch.close(); } catch (IOException ignore) { }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public void failed(Throwable exc, Void att) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
|
|
||||||
SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
|
|
||||||
|
|
||||||
// create 3-10 channels, each in its own group
|
// create 3-10 channels, each in its own group
|
||||||
final int groupCount = 3 + rand.nextInt(8);
|
final int groupCount = 3 + rand.nextInt(8);
|
||||||
AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[groupCount];
|
final AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[groupCount];
|
||||||
final AsynchronousSocketChannel[] channels = new AsynchronousSocketChannel[groupCount];
|
final AsynchronousSocketChannel[] channels = new AsynchronousSocketChannel[groupCount];
|
||||||
for (int i=0; i<groupCount; i++) {
|
|
||||||
ThreadFactory factory = createThreadFactory(i);
|
|
||||||
AsynchronousChannelGroup group;
|
|
||||||
if (rand.nextBoolean()) {
|
|
||||||
int nThreads = 1 + rand.nextInt(10);
|
|
||||||
group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
|
|
||||||
} else {
|
|
||||||
ExecutorService pool = Executors.newCachedThreadPool(factory);
|
|
||||||
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
|
|
||||||
}
|
|
||||||
groups[i] = group;
|
|
||||||
|
|
||||||
// create channel in group and connect it to the server
|
// create listener to accept connections
|
||||||
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
|
try (final AsynchronousServerSocketChannel listener =
|
||||||
ch.connect(sa).get();
|
AsynchronousServerSocketChannel.open()) {
|
||||||
channels[i] = ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
// randomly write to each channel, ensuring that the completion handler
|
listener.bind(new InetSocketAddress(0));
|
||||||
// is always invoked by a thread with the right identity.
|
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
|
||||||
final AtomicInteger writeCount = new AtomicInteger(100);
|
public void completed(final AsynchronousSocketChannel ch, Void att) {
|
||||||
channels[0].write(getBuffer(), 0, new CompletionHandler<Integer,Integer>() {
|
listener.accept((Void)null, this);
|
||||||
public void completed(Integer bytesWritten, Integer groupId) {
|
final ByteBuffer buf = ByteBuffer.allocate(100);
|
||||||
if (bytesWritten != 1)
|
ch.read(buf, ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
|
||||||
fail("Expected 1 byte to be written");
|
public void completed(Integer bytesRead, AsynchronousSocketChannel ch) {
|
||||||
if (!myGroup.get().equals(groupId))
|
if (bytesRead < 0) {
|
||||||
fail("Handler invoked by thread with the wrong identity");
|
try { ch.close(); } catch (IOException ignore) { }
|
||||||
if (writeCount.decrementAndGet() > 0) {
|
} else {
|
||||||
int id = rand.nextInt(groupCount);
|
buf.clear();
|
||||||
channels[id].write(getBuffer(), id, this);
|
ch.read(buf, ch, this);
|
||||||
} else {
|
}
|
||||||
done.countDown();
|
}
|
||||||
|
public void failed(Throwable exc, AsynchronousSocketChannel ch) {
|
||||||
|
try { ch.close(); } catch (IOException ignore) { }
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
public void failed(Throwable exc, Void att) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
|
||||||
|
SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
|
||||||
|
|
||||||
|
for (int i=0; i<groupCount; i++) {
|
||||||
|
ThreadFactory factory = createThreadFactory(i);
|
||||||
|
AsynchronousChannelGroup group;
|
||||||
|
if (rand.nextBoolean()) {
|
||||||
|
int nThreads = 1 + rand.nextInt(10);
|
||||||
|
group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
|
||||||
|
} else {
|
||||||
|
ExecutorService pool = Executors.newCachedThreadPool(factory);
|
||||||
|
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
|
||||||
|
}
|
||||||
|
groups[i] = group;
|
||||||
|
|
||||||
|
// create channel in group and connect it to the server
|
||||||
|
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
|
||||||
|
ch.connect(sa).get();
|
||||||
|
channels[i] = ch;
|
||||||
}
|
}
|
||||||
public void failed(Throwable exc, Integer groupId) {
|
|
||||||
fail(exc.getMessage());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// wait until done
|
// randomly write to each channel, ensuring that the completion handler
|
||||||
done.await();
|
// is always invoked by a thread with the right identity.
|
||||||
|
final AtomicInteger writeCount = new AtomicInteger(100);
|
||||||
|
channels[0].write(getBuffer(), 0, new CompletionHandler<Integer,Integer>() {
|
||||||
|
public void completed(Integer bytesWritten, Integer groupId) {
|
||||||
|
if (bytesWritten != 1)
|
||||||
|
fail("Expected 1 byte to be written");
|
||||||
|
if (!myGroup.get().equals(groupId))
|
||||||
|
fail("Handler invoked by thread with the wrong identity");
|
||||||
|
if (writeCount.decrementAndGet() > 0) {
|
||||||
|
int id = rand.nextInt(groupCount);
|
||||||
|
channels[id].write(getBuffer(), id, this);
|
||||||
|
} else {
|
||||||
|
done.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void failed(Throwable exc, Integer groupId) {
|
||||||
|
fail(exc.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// clean-up
|
// wait until done
|
||||||
for (AsynchronousSocketChannel ch: channels)
|
done.await();
|
||||||
ch.close();
|
} finally {
|
||||||
for (AsynchronousChannelGroup group: groups)
|
// clean-up
|
||||||
group.shutdownNow();
|
for (AsynchronousSocketChannel ch: channels)
|
||||||
listener.close();
|
ch.close();
|
||||||
|
for (AsynchronousChannelGroup group: groups)
|
||||||
|
group.shutdownNow();
|
||||||
|
|
||||||
if (failed.get())
|
if (failed.get())
|
||||||
throw new RuntimeException("Test failed - see log for details");
|
throw new RuntimeException("Test failed - see log for details");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ByteBuffer getBuffer() {
|
static ByteBuffer getBuffer() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -66,21 +66,30 @@ public class Restart {
|
|||||||
// group with fixed thread pool
|
// group with fixed thread pool
|
||||||
int nThreads = 1 + rand.nextInt(4);
|
int nThreads = 1 + rand.nextInt(4);
|
||||||
AsynchronousChannelGroup group =
|
AsynchronousChannelGroup group =
|
||||||
AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
|
AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
|
||||||
testRestart(group, 100);
|
try {
|
||||||
group.shutdown();
|
testRestart(group, 100);
|
||||||
|
} finally {
|
||||||
|
group.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
// group with cached thread pool
|
// group with cached thread pool
|
||||||
ExecutorService pool = Executors.newCachedThreadPool(factory);
|
ExecutorService pool = Executors.newCachedThreadPool(factory);
|
||||||
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
|
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
|
||||||
testRestart(group, 100);
|
try {
|
||||||
group.shutdown();
|
testRestart(group, 100);
|
||||||
|
} finally {
|
||||||
|
group.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
// group with custom thread pool
|
// group with custom thread pool
|
||||||
group = AsynchronousChannelGroup
|
group = AsynchronousChannelGroup.withThreadPool(
|
||||||
.withThreadPool(Executors.newFixedThreadPool(1+rand.nextInt(5), factory));
|
Executors.newFixedThreadPool(1+rand.nextInt(5), factory));
|
||||||
testRestart(group, 100);
|
try {
|
||||||
group.shutdown();
|
testRestart(group, 100);
|
||||||
|
} finally {
|
||||||
|
group.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
// give time for threads to terminate
|
// give time for threads to terminate
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
@ -92,45 +101,43 @@ public class Restart {
|
|||||||
static void testRestart(AsynchronousChannelGroup group, int count)
|
static void testRestart(AsynchronousChannelGroup group, int count)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
AsynchronousServerSocketChannel listener =
|
try (AsynchronousServerSocketChannel listener =
|
||||||
AsynchronousServerSocketChannel.open(group)
|
AsynchronousServerSocketChannel.open(group)) {
|
||||||
.bind(new InetSocketAddress(0));
|
|
||||||
|
|
||||||
for (int i=0; i<count; i++) {
|
listener.bind(new InetSocketAddress(0));
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
for (int i=0; i<count; i++) {
|
||||||
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
|
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
|
||||||
public void completed(AsynchronousSocketChannel ch, Void att) {
|
public void completed(AsynchronousSocketChannel ch, Void att) {
|
||||||
try {
|
try {
|
||||||
ch.close();
|
ch.close();
|
||||||
} catch (IOException ignore) { }
|
} catch (IOException ignore) { }
|
||||||
|
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
|
|
||||||
// throw error or runtime exception
|
// throw error or runtime exception
|
||||||
if (rand.nextBoolean()) {
|
if (rand.nextBoolean()) {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
public void failed(Throwable exc, Void att) {
|
||||||
public void failed(Throwable exc, Void att) {
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// establish loopback connection which should cause completion
|
// establish loopback connection which should cause completion
|
||||||
// handler to be invoked.
|
// handler to be invoked.
|
||||||
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
|
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
|
||||||
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
|
try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()) {
|
||||||
InetAddress lh = InetAddress.getLocalHost();
|
InetAddress lh = InetAddress.getLocalHost();
|
||||||
ch.connect(new InetSocketAddress(lh, port)).get();
|
ch.connect(new InetSocketAddress(lh, port)).get();
|
||||||
ch.close();
|
}
|
||||||
|
|
||||||
// wait for handler to be invoked
|
// wait for handler to be invoked
|
||||||
latch.await();
|
latch.await();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean-up
|
|
||||||
listener.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,8 +22,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* @test
|
/* @test
|
||||||
* @bug 4429043 4493595 6332756 6709457
|
* @bug 4429043 4493595 6332756 6709457 7146506
|
||||||
* @summary The FileChannel file locking
|
* @summary Test FileChannel file locking
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@ -33,17 +33,14 @@ import static java.nio.file.StandardOpenOption.*;
|
|||||||
/**
|
/**
|
||||||
* Testing FileChannel's lock method.
|
* Testing FileChannel's lock method.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Lock {
|
public class Lock {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
if (args.length > 0) {
|
if (args.length == 2) {
|
||||||
if(args[0].equals("1")) {
|
attemptLock(args[1], args[0].equals("2"));
|
||||||
MadWriter mw = new MadWriter(args[1], false);
|
|
||||||
} else {
|
|
||||||
MadWriter mw = new MadWriter(args[1], true);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
|
} else if (args.length != 0) {
|
||||||
|
throw new RuntimeException("Wrong number of parameters.");
|
||||||
}
|
}
|
||||||
File blah = File.createTempFile("blah", null);
|
File blah = File.createTempFile("blah", null);
|
||||||
blah.deleteOnExit();
|
blah.deleteOnExit();
|
||||||
@ -56,120 +53,128 @@ public class Lock {
|
|||||||
test2(blah, false);
|
test2(blah, false);
|
||||||
test3(blah);
|
test3(blah);
|
||||||
test4(blah);
|
test4(blah);
|
||||||
blah.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void test2(File blah, boolean b) throws Exception {
|
|
||||||
RandomAccessFile raf = new RandomAccessFile(blah, "rw");
|
|
||||||
FileChannel channel = raf.getChannel();
|
|
||||||
FileLock lock;
|
|
||||||
if (b)
|
|
||||||
lock = channel.lock();
|
|
||||||
else
|
|
||||||
lock = channel.tryLock();
|
|
||||||
lock.release();
|
|
||||||
channel.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test mutual locking with other process
|
||||||
|
*/
|
||||||
static void test1(File blah, String str) throws Exception {
|
static void test1(File blah, String str) throws Exception {
|
||||||
|
try (RandomAccessFile fis = new RandomAccessFile(blah, "rw")) {
|
||||||
|
FileChannel fc = fis.getChannel();
|
||||||
|
FileLock lock = null;
|
||||||
|
|
||||||
// Grab the lock
|
// grab the lock
|
||||||
RandomAccessFile fis = new RandomAccessFile(blah, "rw");
|
if (str.equals("1")) {
|
||||||
FileChannel fc = fis.getChannel();
|
lock = fc.lock(0, 10, false);
|
||||||
FileLock lock = null;
|
if (lock == null)
|
||||||
|
throw new RuntimeException("Lock should not return null");
|
||||||
if (str.equals("1")) {
|
try {
|
||||||
lock = fc.lock(0, 10, false);
|
fc.lock(5, 10, false);
|
||||||
if (lock == null)
|
throw new RuntimeException("Overlapping locks allowed");
|
||||||
throw new RuntimeException("Lock should not return null");
|
} catch (OverlappingFileLockException e) {} // correct result
|
||||||
try {
|
|
||||||
FileLock lock2 = fc.lock(5, 10, false);
|
|
||||||
throw new RuntimeException("Overlapping locks allowed");
|
|
||||||
} catch (OverlappingFileLockException e) {
|
|
||||||
// Correct result
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Exec the tamperer
|
// execute the tamperer
|
||||||
String command = System.getProperty("java.home") +
|
String command = System.getProperty("java.home") +
|
||||||
File.separator + "bin" + File.separator + "java";
|
File.separator + "bin" + File.separator + "java";
|
||||||
String testClasses = System.getProperty("test.classes");
|
String testClasses = System.getProperty("test.classes");
|
||||||
if (testClasses != null)
|
if (testClasses != null)
|
||||||
command += " -cp " + testClasses;
|
command += " -cp " + testClasses;
|
||||||
command += " Lock " + str + " " + blah;
|
command += " Lock " + str + " " + blah;
|
||||||
Process p = Runtime.getRuntime().exec(command);
|
Process p = Runtime.getRuntime().exec(command);
|
||||||
|
|
||||||
BufferedReader in = new BufferedReader
|
// evaluate System.out of child process
|
||||||
(new InputStreamReader(p.getInputStream()));
|
String s;
|
||||||
|
boolean hasOutput = false;
|
||||||
String s;
|
InputStreamReader isr;
|
||||||
int count = 0;
|
isr = new InputStreamReader(p.getInputStream());
|
||||||
while ((s = in.readLine()) != null) {
|
BufferedReader br = new BufferedReader(isr);
|
||||||
if (!s.equals("good")) {
|
while ((s = br.readLine()) != null) {
|
||||||
if (File.separatorChar == '/') {
|
// only throw on Unix as windows over NFS fails...
|
||||||
// Fails on windows over NFS...
|
if ((File.separatorChar == '/') && !s.equals("good")) {
|
||||||
throw new RuntimeException("Failed: "+s);
|
throw new RuntimeException("Failed: " + s);
|
||||||
}
|
}
|
||||||
|
hasOutput = true;
|
||||||
}
|
}
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0) {
|
// evaluate System.err in case of System.out of child process
|
||||||
in = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
// was empty
|
||||||
while ((s = in.readLine()) != null) {
|
if (!hasOutput) {
|
||||||
System.err.println("Error output: " + s);
|
isr = new InputStreamReader(p.getErrorStream());
|
||||||
|
br = new BufferedReader(isr);
|
||||||
|
if ((s = br.readLine()) != null) {
|
||||||
|
System.err.println("Error output:");
|
||||||
|
System.err.println(s);
|
||||||
|
while ((s = br.readLine()) != null) {
|
||||||
|
System.err.println(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Failed, no output");
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Failed, no output");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up
|
// clean up, check multiple releases
|
||||||
if (lock != null) {
|
if (lock != null) {
|
||||||
/* Check multiple releases */
|
lock.release();
|
||||||
lock.release();
|
lock.release();
|
||||||
lock.release();
|
}
|
||||||
}
|
}
|
||||||
fc.close();
|
|
||||||
fis.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The overlap check for file locks should be JVM-wide
|
/**
|
||||||
private static void test3(File blah) throws Exception {
|
* Basic test for FileChannel.lock() and FileChannel.tryLock()
|
||||||
FileChannel fc1 = new RandomAccessFile(blah, "rw").getChannel();
|
*/
|
||||||
FileChannel fc2 = new RandomAccessFile(blah, "rw").getChannel();
|
static void test2(File blah, boolean b) throws Exception {
|
||||||
|
try (RandomAccessFile raf = new RandomAccessFile(blah, "rw")) {
|
||||||
// lock via one channel, and then attempt to lock the same file
|
FileChannel channel = raf.getChannel();
|
||||||
// using a second channel
|
FileLock lock;
|
||||||
FileLock fl1 = fc1.lock();
|
if (b)
|
||||||
try {
|
lock = channel.lock();
|
||||||
fc2.tryLock();
|
else
|
||||||
throw new RuntimeException("Overlapping locks allowed");
|
lock = channel.tryLock();
|
||||||
} catch (OverlappingFileLockException x) {
|
lock.release();
|
||||||
}
|
}
|
||||||
try {
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that overlapping file locking is not possible when using different
|
||||||
|
* FileChannel objects to the same file path
|
||||||
|
*/
|
||||||
|
static void test3(File blah) throws Exception {
|
||||||
|
try (RandomAccessFile raf1 = new RandomAccessFile(blah, "rw");
|
||||||
|
RandomAccessFile raf2 = new RandomAccessFile(blah, "rw"))
|
||||||
|
{
|
||||||
|
FileChannel fc1 = raf1.getChannel();
|
||||||
|
FileChannel fc2 = raf2.getChannel();
|
||||||
|
|
||||||
|
// lock via one channel, and then attempt to lock the same file
|
||||||
|
// using a second channel
|
||||||
|
FileLock fl1 = fc1.lock();
|
||||||
|
try {
|
||||||
|
fc2.tryLock();
|
||||||
|
throw new RuntimeException("Overlapping locks allowed");
|
||||||
|
} catch (OverlappingFileLockException x) {}
|
||||||
|
try {
|
||||||
|
fc2.lock();
|
||||||
|
throw new RuntimeException("Overlapping locks allowed");
|
||||||
|
} catch (OverlappingFileLockException x) {}
|
||||||
|
|
||||||
|
// release lock and the attempt to lock with the second channel
|
||||||
|
// should succeed.
|
||||||
|
fl1.release();
|
||||||
fc2.lock();
|
fc2.lock();
|
||||||
throw new RuntimeException("Overlapping locks allowed");
|
try {
|
||||||
} catch (OverlappingFileLockException x) {
|
fc1.lock();
|
||||||
|
throw new RuntimeException("Overlapping locks allowed");
|
||||||
|
} catch (OverlappingFileLockException x) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// release lock and the attempt to lock with the second channel
|
|
||||||
// should succeed.
|
|
||||||
fl1.release();
|
|
||||||
FileLock fl2 = fc2.lock();
|
|
||||||
try {
|
|
||||||
fc1.lock();
|
|
||||||
throw new RuntimeException("Overlapping locks allowed");
|
|
||||||
} catch (OverlappingFileLockException x) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fc1.close();
|
|
||||||
fc2.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test file locking when file is opened for append
|
* Test file locking when file is opened for append
|
||||||
*/
|
*/
|
||||||
static void test4(File blah) throws Exception {
|
static void test4(File blah) throws Exception {
|
||||||
try (FileChannel fc = new FileOutputStream(blah, true).getChannel()) {
|
try (FileOutputStream fos = new FileOutputStream(blah, true)) {
|
||||||
|
FileChannel fc = fos.getChannel();
|
||||||
fc.tryLock().release();
|
fc.tryLock().release();
|
||||||
fc.tryLock(0L, 1L, false).release();
|
fc.tryLock(0L, 1L, false).release();
|
||||||
fc.lock().release();
|
fc.lock().release();
|
||||||
@ -182,30 +187,31 @@ public class Lock {
|
|||||||
fc.lock(0L, 1L, false).release();
|
fc.lock(0L, 1L, false).release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class MadWriter {
|
/**
|
||||||
public MadWriter(String s, boolean b) throws Exception {
|
* Utility method to be run in secondary process which tries to acquire a
|
||||||
File f = new File(s);
|
* lock on a FileChannel
|
||||||
RandomAccessFile fos = new RandomAccessFile(f, "rw");
|
*/
|
||||||
FileChannel fc = fos.getChannel();
|
static void attemptLock(String fileName,
|
||||||
if (fc.tryLock(10, 10, false) == null) {
|
boolean expectsLock) throws Exception
|
||||||
System.out.println("bad: Failed to grab adjacent lock");
|
{
|
||||||
|
File f = new File(fileName);
|
||||||
|
try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) {
|
||||||
|
FileChannel fc = raf.getChannel();
|
||||||
|
if (fc.tryLock(10, 10, false) == null) {
|
||||||
|
System.out.println("bad: Failed to grab adjacent lock");
|
||||||
|
}
|
||||||
|
if (fc.tryLock(0, 10, false) == null) {
|
||||||
|
if (expectsLock)
|
||||||
|
System.out.println("bad");
|
||||||
|
else
|
||||||
|
System.out.println("good");
|
||||||
|
} else {
|
||||||
|
if (expectsLock)
|
||||||
|
System.out.println("good");
|
||||||
|
else
|
||||||
|
System.out.println("bad");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FileLock lock = fc.tryLock(0, 10, false);
|
|
||||||
if (lock == null) {
|
|
||||||
if (b)
|
|
||||||
System.out.println("bad");
|
|
||||||
else
|
|
||||||
System.out.println("good");
|
|
||||||
} else {
|
|
||||||
if (b)
|
|
||||||
System.out.println("good");
|
|
||||||
else
|
|
||||||
System.out.println("bad");
|
|
||||||
}
|
|
||||||
fc.close();
|
|
||||||
fos.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public class Basic {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int checkContentTypes(String[] extensions, String[][] expectedTypes)
|
static int checkContentTypes(String[] extensions, String[] expectedTypes)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (extensions.length != expectedTypes.length) {
|
if (extensions.length != expectedTypes.length) {
|
||||||
System.err.println("Parameter array lengths differ");
|
System.err.println("Parameter array lengths differ");
|
||||||
@ -112,27 +112,10 @@ public class Basic {
|
|||||||
System.err.println("Content type of " + extension
|
System.err.println("Content type of " + extension
|
||||||
+ " cannot be determined");
|
+ " cannot be determined");
|
||||||
failures++;
|
failures++;
|
||||||
} else {
|
} else if (!type.equals(expectedTypes[i])) {
|
||||||
boolean isTypeFound = false;
|
System.err.printf("Content type: %s; expected: %s%n",
|
||||||
for (String s : expectedTypes[i]) {
|
type, expectedTypes);
|
||||||
if (type.equals(s)) {
|
failures++;
|
||||||
isTypeFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isTypeFound) {
|
|
||||||
System.err.printf("Content type: %s; expected: ", type);
|
|
||||||
int j = 0;
|
|
||||||
for (String s : expectedTypes[i]) {
|
|
||||||
if (j++ == 0) {
|
|
||||||
System.err.printf("%s", s);
|
|
||||||
} else {
|
|
||||||
System.err.printf(", or %s", s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.err.println();
|
|
||||||
failures++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
Files.delete(file);
|
Files.delete(file);
|
||||||
@ -174,8 +157,6 @@ public class Basic {
|
|||||||
|
|
||||||
// Verify that certain media extensions are mapped to the correct type.
|
// Verify that certain media extensions are mapped to the correct type.
|
||||||
String[] extensions = new String[]{
|
String[] extensions = new String[]{
|
||||||
"aac",
|
|
||||||
"flac",
|
|
||||||
"jpg",
|
"jpg",
|
||||||
"mp3",
|
"mp3",
|
||||||
"mp4",
|
"mp4",
|
||||||
@ -183,15 +164,13 @@ public class Basic {
|
|||||||
"png",
|
"png",
|
||||||
"webm"
|
"webm"
|
||||||
};
|
};
|
||||||
String[][] expectedTypes = new String[][] {
|
String[] expectedTypes = new String[] {
|
||||||
{"audio/aac", "audio/x-aac", "audio/vnd.dlna.adts"},
|
"image/jpeg",
|
||||||
{"audio/flac", "audio/x-flac"},
|
"audio/mpeg",
|
||||||
{"image/jpeg"},
|
"video/mp4",
|
||||||
{"audio/mpeg"},
|
"application/pdf",
|
||||||
{"video/mp4"},
|
"image/png",
|
||||||
{"application/pdf"},
|
"video/webm"
|
||||||
{"image/png"},
|
|
||||||
{"video/webm"}
|
|
||||||
};
|
};
|
||||||
failures += checkContentTypes(extensions, expectedTypes);
|
failures += checkContentTypes(extensions, expectedTypes);
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -53,10 +53,11 @@ public class LotsOfCancels {
|
|||||||
Path testDir = Paths.get(System.getProperty("test.dir", "."));
|
Path testDir = Paths.get(System.getProperty("test.dir", "."));
|
||||||
Path top = Files.createTempDirectory(testDir, "LotsOfCancels");
|
Path top = Files.createTempDirectory(testDir, "LotsOfCancels");
|
||||||
for (int i=1; i<=16; i++) {
|
for (int i=1; i<=16; i++) {
|
||||||
|
int id = i;
|
||||||
Path dir = Files.createDirectory(top.resolve("dir-" + i));
|
Path dir = Files.createDirectory(top.resolve("dir-" + i));
|
||||||
WatchService watcher = FileSystems.getDefault().newWatchService();
|
WatchService watcher = FileSystems.getDefault().newWatchService();
|
||||||
pool.submit(() -> handle(dir, watcher));
|
pool.submit(() -> handle(id, dir, watcher));
|
||||||
pool.submit(() -> poll(watcher));
|
pool.submit(() -> poll(id, watcher));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
pool.shutdown();
|
pool.shutdown();
|
||||||
@ -74,7 +75,8 @@ public class LotsOfCancels {
|
|||||||
* Stress the given WatchService, specifically the cancel method, in
|
* Stress the given WatchService, specifically the cancel method, in
|
||||||
* the given directory. Closes the WatchService when done.
|
* the given directory. Closes the WatchService when done.
|
||||||
*/
|
*/
|
||||||
static void handle(Path dir, WatchService watcher) {
|
static void handle(int id, Path dir, WatchService watcher) {
|
||||||
|
System.out.printf("begin handle %d%n", id);
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
Path file = dir.resolve("anyfile");
|
Path file = dir.resolve("anyfile");
|
||||||
@ -85,12 +87,15 @@ public class LotsOfCancels {
|
|||||||
key.cancel();
|
key.cancel();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
System.out.printf("WatchService %d closing ...%n", id);
|
||||||
watcher.close();
|
watcher.close();
|
||||||
|
System.out.printf("WatchService %d closed %n", id);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
System.out.printf("end handle %d%n", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,7 +103,8 @@ public class LotsOfCancels {
|
|||||||
* queue drained, it also hogs a CPU core which seems necessary to
|
* queue drained, it also hogs a CPU core which seems necessary to
|
||||||
* tickle the original bug.
|
* tickle the original bug.
|
||||||
*/
|
*/
|
||||||
static void poll(WatchService watcher) {
|
static void poll(int id, WatchService watcher) {
|
||||||
|
System.out.printf("begin poll %d%n", id);
|
||||||
try {
|
try {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
WatchKey key = watcher.take();
|
WatchKey key = watcher.take();
|
||||||
@ -108,10 +114,12 @@ public class LotsOfCancels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ClosedWatchServiceException expected) {
|
} catch (ClosedWatchServiceException expected) {
|
||||||
// nothing to do
|
// nothing to do but print
|
||||||
|
System.out.printf("poll %d expected exception %s%n", id, expected);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
System.out.printf("end poll %d%n", id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -33,6 +33,9 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import static java.nio.file.StandardWatchEventKinds.*;
|
import static java.nio.file.StandardWatchEventKinds.*;
|
||||||
|
|
||||||
public class UpdateInterference {
|
public class UpdateInterference {
|
||||||
|
|
||||||
|
private static volatile boolean stop;
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, InterruptedException {
|
public static void main(String[] args) throws IOException, InterruptedException {
|
||||||
final Path root = Files.createTempDirectory("test");
|
final Path root = Files.createTempDirectory("test");
|
||||||
final Path foo = root.resolve("foo");
|
final Path foo = root.resolve("foo");
|
||||||
@ -43,64 +46,89 @@ public class UpdateInterference {
|
|||||||
Files.createDirectory(bar);
|
Files.createDirectory(bar);
|
||||||
Files.createDirectory(baz);
|
Files.createDirectory(baz);
|
||||||
|
|
||||||
final WatchService watcher = root.getFileSystem().newWatchService();
|
try (final WatchService watcher = root.getFileSystem().newWatchService()) {
|
||||||
final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE);
|
final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE);
|
||||||
final WatchKey barKey = bar.register(watcher, ENTRY_CREATE);
|
final WatchKey barKey = bar.register(watcher, ENTRY_CREATE);
|
||||||
|
|
||||||
new Thread() {
|
Thread t1 = null;
|
||||||
{ setDaemon(true); }
|
Thread t2 = null;
|
||||||
|
try {
|
||||||
|
t1 = new Thread() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true) {
|
while (!stop) {
|
||||||
try {
|
try {
|
||||||
final Path temp = Files.createTempFile(foo, "temp", ".tmp");
|
final Path temp = Files.createTempFile(foo, "temp", ".tmp");
|
||||||
Files.delete(temp);
|
Files.delete(temp);
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
|
|
||||||
new Thread() {
|
|
||||||
{ setDaemon(true); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
WatchKey bazKeys[] = new WatchKey[32];
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
for( int i = 0; i < bazKeys.length; i++) {
|
|
||||||
bazKeys[i] = baz.register(watcher, ENTRY_CREATE);
|
|
||||||
}
|
}
|
||||||
for( int i = 0; i < bazKeys.length; i++) {
|
|
||||||
bazKeys[i].cancel();
|
|
||||||
}
|
|
||||||
Thread.sleep(1);
|
|
||||||
} catch (IOException | InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
t2 = new Thread() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
WatchKey bazKeys[] = new WatchKey[32];
|
||||||
|
while (!stop) {
|
||||||
|
try {
|
||||||
|
for( int i = 0; i < bazKeys.length; i++) {
|
||||||
|
bazKeys[i] = baz.register(watcher, ENTRY_CREATE);
|
||||||
|
}
|
||||||
|
for( int i = 0; i < bazKeys.length; i++) {
|
||||||
|
bazKeys[i].cancel();
|
||||||
|
}
|
||||||
|
Thread.sleep(1);
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
while ((System.currentTimeMillis() - time) < 15000) {
|
||||||
|
final WatchKey key = watcher.poll(60, TimeUnit.SECONDS);
|
||||||
|
if (key == null) continue;
|
||||||
|
|
||||||
|
if (key != fooKey) {
|
||||||
|
List<WatchEvent<?>> pollEvents = key.pollEvents();
|
||||||
|
for (WatchEvent<?> watchEvent : pollEvents) {
|
||||||
|
System.out.println(watchEvent.count() + " " +
|
||||||
|
watchEvent.kind() + " " +
|
||||||
|
watchEvent.context());
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Event received for unexpected key");
|
||||||
|
}
|
||||||
|
key.reset();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// the threads should stop before WatchService is closed
|
||||||
|
// to avoid ClosedWatchServiceException
|
||||||
|
stop = true;
|
||||||
|
|
||||||
|
// wait for threads to finish
|
||||||
|
if (t1 != null) {
|
||||||
|
t1.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t2 != null) {
|
||||||
|
t2.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.start();
|
} finally {
|
||||||
|
// clean up
|
||||||
long time = System.currentTimeMillis();
|
Files.delete(foo);
|
||||||
while ((System.currentTimeMillis() - time) < 15000) {
|
Files.delete(bar);
|
||||||
final WatchKey key = watcher.poll(60, TimeUnit.SECONDS);
|
Files.delete(baz);
|
||||||
if (key == null) continue;
|
Files.delete(root);
|
||||||
|
|
||||||
if (key != fooKey) {
|
|
||||||
List<WatchEvent<?>> pollEvents = key.pollEvents();
|
|
||||||
for (WatchEvent<?> watchEvent : pollEvents) {
|
|
||||||
System.out.println(watchEvent.count() + " " +
|
|
||||||
watchEvent.kind() + " " +
|
|
||||||
watchEvent.context());
|
|
||||||
}
|
|
||||||
throw new RuntimeException("Event received for unexpected key");
|
|
||||||
}
|
|
||||||
key.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -419,6 +419,21 @@ public class TCKZoneOffset extends AbstractDateTimeTest {
|
|||||||
ZoneOffset.ofHoursMinutesSeconds(-19, 0, 0);
|
ZoneOffset.ofHoursMinutesSeconds(-19, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions=DateTimeException.class)
|
||||||
|
public void test_factory_int_hours_minutes_seconds_minutesMinValue() {
|
||||||
|
ZoneOffset.ofHoursMinutesSeconds(0, Integer.MIN_VALUE, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions=DateTimeException.class)
|
||||||
|
public void test_factory_int_hours_minutes_seconds_secondsMinValue() {
|
||||||
|
ZoneOffset.ofHoursMinutesSeconds(0, 0, Integer.MIN_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions=DateTimeException.class)
|
||||||
|
public void test_factory_int_hours_minutes_seconds_minutesAndSecondsMinValue() {
|
||||||
|
ZoneOffset.ofHoursMinutesSeconds(0, Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
@Test
|
@Test
|
||||||
public void test_factory_ofTotalSeconds() {
|
public void test_factory_ofTotalSeconds() {
|
||||||
@ -437,6 +452,11 @@ public class TCKZoneOffset extends AbstractDateTimeTest {
|
|||||||
ZoneOffset.ofTotalSeconds(-18 * 60 * 60 - 1);
|
ZoneOffset.ofTotalSeconds(-18 * 60 * 60 - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions=DateTimeException.class)
|
||||||
|
public void test_factory_ofTotalSeconds_minValue() {
|
||||||
|
ZoneOffset.ofTotalSeconds(Integer.MIN_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
// from()
|
// from()
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
|
@ -359,6 +359,21 @@ public class ConcurrentHashMapTest extends JSR166TestCase {
|
|||||||
assertTrue(s.contains(five));
|
assertTrue(s.contains(five));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test keySet().removeAll on empty map
|
||||||
|
*/
|
||||||
|
public void testKeySet_empty_removeAll() {
|
||||||
|
ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
|
||||||
|
Set<Integer> set = map.keySet();
|
||||||
|
set.removeAll(Collections.emptyList());
|
||||||
|
assertTrue(map.isEmpty());
|
||||||
|
assertTrue(set.isEmpty());
|
||||||
|
// following is test for JDK-8163353
|
||||||
|
set.removeAll(Collections.emptySet());
|
||||||
|
assertTrue(map.isEmpty());
|
||||||
|
assertTrue(set.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* keySet.toArray returns contains all keys
|
* keySet.toArray returns contains all keys
|
||||||
*/
|
*/
|
||||||
|
@ -80,7 +80,7 @@ public class MultiReleaseJarAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try (JarFile jf = new JarFile(multirelease)) {
|
try (JarFile jf = new JarFile(multirelease)) {
|
||||||
Assert.assertFalse(jf.isMultiRelease());
|
Assert.assertTrue(jf.isMultiRelease());
|
||||||
}
|
}
|
||||||
|
|
||||||
try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Runtime.version())) {
|
try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Runtime.version())) {
|
||||||
|
96
jdk/test/javax/crypto/CryptoPermissions/TestUnlimited.java
Normal file
96
jdk/test/javax/crypto/CryptoPermissions/TestUnlimited.java
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8061842
|
||||||
|
* @summary Package jurisdiction policy files as something other than JAR
|
||||||
|
* @run main/othervm TestUnlimited "" exception
|
||||||
|
* @run main/othervm TestUnlimited limited fail
|
||||||
|
* @run main/othervm TestUnlimited unlimited pass
|
||||||
|
* @run main/othervm TestUnlimited unlimited/ pass
|
||||||
|
* @run main/othervm TestUnlimited NosuchDir exception
|
||||||
|
* @run main/othervm TestUnlimited . exception
|
||||||
|
* @run main/othervm TestUnlimited /tmp/unlimited exception
|
||||||
|
* @run main/othervm TestUnlimited ../policy/unlimited exception
|
||||||
|
* @run main/othervm TestUnlimited ./unlimited exception
|
||||||
|
* @run main/othervm TestUnlimited /unlimited exception
|
||||||
|
*/
|
||||||
|
import javax.crypto.*;
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
|
public class TestUnlimited {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
/*
|
||||||
|
* Override the Security property to allow for unlimited policy.
|
||||||
|
* Would need appropriate permissions if Security Manager were
|
||||||
|
* active.
|
||||||
|
*/
|
||||||
|
if (args.length != 2) {
|
||||||
|
throw new Exception("Two args required");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean expected = args[1].equals("pass");
|
||||||
|
boolean exception = args[1].equals("exception");
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
|
System.out.println("Testing: " + args[0]);
|
||||||
|
|
||||||
|
if (args[0].equals("\"\"")) {
|
||||||
|
Security.setProperty("crypto.policy", "");
|
||||||
|
} else {
|
||||||
|
Security.setProperty("crypto.policy", args[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use the AES as the test Cipher
|
||||||
|
* If there is an error initializing, we will never get past here.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
|
||||||
|
System.out.println("max AES key len:" + maxKeyLen);
|
||||||
|
if (maxKeyLen > 128) {
|
||||||
|
System.out.println("Unlimited policy is active");
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
System.out.println("Unlimited policy is NOT active");
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
if (!exception) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(
|
||||||
|
"Expected:\t" + expected + "\nResult:\t\t" + result);
|
||||||
|
if (expected != result) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("DONE!");
|
||||||
|
}
|
||||||
|
}
|
72
jdk/test/javax/xml/crypto/dsig/SecureValidationPolicy.java
Normal file
72
jdk/test/javax/xml/crypto/dsig/SecureValidationPolicy.java
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8151893
|
||||||
|
* @summary Tests for the jdk.xml.dsig.secureValidationPolicy security property
|
||||||
|
* @modules java.xml.crypto/org.jcp.xml.dsig.internal.dom
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.security.Security;
|
||||||
|
import java.util.List;
|
||||||
|
import org.jcp.xml.dsig.internal.dom.Policy;
|
||||||
|
|
||||||
|
public class SecureValidationPolicy {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
List<String> restrictedSchemes = List.of("file:/tmp/foo",
|
||||||
|
"http://java.com", "https://java.com");
|
||||||
|
List<String> restrictedAlgs = List.of(
|
||||||
|
"http://www.w3.org/TR/1999/REC-xslt-19991116",
|
||||||
|
"http://www.w3.org/2001/04/xmldsig-more#rsa-md5",
|
||||||
|
"http://www.w3.org/2001/04/xmldsig-more#hmac-md5",
|
||||||
|
"http://www.w3.org/2001/04/xmldsig-more#md5");
|
||||||
|
|
||||||
|
// Test expected defaults
|
||||||
|
System.out.println("Testing defaults");
|
||||||
|
if (!Policy.restrictNumTransforms(6)) {
|
||||||
|
throw new Exception("maxTransforms not enforced");
|
||||||
|
}
|
||||||
|
if (!Policy.restrictNumReferences(31)) {
|
||||||
|
throw new Exception("maxReferences not enforced");
|
||||||
|
}
|
||||||
|
for (String scheme : restrictedSchemes) {
|
||||||
|
if (!Policy.restrictReferenceUriScheme(scheme)) {
|
||||||
|
throw new Exception(scheme + " scheme not restricted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String alg : restrictedAlgs) {
|
||||||
|
if (!Policy.restrictAlg(alg)) {
|
||||||
|
throw new Exception(alg + " alg not restricted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!Policy.restrictDuplicateIds()) {
|
||||||
|
throw new Exception("noDuplicateIds not enforced");
|
||||||
|
}
|
||||||
|
if (!Policy.restrictRetrievalMethodLoops()) {
|
||||||
|
throw new Exception("noRetrievalMethodLoops not enforced");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,4 +3,4 @@
|
|||||||
TestNG.dirs = .
|
TestNG.dirs = .
|
||||||
|
|
||||||
javatest.maxOutputSize = 250000
|
javatest.maxOutputSize = 250000
|
||||||
modules = jdk.compiler
|
modules = jdk.compiler jdk.zipfs
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,6 +26,7 @@
|
|||||||
* @summary Verify the defining class loader of each module never delegates
|
* @summary Verify the defining class loader of each module never delegates
|
||||||
* to its child class loader. Also sanity check java.compact2
|
* to its child class loader. Also sanity check java.compact2
|
||||||
* requires.
|
* requires.
|
||||||
|
* @modules java.compact2
|
||||||
* @run testng/othervm --add-modules=ALL-SYSTEM VerifyModuleDelegation
|
* @run testng/othervm --add-modules=ALL-SYSTEM VerifyModuleDelegation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -33,7 +34,9 @@ import java.lang.module.ModuleDescriptor;
|
|||||||
import java.lang.module.ModuleFinder;
|
import java.lang.module.ModuleFinder;
|
||||||
import java.lang.module.ModuleReference;
|
import java.lang.module.ModuleReference;
|
||||||
import java.lang.reflect.Layer;
|
import java.lang.reflect.Layer;
|
||||||
|
import java.lang.reflect.Module;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import static java.util.stream.Collectors.toSet;
|
||||||
|
|
||||||
import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
|
import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
|
||||||
|
|
||||||
@ -58,8 +61,9 @@ public class VerifyModuleDelegation {
|
|||||||
.requires(Set.of(PUBLIC), "java.xml")
|
.requires(Set.of(PUBLIC), "java.xml")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private static final Set<ModuleReference> MREFS
|
private static final Set<ModuleDescriptor> MREFS
|
||||||
= ModuleFinder.ofSystem().findAll();
|
= Layer.boot().modules().stream().map(Module::getDescriptor)
|
||||||
|
.collect(toSet());
|
||||||
|
|
||||||
private void check(ModuleDescriptor md, ModuleDescriptor ref) {
|
private void check(ModuleDescriptor md, ModuleDescriptor ref) {
|
||||||
assertTrue(md.requires().size() == ref.requires().size());
|
assertTrue(md.requires().size() == ref.requires().size());
|
||||||
@ -69,7 +73,7 @@ public class VerifyModuleDelegation {
|
|||||||
@Test
|
@Test
|
||||||
public void checkJavaBase() {
|
public void checkJavaBase() {
|
||||||
ModuleDescriptor md =
|
ModuleDescriptor md =
|
||||||
MREFS.stream().map(ModuleReference::descriptor)
|
MREFS.stream()
|
||||||
.filter(d -> d.name().equals(JAVA_BASE))
|
.filter(d -> d.name().equals(JAVA_BASE))
|
||||||
.findFirst().orElseThrow(Error::new);
|
.findFirst().orElseThrow(Error::new);
|
||||||
|
|
||||||
@ -78,7 +82,7 @@ public class VerifyModuleDelegation {
|
|||||||
@Test
|
@Test
|
||||||
public void checkCompact2() {
|
public void checkCompact2() {
|
||||||
ModuleDescriptor md =
|
ModuleDescriptor md =
|
||||||
MREFS.stream().map(ModuleReference::descriptor)
|
MREFS.stream()
|
||||||
.filter(d -> d.name().equals(JAVA_COMPACT2))
|
.filter(d -> d.name().equals(JAVA_COMPACT2))
|
||||||
.findFirst().orElseThrow(Error::new);
|
.findFirst().orElseThrow(Error::new);
|
||||||
check(md, COMPACT2);
|
check(md, COMPACT2);
|
||||||
@ -87,7 +91,7 @@ public class VerifyModuleDelegation {
|
|||||||
@Test
|
@Test
|
||||||
public void checkLoaderDelegation() {
|
public void checkLoaderDelegation() {
|
||||||
Layer boot = Layer.boot();
|
Layer boot = Layer.boot();
|
||||||
MREFS.stream().map(ModuleReference::descriptor)
|
MREFS.stream()
|
||||||
.forEach(md -> md.requires().stream().forEach(req ->
|
.forEach(md -> md.requires().stream().forEach(req ->
|
||||||
{
|
{
|
||||||
// check if M requires D and D's loader must be either the
|
// check if M requires D and D's loader must be either the
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user