Merge
This commit is contained in:
commit
637fc0b863
@ -375,3 +375,4 @@ f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129
|
||||
d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130
|
||||
8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131
|
||||
a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132
|
||||
be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133
|
||||
|
@ -535,3 +535,4 @@ e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
|
||||
7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130
|
||||
943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
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,
|
||||
|
@ -155,7 +155,6 @@ public:
|
||||
void update_recent_gc_times(double end_time_sec, double elapsed_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;
|
||||
};
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "gc/g1/g1Analytics.hpp"
|
||||
#include "gc/g1/bufferingOopClosure.hpp"
|
||||
#include "gc/g1/concurrentG1Refine.hpp"
|
||||
#include "gc/g1/concurrentG1RefineThread.hpp"
|
||||
@ -2474,19 +2473,8 @@ size_t G1CollectedHeap::max_capacity() const {
|
||||
}
|
||||
|
||||
jlong G1CollectedHeap::millis_since_last_gc() {
|
||||
jlong now = os::elapsed_counter() / NANOSECS_PER_MILLISEC;
|
||||
const G1Analytics* analytics = _g1_policy->analytics();
|
||||
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;
|
||||
// assert(false, "NYI");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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->compute_pause_time_ratio(interval_ms, pause_time_ms);
|
||||
}
|
||||
|
@ -1256,21 +1256,21 @@ class GenTimeOfLastGCClosure: public GenCollectedHeap::GenClosure {
|
||||
};
|
||||
|
||||
jlong GenCollectedHeap::millis_since_last_gc() {
|
||||
// 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'.
|
||||
// We need a monotonically non-decreasing time in ms but
|
||||
// os::javaTimeMillis() does not guarantee monotonicity.
|
||||
jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
|
||||
GenTimeOfLastGCClosure tolgc_cl(now);
|
||||
// iterate over generations getting the oldest
|
||||
// time that a generation was collected
|
||||
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();
|
||||
if (retVal < 0) {
|
||||
log_warning(gc)("Detected clock going backwards. "
|
||||
"Milliseconds since last GC would be " JLONG_FORMAT
|
||||
". returning zero instead.", retVal);
|
||||
NOT_PRODUCT(log_warning(gc)("time warp: " JLONG_FORMAT, retVal);)
|
||||
return 0;
|
||||
}
|
||||
return retVal;
|
||||
|
@ -375,3 +375,4 @@ c40c8739bcdc88892ff58ebee3fd8a3f287be94d jdk-9+123
|
||||
6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130
|
||||
8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131
|
||||
d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
|
||||
3cdae27c90b5e41afe75eab904fda19fac076330 jdk-9+133
|
||||
|
@ -34,7 +34,7 @@ include GendataTZDB.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 := $(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
|
||||
|
||||
$(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC)
|
||||
$(call LogInfo, Generating java.security)
|
||||
$(call MakeDir, $(@D))
|
||||
$(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)
|
||||
|
||||
|
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 \
|
||||
-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.
|
||||
#
|
||||
# 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)) \
|
||||
$(LIBJAVA_HEADER_FLAGS) \
|
||||
-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, \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
$(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.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* (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 {
|
||||
|
||||
if (args.length < 4) {
|
||||
if (args.length < 5) {
|
||||
System.err.println("Usage: java MakeJavaSecurity " +
|
||||
"[input java.security file name] " +
|
||||
"[output java.security file name] " +
|
||||
"[openjdk target os] " +
|
||||
"[openjdk target cpu architecture]" +
|
||||
"[JCE jurisdiction policy directory]" +
|
||||
"[more restricted packages file name?]");
|
||||
|
||||
System.exit(1);
|
||||
@ -63,8 +65,8 @@ public class MakeJavaSecurity {
|
||||
|
||||
// more restricted packages
|
||||
List<String> extraLines;
|
||||
if (args.length == 5) {
|
||||
extraLines = Files.readAllLines(Paths.get(args[4]));
|
||||
if (args.length == 6) {
|
||||
extraLines = Files.readAllLines(Paths.get(args[5]));
|
||||
} else {
|
||||
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.
|
||||
// Not really necessary since a blank line follows.
|
||||
boolean inBlock = false;
|
||||
|
@ -986,8 +986,9 @@ final class CipherCore {
|
||||
if (padding != null) {
|
||||
int padStart = padding.unpad(outWithPadding, 0, outLen);
|
||||
if (padStart < 0) {
|
||||
throw new BadPaddingException("Given final block not "
|
||||
+ "properly padded");
|
||||
throw new BadPaddingException("Given final block not " +
|
||||
"properly padded. Such issues can arise if a bad key " +
|
||||
"is used during decryption.");
|
||||
}
|
||||
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
|
||||
* 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 initialize if {@code true} the class will be initialized.
|
||||
* 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
|
||||
* @exception ClassNotFoundException if the class cannot be located by
|
||||
* 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.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
|
||||
* 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
|
||||
* represents a primitive type or void, null is returned.
|
||||
*
|
||||
* @return the class loader that loaded the class or interface
|
||||
* represented by this object.
|
||||
* @throws SecurityException
|
||||
* if a security manager exists and its
|
||||
* {@code checkPermission} method denies
|
||||
* access to the class loader for the class.
|
||||
* @throws SecurityException
|
||||
* 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
|
||||
* 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 SecurityManager#checkPermission
|
||||
* @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
|
||||
* 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>
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager exists and its <tt>checkPermission</tt>
|
||||
* method doesn't allow access to this class loader's parent class
|
||||
* loader.
|
||||
* If a security manager is present, and the caller's class loader
|
||||
* is not {@code null} and is not an ancestor of this class loader,
|
||||
* and the caller does not have the
|
||||
* {@link RuntimePermission}{@code ("getClassLoader")}
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
@ -1590,12 +1581,11 @@ public abstract class ClassLoader {
|
||||
* @return The platform {@code ClassLoader}.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager exists and the caller's class loader is
|
||||
* not {@code null} and the caller's class loader is not the same
|
||||
* 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
|
||||
* as or an ancestor of the platform class loader,
|
||||
* and the {@link SecurityManager#checkPermission(java.security.Permission)
|
||||
* checkPermission} method denies {@code RuntimePermission("getClassLoader")}
|
||||
* to access the platform class loader.
|
||||
* and the caller does not have the
|
||||
* {@link RuntimePermission}{@code ("getClassLoader")}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@ -1636,17 +1626,6 @@ public abstract class ClassLoader {
|
||||
* If circular initialization of the system class loader is detected then
|
||||
* 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
|
||||
* examined until the VM is almost fully initialized. Code that executes
|
||||
* 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
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager exists and its <tt>checkPermission</tt>
|
||||
* method doesn't allow access to the system class loader.
|
||||
* 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
|
||||
* system class loader, and the caller does not have the
|
||||
* {@link RuntimePermission}{@code ("getClassLoader")}
|
||||
*
|
||||
* @throws IllegalStateException
|
||||
* If invoked recursively during the construction of the class
|
||||
|
@ -1370,8 +1370,13 @@ public final class Math {
|
||||
* result is positive zero.
|
||||
* <li>If the argument is infinite, the result is positive infinity.
|
||||
* <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
|
||||
* @return the absolute value of the argument.
|
||||
@ -1389,8 +1394,13 @@ public final class Math {
|
||||
* is positive zero.
|
||||
* <li>If the argument is infinite, the result is positive infinity.
|
||||
* <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
|
||||
* @return the absolute value of the argument.
|
||||
|
@ -1070,8 +1070,13 @@ public final class StrictMath {
|
||||
* result is positive zero.
|
||||
* <li>If the argument is infinite, the result is positive infinity.
|
||||
* <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
|
||||
* @return the absolute value of the argument.
|
||||
@ -1089,8 +1094,13 @@ public final class StrictMath {
|
||||
* is positive zero.
|
||||
* <li>If the argument is infinite, the result is positive infinity.
|
||||
* <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
|
||||
* @return the absolute value of the argument.
|
||||
|
@ -1507,28 +1507,25 @@ class Thread implements Runnable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the context ClassLoader for this Thread. The context
|
||||
* ClassLoader is provided by the creator of the thread for use
|
||||
* Returns the context {@code ClassLoader} for this thread. The context
|
||||
* {@code ClassLoader} is provided by the creator of the thread for use
|
||||
* by code running in this thread when loading classes and resources.
|
||||
* 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
|
||||
* 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
|
||||
* bootstrap class loader)
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
@ -497,6 +497,10 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||
String shortTypes = LambdaForm.shortenSignature(types);
|
||||
String className = SPECIES_CLASS_PREFIX + shortTypes;
|
||||
Class<?> c = BootLoader.loadClassOrNull(className);
|
||||
if (TRACE_RESOLVE) {
|
||||
System.out.println("[BMH_RESOLVE] " + shortTypes +
|
||||
(c != null ? " (success)" : " (fail)") );
|
||||
}
|
||||
if (c != null) {
|
||||
return c.asSubclass(BoundMethodHandle.class);
|
||||
} else {
|
||||
|
@ -492,7 +492,7 @@ class DirectMethodHandle extends MethodHandle {
|
||||
}
|
||||
|
||||
// Caching machinery for field accessors:
|
||||
private static final byte
|
||||
static final byte
|
||||
AF_GETFIELD = 0,
|
||||
AF_PUTFIELD = 1,
|
||||
AF_GETSTATIC = 2,
|
||||
@ -502,7 +502,7 @@ class DirectMethodHandle extends MethodHandle {
|
||||
AF_LIMIT = 6;
|
||||
// Enumerate the different field kinds using Wrapper,
|
||||
// with an extra case added for checked references.
|
||||
private static final int
|
||||
static final int
|
||||
FT_LAST_WRAPPER = Wrapper.COUNT-1,
|
||||
FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
|
||||
FT_CHECKED_REF = FT_LAST_WRAPPER+1,
|
||||
@ -515,7 +515,7 @@ class DirectMethodHandle extends MethodHandle {
|
||||
@Stable
|
||||
private static final LambdaForm[] ACCESSOR_FORMS
|
||||
= new LambdaForm[afIndex(AF_LIMIT, false, 0)];
|
||||
private static int ftypeKind(Class<?> ftype) {
|
||||
static int ftypeKind(Class<?> ftype) {
|
||||
if (ftype.isPrimitive())
|
||||
return Wrapper.forPrimitiveType(ftype).ordinal();
|
||||
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 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 isStatic = (formOp >= AF_GETSTATIC);
|
||||
boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
|
||||
@ -576,24 +633,14 @@ class DirectMethodHandle extends MethodHandle {
|
||||
assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
|
||||
|
||||
// getObject, putIntVolatile, etc.
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
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");
|
||||
}
|
||||
Kind kind = getFieldKind(isGetter, isVolatile, fw);
|
||||
|
||||
MethodType linkerType;
|
||||
if (isGetter)
|
||||
linkerType = MethodType.methodType(ft, Object.class, long.class);
|
||||
else
|
||||
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 {
|
||||
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
|
||||
} 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_OFFSET = nameCursor++; // Either static offset or field offset.
|
||||
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 PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
|
||||
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]);
|
||||
Object[] outArgs = new Object[1 + linkerType.parameterCount()];
|
||||
assert(outArgs.length == (isGetter ? 3 : 4));
|
||||
outArgs[0] = UNSAFE;
|
||||
outArgs[0] = names[U_HOLDER] = new Name(NF_UNSAFE);
|
||||
if (isStatic) {
|
||||
outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, 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);
|
||||
// add some detail to the lambdaForm debugname,
|
||||
// significant only for debugging
|
||||
StringBuilder nameBuilder = new StringBuilder(kind.methodName);
|
||||
if (isStatic) {
|
||||
nameBuilder.append("Static");
|
||||
} else {
|
||||
@ -657,7 +706,12 @@ class DirectMethodHandle extends MethodHandle {
|
||||
}
|
||||
if (needsCast) nameBuilder.append("Cast");
|
||||
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_checkCast,
|
||||
NF_allocateInstance,
|
||||
NF_constructorMethod;
|
||||
NF_constructorMethod,
|
||||
NF_UNSAFE;
|
||||
static {
|
||||
try {
|
||||
NamedFunction nfs[] = {
|
||||
@ -697,7 +752,9 @@ class DirectMethodHandle extends MethodHandle {
|
||||
NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("allocateInstance", Object.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.
|
||||
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
|
||||
|
@ -28,9 +28,11 @@ package java.lang.invoke;
|
||||
import java.util.Map;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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
|
||||
@ -66,14 +68,38 @@ class GenerateJLIClassesHelper {
|
||||
|
||||
static byte[] generateDirectMethodHandleHolderClassBytes(String className,
|
||||
MethodType[] methodTypes, int[] types) {
|
||||
LambdaForm[] forms = new LambdaForm[methodTypes.length];
|
||||
String[] names = new String[methodTypes.length];
|
||||
for (int i = 0; i < forms.length; i++) {
|
||||
forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i],
|
||||
types[i]);
|
||||
names[i] = forms[i].kind.defaultLambdaName;
|
||||
ArrayList<LambdaForm> forms = new ArrayList<>();
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
for (int i = 0; i < methodTypes.length; i++) {
|
||||
LambdaForm form = DirectMethodHandle
|
||||
.makePreparedLambdaForm(methodTypes[i], types[i]);
|
||||
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,
|
||||
@ -107,6 +133,34 @@ class GenerateJLIClassesHelper {
|
||||
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
|
||||
* a class with a specified name.
|
||||
@ -166,4 +220,5 @@ class GenerateJLIClassesHelper {
|
||||
BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
|
||||
shortTypes, types, className));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -607,7 +607,10 @@ class InvokerBytecodeGenerator {
|
||||
private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
|
||||
MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -629,6 +632,28 @@ class InvokerBytecodeGenerator {
|
||||
name = name + "_" + form.returnType().basicTypeChar();
|
||||
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_SPECIAL: // 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.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
import static java.lang.invoke.LambdaForm.*;
|
||||
import static java.lang.invoke.LambdaForm.Kind.*;
|
||||
|
||||
/**
|
||||
* 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");
|
||||
* 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;
|
||||
if (!customized) {
|
||||
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()
|
||||
}
|
||||
boolean isLinker, isGeneric;
|
||||
String debugName;
|
||||
Kind kind;
|
||||
switch (which) {
|
||||
case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; debugName = "invokeExact_MT"; break;
|
||||
case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; debugName = "exactInvoker"; break;
|
||||
case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; debugName = "invoke_MT"; break;
|
||||
case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; debugName = "invoker"; break;
|
||||
case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; kind = EXACT_LINKER; break;
|
||||
case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; kind = EXACT_INVOKER; break;
|
||||
case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; kind = GENERIC_LINKER; break;
|
||||
case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; kind = GENERIC_INVOKER; break;
|
||||
default: throw new InternalError();
|
||||
}
|
||||
LambdaForm lform;
|
||||
@ -323,7 +324,11 @@ class Invokers {
|
||||
names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]);
|
||||
}
|
||||
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)
|
||||
lform.compileToBytecode(); // JVM needs a real methodOop
|
||||
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"),
|
||||
REINVOKER("MH.reinvoke"),
|
||||
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_SPECIAL("DMH.invokeSpecial"),
|
||||
DIRECT_INVOKE_STATIC("DMH.invokeStatic"),
|
||||
DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"),
|
||||
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 methodName;
|
||||
@ -329,6 +369,10 @@ class LambdaForm {
|
||||
int arity, Name[] names) {
|
||||
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,
|
||||
int arity, Name[] names, boolean forceInline) {
|
||||
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
|
||||
// They verify that the built-in invokers process the correct raw data types.
|
||||
private static boolean argumentTypesMatch(String sig, Object[] av) {
|
||||
@ -1151,113 +1147,6 @@ class LambdaForm {
|
||||
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 =
|
||||
MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
|
||||
|
||||
@ -1920,12 +1809,7 @@ class LambdaForm {
|
||||
DEBUG_NAME_COUNTERS = null;
|
||||
}
|
||||
|
||||
// Put this last, so that previous static inits can run before.
|
||||
static {
|
||||
if (USE_PREDEFINED_INTERPRET_METHODS)
|
||||
computeInitialPreparedForms();
|
||||
NamedFunction.initializeInvokers();
|
||||
|
||||
// The Holder class will contain pre-generated forms resolved
|
||||
// using MemberName.getFactory(). However, that doesn't initialize the
|
||||
// class, which subtly breaks inlining etc. By forcing
|
||||
|
@ -1745,6 +1745,13 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||
return GenerateJLIClassesHelper
|
||||
.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 TRACE_INTERPRETER;
|
||||
static final boolean TRACE_METHOD_LINKAGE;
|
||||
static final boolean TRACE_RESOLVE;
|
||||
static final int COMPILE_THRESHOLD;
|
||||
static final boolean LOG_LF_COMPILATION_FAILURE;
|
||||
static final int DONT_INLINE_THRESHOLD;
|
||||
@ -65,6 +66,8 @@ import java.util.Properties;
|
||||
props.getProperty("java.lang.invoke.MethodHandle.TRACE_INTERPRETER"));
|
||||
TRACE_METHOD_LINKAGE = Boolean.parseBoolean(
|
||||
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(
|
||||
props.getProperty("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", "0"));
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
// discarded when user agent is to be closed, but
|
||||
// it is not expired.
|
||||
if (maxAge == MAX_AGE_UNSPECIFIED) return false;
|
||||
if (maxAge < 0) return false;
|
||||
|
||||
long deltaSecond = (System.currentTimeMillis() - whenCreated) / 1000;
|
||||
if (deltaSecond > maxAge)
|
||||
@ -952,7 +952,8 @@ public final class HttpCookie implements Cloneable {
|
||||
String attrName,
|
||||
String attrValue) {
|
||||
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.
|
||||
*/
|
||||
private static final Pattern PATTERN =
|
||||
private static class Lazy {
|
||||
static final Pattern PATTERN =
|
||||
Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?" +
|
||||
"(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of seconds in the duration.
|
||||
@ -387,7 +389,7 @@ public final class Duration
|
||||
*/
|
||||
public static Duration parse(CharSequence text) {
|
||||
Objects.requireNonNull(text, "text");
|
||||
Matcher matcher = PATTERN.matcher(text);
|
||||
Matcher matcher = Lazy.PATTERN.matcher(text);
|
||||
if (matcher.matches()) {
|
||||
// check for letter T but no time sections
|
||||
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.
|
||||
*
|
||||
* 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)) {
|
||||
throw new DateTimeException("Zone offset minutes and seconds must have the same sign");
|
||||
}
|
||||
if (Math.abs(minutes) > 59) {
|
||||
throw new DateTimeException("Zone offset minutes not in valid range: abs(value) " +
|
||||
Math.abs(minutes) + " is not in the range 0 to 59");
|
||||
if (minutes < -59 || minutes > 59) {
|
||||
throw new DateTimeException("Zone offset minutes not in valid range: value " +
|
||||
minutes + " is not in the range -59 to 59");
|
||||
}
|
||||
if (Math.abs(seconds) > 59) {
|
||||
throw new DateTimeException("Zone offset seconds not in valid range: abs(value) " +
|
||||
Math.abs(seconds) + " is not in the range 0 to 59");
|
||||
if (seconds < -59 || seconds > 59) {
|
||||
throw new DateTimeException("Zone offset seconds not in valid range: value " +
|
||||
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");
|
||||
}
|
||||
}
|
||||
@ -411,7 +411,7 @@ public final class ZoneOffset
|
||||
* @throws DateTimeException if the offset is not in the required range
|
||||
*/
|
||||
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");
|
||||
}
|
||||
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}.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(ZoneOffset other) {
|
||||
// abs(totalSeconds) <= MAX_SECONDS, so no overflow can happen here
|
||||
return other.totalSeconds - totalSeconds;
|
||||
}
|
||||
|
||||
|
@ -4566,7 +4566,10 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
|
||||
boolean modified = false;
|
||||
// Use (c instanceof Set) as a hint that lookup in c is as
|
||||
// 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(); ) {
|
||||
if (c.contains(it.next())) {
|
||||
it.remove();
|
||||
|
@ -353,7 +353,7 @@ class JarFile extends ZipFile {
|
||||
if (isMultiRelease) {
|
||||
return true;
|
||||
}
|
||||
if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) {
|
||||
if (MULTI_RELEASE_ENABLED) {
|
||||
try {
|
||||
checkForSpecialAttributes();
|
||||
} catch (IOException io) {
|
||||
@ -644,7 +644,7 @@ class JarFile extends ZipFile {
|
||||
return signers == null ? null : signers.clone();
|
||||
}
|
||||
JarFileEntry realEntry() {
|
||||
if (isMultiRelease()) {
|
||||
if (isMultiRelease() && versionMajor != BASE_VERSION_MAJOR) {
|
||||
String entryName = super.getName();
|
||||
return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this);
|
||||
}
|
||||
@ -960,7 +960,7 @@ class JarFile extends ZipFile {
|
||||
hasClassPathAttribute = match(CLASSPATH_CHARS, b,
|
||||
CLASSPATH_LASTOCC) != -1;
|
||||
// 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);
|
||||
if (i != -1) {
|
||||
i += MULTIRELEASE_CHARS.length;
|
||||
|
@ -29,6 +29,7 @@ import java.util.*;
|
||||
import java.util.jar.*;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.nio.file.*;
|
||||
import java.security.*;
|
||||
|
||||
import java.security.Provider.Service;
|
||||
@ -206,7 +207,7 @@ final class JceSecurity {
|
||||
|
||||
static {
|
||||
try {
|
||||
NULL_URL = new URL("http://null.sun.com/");
|
||||
NULL_URL = new URL("http://null.oracle.com/");
|
||||
} catch (Exception 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 {
|
||||
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");
|
||||
File importJar = new File(pathToPolicyJar, "local_policy.jar");
|
||||
// Sanity check the crypto.policy Security property. Single
|
||||
// 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()) {
|
||||
throw new SecurityException
|
||||
("Cannot locate policy or framework files!");
|
||||
if ((cryptoPolicyProperty == null) ||
|
||||
(cpPath.getNameCount() != 1) ||
|
||||
(cpPath.compareTo(cpPath.getFileName()) != 0)) {
|
||||
throw new SecurityException(
|
||||
"Invalid policy directory name format: " +
|
||||
cryptoPolicyProperty);
|
||||
}
|
||||
|
||||
// Read jurisdiction policies.
|
||||
CryptoPermissions defaultExport = new CryptoPermissions();
|
||||
CryptoPermissions exemptExport = new CryptoPermissions();
|
||||
loadPolicies(exportJar, defaultExport, exemptExport);
|
||||
// Prepend java.home to get the full path. normalize() in
|
||||
// case an extra "." or ".." snuck in somehow.
|
||||
String javaHomeProperty = System.getProperty("java.home");
|
||||
Path javaHomePolicyPath = Paths.get(javaHomeProperty, "conf",
|
||||
"security", "policy").normalize();
|
||||
Path cryptoPolicyPath = Paths.get(javaHomeProperty, "conf", "security",
|
||||
"policy", cryptoPolicyProperty).normalize();
|
||||
|
||||
CryptoPermissions defaultImport = new CryptoPermissions();
|
||||
CryptoPermissions exemptImport = new CryptoPermissions();
|
||||
loadPolicies(importJar, defaultImport, exemptImport);
|
||||
|
||||
// Merge the export and import policies for default applications.
|
||||
if (defaultExport.isEmpty() || defaultImport.isEmpty()) {
|
||||
throw new SecurityException("Missing mandatory jurisdiction " +
|
||||
"policy files");
|
||||
if (cryptoPolicyPath.getParent().compareTo(javaHomePolicyPath) != 0) {
|
||||
throw new SecurityException(
|
||||
"Invalid cryptographic jurisdiction policy directory path: " +
|
||||
cryptoPolicyProperty);
|
||||
}
|
||||
defaultPolicy = defaultExport.getMinimum(defaultImport);
|
||||
|
||||
// Merge the export and import policies for exempt applications.
|
||||
if (exemptExport.isEmpty()) {
|
||||
exemptPolicy = exemptImport.isEmpty() ? null : exemptImport;
|
||||
} else {
|
||||
exemptPolicy = exemptExport.getMinimum(exemptImport);
|
||||
if (!Files.isDirectory(cryptoPolicyPath)
|
||||
|| !Files.isReadable(cryptoPolicyPath)) {
|
||||
throw new SecurityException(
|
||||
"Can't read cryptographic policy directory: " +
|
||||
cryptoPolicyProperty);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the policies from the specified file. Also checks that the
|
||||
* policies are correctly signed.
|
||||
*/
|
||||
private static void loadPolicies(File jarPathName,
|
||||
CryptoPermissions defaultPolicy,
|
||||
CryptoPermissions exemptPolicy)
|
||||
throws Exception {
|
||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(
|
||||
cryptoPolicyPath, "{default,exempt}_*.policy")) {
|
||||
for (Path entry : stream) {
|
||||
try (InputStream is = new BufferedInputStream(
|
||||
Files.newInputStream(entry))) {
|
||||
String filename = entry.getFileName().toString();
|
||||
|
||||
JarFile jf = new JarFile(jarPathName);
|
||||
CryptoPermissions tmpPerms = new CryptoPermissions();
|
||||
tmpPerms.load(is);
|
||||
|
||||
Enumeration<JarEntry> entries = jf.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry je = entries.nextElement();
|
||||
InputStream is = null;
|
||||
try {
|
||||
if (je.getName().startsWith("default_")) {
|
||||
is = jf.getInputStream(je);
|
||||
defaultPolicy.load(is);
|
||||
} else if (je.getName().startsWith("exempt_")) {
|
||||
is = jf.getInputStream(je);
|
||||
exemptPolicy.load(is);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
if (filename.startsWith("default_")) {
|
||||
// Did we find a default perms?
|
||||
defaultPolicy = ((defaultPolicy == null) ? tmpPerms :
|
||||
defaultPolicy.getMinimum(tmpPerms));
|
||||
} else if (filename.startsWith("exempt_")) {
|
||||
// Did we find a exempt perms?
|
||||
exemptPolicy = ((exemptPolicy == null) ? tmpPerms :
|
||||
exemptPolicy.getMinimum(tmpPerms));
|
||||
} else {
|
||||
// This should never happen. newDirectoryStream
|
||||
// should only throw return "{default,exempt}_*.policy"
|
||||
throw new SecurityException(
|
||||
"Unexpected jurisdiction policy files in : " +
|
||||
cryptoPolicyProperty);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException(
|
||||
"Couldn't parse jurisdiction policy files in: " +
|
||||
cryptoPolicyProperty);
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce the signer restraint, i.e. signer of JCE framework
|
||||
// jar should also be the signer of the two jurisdiction policy
|
||||
// jar files.
|
||||
ProviderVerifier.verifyPolicySigned(je.getCertificates());
|
||||
} catch (DirectoryIteratorException ex) {
|
||||
// I/O error encountered during the iteration,
|
||||
// the cause is an IOException
|
||||
throw new SecurityException(
|
||||
"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() {
|
||||
|
@ -47,8 +47,8 @@ final class JrtDirectoryStream implements DirectoryStream<Path> {
|
||||
|
||||
private final JrtPath dir;
|
||||
private final DirectoryStream.Filter<? super Path> filter;
|
||||
private volatile boolean isClosed;
|
||||
private volatile Iterator<Path> itr;
|
||||
private boolean isClosed;
|
||||
private Iterator<Path> itr;
|
||||
|
||||
JrtDirectoryStream(JrtPath dir,
|
||||
DirectoryStream.Filter<? super java.nio.file.Path> filter)
|
||||
@ -73,24 +73,22 @@ final class JrtDirectoryStream implements DirectoryStream<Path> {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return new Iterator<Path>() {
|
||||
private Path next;
|
||||
@Override
|
||||
public synchronized boolean hasNext() {
|
||||
if (isClosed)
|
||||
return false;
|
||||
return itr.hasNext();
|
||||
public boolean hasNext() {
|
||||
synchronized (JrtDirectoryStream.this) {
|
||||
if (isClosed)
|
||||
return false;
|
||||
return itr.hasNext();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Path next() {
|
||||
if (isClosed)
|
||||
throw new NoSuchElementException();
|
||||
return itr.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
public Path next() {
|
||||
synchronized (JrtDirectoryStream.this) {
|
||||
if (isClosed)
|
||||
throw new NoSuchElementException();
|
||||
return itr.next();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -119,9 +119,7 @@ class JrtFileSystem extends FileSystem {
|
||||
|
||||
@Override
|
||||
public Iterable<Path> getRootDirectories() {
|
||||
ArrayList<Path> dirs = new ArrayList<>();
|
||||
dirs.add(getRootPath());
|
||||
return dirs;
|
||||
return Collections.singleton(getRootPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -159,9 +157,7 @@ class JrtFileSystem extends FileSystem {
|
||||
|
||||
@Override
|
||||
public final Iterable<FileStore> getFileStores() {
|
||||
ArrayList<FileStore> list = new ArrayList<>(1);
|
||||
list.add(getFileStore(getRootPath()));
|
||||
return list;
|
||||
return Collections.singleton(getFileStore(getRootPath()));
|
||||
}
|
||||
|
||||
private static final Set<String> supportedFileAttributeViews
|
||||
|
@ -46,7 +46,7 @@ public interface JavaLangInvokeAccess {
|
||||
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
|
||||
* an {@code int} representing method type. Used by
|
||||
* GenerateJLIClassesPlugin to generate such a class during the jlink phase.
|
||||
@ -55,7 +55,7 @@ public interface JavaLangInvokeAccess {
|
||||
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
|
||||
* {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to
|
||||
* generate such a class during the jlink phase.
|
||||
@ -64,7 +64,7 @@ public interface JavaLangInvokeAccess {
|
||||
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
|
||||
* by GenerateBMHClassesPlugin to enable generation of such classes during
|
||||
* the jlink phase. Should do some added validation since this string may be
|
||||
@ -74,8 +74,15 @@ public interface JavaLangInvokeAccess {
|
||||
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.
|
||||
*/
|
||||
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 {
|
||||
if (data.length > maxDataSize) {
|
||||
throw new BadPaddingException("Data must be shorter than "
|
||||
+ (maxDataSize + 1) + " bytes");
|
||||
+ (maxDataSize + 1) + " bytes but received "
|
||||
+ data.length + " bytes.");
|
||||
}
|
||||
switch (type) {
|
||||
case PAD_NONE:
|
||||
@ -281,7 +282,9 @@ public final class RSAPadding {
|
||||
*/
|
||||
public byte[] unpad(byte[] padded) throws BadPaddingException {
|
||||
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) {
|
||||
case PAD_NONE:
|
||||
|
@ -493,7 +493,9 @@ final class CipherBox {
|
||||
|
||||
if (protocolVersion.useTLS11PlusSpec()) {
|
||||
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
|
||||
* 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
|
||||
if (protocolVersion.useTLS11PlusSpec()) {
|
||||
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
|
||||
@ -756,7 +759,9 @@ final class CipherBox {
|
||||
// so accept that as well
|
||||
// v3 does not require any particular value for the other bytes
|
||||
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;
|
||||
@ -802,7 +807,9 @@ final class CipherBox {
|
||||
// so accept that as well
|
||||
// v3 does not require any particular value for the other bytes
|
||||
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:
|
||||
if (bb.remaining() < (recordIvSize + tagSize)) {
|
||||
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
|
||||
|
@ -27,15 +27,8 @@ package sun.util.calendar;
|
||||
|
||||
import java.io.IOException;
|
||||
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.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@ -80,8 +73,6 @@ public class ZoneInfo extends TimeZone {
|
||||
private static final long ABBR_MASK = 0xf00L;
|
||||
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.
|
||||
* Negative offsets are to the west of Greenwich. To obtain local
|
||||
@ -379,6 +370,7 @@ public class ZoneInfo extends TimeZone {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
Gregorian gcal = CalendarSystem.getGregorianCalendar();
|
||||
CalendarDate date = gcal.newCalendarDate(null);
|
||||
date.setDate(year, month + 1, day);
|
||||
if (gcal.validate(date) == false) {
|
||||
|
@ -490,7 +490,7 @@ networkaddress.cache.negative.ttl=10
|
||||
# property is set then those two properties are ignored.
|
||||
#
|
||||
# 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
|
||||
@ -505,7 +505,7 @@ networkaddress.cache.negative.ttl=10
|
||||
# property is ignored.
|
||||
#
|
||||
# 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
|
||||
@ -803,3 +803,94 @@ jdk.tls.legacyAlgorithms= \
|
||||
# E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \
|
||||
# EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \
|
||||
# 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 {
|
||||
// There is no restriction to any algorithms.
|
||||
permission javax.crypto.CryptoAllPermission;
|
@ -1,5 +1,5 @@
|
||||
// Some countries have import limits on crypto strength. So this file
|
||||
// will be useful.
|
||||
// Some countries have import limits on crypto strength, but may allow for
|
||||
// these exemptions if the exemption mechanism is used.
|
||||
|
||||
grant {
|
||||
// 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.
|
||||
|
||||
grant {
|
||||
// There is no restriction to any algorithms.
|
||||
permission javax.crypto.CryptoAllPermission;
|
@ -72,6 +72,8 @@ grant codeBase "jrt:/java.xml.crypto" {
|
||||
"removeProviderProperty.XMLDSig";
|
||||
permission java.security.SecurityPermission
|
||||
"com.sun.org.apache.xml.internal.security.register";
|
||||
permission java.security.SecurityPermission
|
||||
"getProperty.jdk.xml.dsig.secureValidationPolicy";
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/java.xml.ws" {
|
||||
|
@ -252,6 +252,21 @@ class UnixPath implements Path {
|
||||
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
|
||||
public UnixFileSystem getFileSystem() {
|
||||
return fs;
|
||||
@ -405,80 +420,94 @@ class UnixPath implements Path {
|
||||
|
||||
@Override
|
||||
public UnixPath relativize(Path obj) {
|
||||
UnixPath other = toUnixPath(obj);
|
||||
if (other.equals(this))
|
||||
UnixPath child = toUnixPath(obj);
|
||||
if (child.equals(this))
|
||||
return emptyPath();
|
||||
|
||||
// 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");
|
||||
|
||||
// this path is the empty path
|
||||
if (this.isEmpty())
|
||||
return other;
|
||||
return child;
|
||||
|
||||
int bn = this.getNameCount();
|
||||
int cn = other.getNameCount();
|
||||
UnixPath base = this;
|
||||
if (base.hasDotOrDotDot() || child.hasDotOrDotDot()) {
|
||||
base = base.normalize();
|
||||
child = child.normalize();
|
||||
}
|
||||
|
||||
int baseCount = base.getNameCount();
|
||||
int childCount = child.getNameCount();
|
||||
|
||||
// skip matching names
|
||||
int n = (bn > cn) ? cn : bn;
|
||||
int n = Math.min(baseCount, childCount);
|
||||
int i = 0;
|
||||
while (i < n) {
|
||||
if (!this.getName(i).equals(other.getName(i)))
|
||||
if (!base.getName(i).equals(child.getName(i)))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
int dotdots = bn - i;
|
||||
if (i < cn) {
|
||||
// remaining name components in other
|
||||
UnixPath remainder = other.subpath(i, cn);
|
||||
if (dotdots == 0)
|
||||
return remainder;
|
||||
|
||||
// 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);
|
||||
// remaining elements in child
|
||||
UnixPath childRemaining;
|
||||
boolean isChildEmpty;
|
||||
if (i == childCount) {
|
||||
childRemaining = emptyPath();
|
||||
isChildEmpty = true;
|
||||
} else {
|
||||
// no remaining names in other so result is simply a sequence of ".."
|
||||
byte[] result = new byte[dotdots*3 - 1];
|
||||
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);
|
||||
childRemaining = child.subpath(i, childCount);
|
||||
isChildEmpty = childRemaining.isEmpty();
|
||||
}
|
||||
|
||||
// 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
|
||||
public Path normalize() {
|
||||
public UnixPath normalize() {
|
||||
final int count = getNameCount();
|
||||
if (count == 0 || isEmpty())
|
||||
return this;
|
||||
|
@ -375,57 +375,108 @@ class WindowsPath implements 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
|
||||
public WindowsPath relativize(Path obj) {
|
||||
WindowsPath other = toWindowsPath(obj);
|
||||
if (this.equals(other))
|
||||
WindowsPath child = toWindowsPath(obj);
|
||||
if (this.equals(child))
|
||||
return emptyPath();
|
||||
|
||||
// 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");
|
||||
|
||||
// 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");
|
||||
|
||||
// this path is the empty path
|
||||
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
|
||||
int n = (bn > cn) ? cn : bn;
|
||||
int n = Math.min(baseCount, childCount);
|
||||
int i = 0;
|
||||
while (i < n) {
|
||||
if (!this.getName(i).equals(other.getName(i)))
|
||||
if (!base.getName(i).equals(child.getName(i)))
|
||||
break;
|
||||
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();
|
||||
for (int j=i; j<bn; j++) {
|
||||
for (int j=0; j<dotdots; j++) {
|
||||
result.append("..\\");
|
||||
}
|
||||
|
||||
// append remaining names in child
|
||||
if (!other.isEmpty()) {
|
||||
for (int j=i; j<cn; j++) {
|
||||
result.append(other.getName(j).toString());
|
||||
if (!isChildEmpty) {
|
||||
for (int j=0; j<childRemaining.getNameCount(); j++) {
|
||||
result.append(childRemaining.getName(j).toString());
|
||||
result.append("\\");
|
||||
}
|
||||
}
|
||||
|
||||
// drop trailing slash in result
|
||||
// drop trailing slash
|
||||
result.setLength(result.length()-1);
|
||||
return createFromNormalizedPath(getFileSystem(), result.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path normalize() {
|
||||
public WindowsPath normalize() {
|
||||
final int count = getNameCount();
|
||||
if (count == 0 || isEmpty())
|
||||
return this;
|
||||
|
@ -390,35 +390,27 @@ public final class KdcComm {
|
||||
|
||||
for (int i=1; i <= retries; i++) {
|
||||
String proto = useTCP?"TCP":"UDP";
|
||||
try (NetClient kdcClient = NetClient.getInstance(
|
||||
proto, kdc, port, timeout)) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KDCCommunication: kdc=" + kdc
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KDCCommunication: kdc=" + kdc
|
||||
+ " " + proto + ":"
|
||||
+ port + ", timeout="
|
||||
+ timeout
|
||||
+ ",Attempt =" + i
|
||||
+ ", #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 {
|
||||
/*
|
||||
* Send the data to the kdc.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
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.
|
||||
*
|
||||
* 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>
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setNull(String parameterName, int sqlType) throws SQLException {
|
||||
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>
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setNull (String parameterName, int sqlType, String typeName)
|
||||
throws SQLException{
|
||||
@ -3259,7 +3257,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setBoolean(String parameterName, boolean x) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setByte(String parameterName, byte x) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setShort(String parameterName, short x) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setInt(String parameterName, int x) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setLong(String parameterName, long x) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setFloat(String parameterName, float x) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setDouble(String parameterName, double x) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setString(String parameterName, String x) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setBytes(String parameterName, byte x[]) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setTimestamp(String parameterName, java.sql.Timestamp x)
|
||||
throws SQLException{
|
||||
@ -3474,7 +3461,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
||||
* this method is called on a closed <code>CallableStatement</code>
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setAsciiStream(String parameterName, java.io.InputStream x, int length)
|
||||
throws SQLException{
|
||||
@ -3500,7 +3486,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
||||
* this method is called on a closed <code>CallableStatement</code>
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setBinaryStream(String parameterName, java.io.InputStream x,
|
||||
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>
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setCharacterStream(String parameterName,
|
||||
java.io.Reader reader,
|
||||
@ -3684,7 +3668,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
||||
* this data type
|
||||
* @see Types
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setObject(String parameterName, Object x, int targetSqlType, int scale)
|
||||
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
|
||||
* this data type
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setObject(String parameterName, Object x, int targetSqlType)
|
||||
throws SQLException{
|
||||
@ -3751,7 +3733,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setObject(String parameterName, Object x) throws SQLException{
|
||||
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
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setDate(String parameterName, java.sql.Date x)
|
||||
throws SQLException {
|
||||
@ -4050,7 +4030,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setDate(String parameterName, java.sql.Date x, Calendar cal)
|
||||
throws SQLException {
|
||||
@ -4069,7 +4048,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setTime(String parameterName, java.sql.Time x)
|
||||
throws SQLException {
|
||||
@ -4095,7 +4073,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setTime(String parameterName, java.sql.Time x, Calendar cal)
|
||||
throws SQLException {
|
||||
@ -4121,7 +4098,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||
* this method
|
||||
* @see #getParams
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)
|
||||
throws SQLException {
|
||||
@ -4459,7 +4435,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
|
||||
* @exception SQLException if a database access error occurs or
|
||||
* this method is called on a closed <code>PreparedStatement</code>
|
||||
* @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 {
|
||||
throw new SQLFeatureNotSupportedException("Feature not supported");
|
||||
|
@ -57,7 +57,6 @@ public interface CommonDataSource {
|
||||
* logging is disabled
|
||||
* @exception java.sql.SQLException if a database access error occurs
|
||||
* @see #setLogWriter
|
||||
* @since 1.4
|
||||
*/
|
||||
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
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @see #getLogWriter
|
||||
* @since 1.4
|
||||
*/
|
||||
void setLogWriter(java.io.PrintWriter out) throws SQLException;
|
||||
|
||||
@ -94,7 +92,6 @@ public interface CommonDataSource {
|
||||
* @param seconds the data source login time limit
|
||||
* @exception SQLException if a database access error occurs.
|
||||
* @see #getLoginTimeout
|
||||
* @since 1.4
|
||||
*/
|
||||
void setLoginTimeout(int seconds) throws SQLException;
|
||||
|
||||
@ -109,7 +106,6 @@ public interface CommonDataSource {
|
||||
* @return the data source login time limit
|
||||
* @exception SQLException if a database access error occurs.
|
||||
* @see #setLoginTimeout
|
||||
* @since 1.4
|
||||
*/
|
||||
int getLoginTimeout() throws SQLException;
|
||||
|
||||
|
@ -72,6 +72,34 @@ public interface ConnectionPoolDataSource extends CommonDataSource {
|
||||
PooledConnection getPooledConnection(String user, String password)
|
||||
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 -----------------------------------
|
||||
|
||||
/**
|
||||
|
@ -109,6 +109,34 @@ public interface DataSource extends CommonDataSource, Wrapper {
|
||||
Connection getConnection(String username, String password)
|
||||
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
|
||||
|
||||
/**
|
||||
|
@ -81,7 +81,35 @@ public interface XADataSource extends CommonDataSource {
|
||||
XAConnection getXAConnection(String user, String password)
|
||||
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
|
||||
|
@ -150,7 +150,7 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi {
|
||||
this.macAlgorithm.init(secretKey);
|
||||
} catch (InvalidKeyException ex) {
|
||||
// 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;
|
||||
try {
|
||||
this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm());
|
||||
|
@ -112,7 +112,7 @@ public abstract class SignatureBaseRSA extends SignatureAlgorithmSpi {
|
||||
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
|
||||
} catch (InvalidKeyException ex) {
|
||||
// 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;
|
||||
try {
|
||||
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
|
||||
|
@ -139,7 +139,7 @@ public class SignatureDSA extends SignatureAlgorithmSpi {
|
||||
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
|
||||
} catch (InvalidKeyException ex) {
|
||||
// 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;
|
||||
try {
|
||||
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
|
||||
|
@ -252,7 +252,7 @@ public abstract class SignatureECDSA extends SignatureAlgorithmSpi {
|
||||
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
|
||||
} catch (InvalidKeyException ex) {
|
||||
// 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;
|
||||
try {
|
||||
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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 $
|
||||
@ -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.transforms.Transform;
|
||||
import com.sun.org.apache.xml.internal.security.transforms.Transforms;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dom.DOMCryptoContext;
|
||||
@ -150,7 +149,7 @@ public abstract class ApacheTransform extends TransformService {
|
||||
|
||||
if (Utils.secureValidation(xc)) {
|
||||
String algorithm = getAlgorithm();
|
||||
if (Transforms.TRANSFORM_XSLT.equals(algorithm)) {
|
||||
if (Policy.restrictAlg(algorithm)) {
|
||||
throw new TransformException(
|
||||
"Transform " + algorithm + " is forbidden when secure validation is enabled"
|
||||
);
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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 $
|
||||
@ -110,9 +110,10 @@ public final class DOMManifest extends DOMStructure implements Manifest {
|
||||
localName + ", expected Reference");
|
||||
}
|
||||
refs.add(new DOMReference(refElem, context, provider));
|
||||
if (secVal && (refs.size() > DOMSignedInfo.MAXIMUM_REFERENCE_COUNT)) {
|
||||
String error = "A maxiumum of " + DOMSignedInfo.MAXIMUM_REFERENCE_COUNT + " "
|
||||
+ "references per Manifest are allowed with secure validation";
|
||||
if (secVal && Policy.restrictNumReferences(refs.size())) {
|
||||
String error = "A maximum of " + Policy.maxReferences()
|
||||
+ " references per Manifest are allowed when"
|
||||
+ " secure validation is enabled";
|
||||
throw new MarshalException(error);
|
||||
}
|
||||
refElem = DOMUtils.getNextSiblingElement(refElem);
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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.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.signature.XMLSignatureInput;
|
||||
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
|
||||
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
|
||||
* will be added if necessary when generating the signature. See section
|
||||
@ -208,9 +202,10 @@ public final class DOMReference extends DOMStructure
|
||||
}
|
||||
transforms.add
|
||||
(new DOMTransform(transformElem, context, provider));
|
||||
if (secVal && (transforms.size() > MAXIMUM_TRANSFORM_COUNT)) {
|
||||
String error = "A maxiumum of " + MAXIMUM_TRANSFORM_COUNT + " "
|
||||
+ "transforms per Reference are allowed with secure validation";
|
||||
if (secVal && Policy.restrictNumTransforms(transforms.size())) {
|
||||
String error = "A maximum of " + Policy.maxTransforms()
|
||||
+ " transforms per Reference are allowed when"
|
||||
+ " secure validation is enabled";
|
||||
throw new MarshalException(error);
|
||||
}
|
||||
transformElem = DOMUtils.getNextSiblingElement(transformElem);
|
||||
@ -227,10 +222,10 @@ public final class DOMReference extends DOMStructure
|
||||
Element dmElem = nextSibling;
|
||||
this.digestMethod = DOMDigestMethod.unmarshal(dmElem);
|
||||
String digestMethodAlgorithm = this.digestMethod.getAlgorithm();
|
||||
if (secVal
|
||||
&& MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5.equals(digestMethodAlgorithm)) {
|
||||
if (secVal && Policy.restrictAlg(digestMethodAlgorithm)) {
|
||||
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.
|
||||
*/
|
||||
/*
|
||||
* 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
|
||||
(new DOMTransform(transformElem, context, provider));
|
||||
if (secVal && (transforms.size() > DOMReference.MAXIMUM_TRANSFORM_COUNT)) {
|
||||
String error = "A maxiumum of " + DOMReference.MAXIMUM_TRANSFORM_COUNT + " "
|
||||
+ "transforms per Reference are allowed with secure validation";
|
||||
if (secVal && Policy.restrictNumTransforms(transforms.size())) {
|
||||
String error = "A maximum of " + Policy.maxTransforms()
|
||||
+ " transforms per Reference are allowed when"
|
||||
+ " secure validation is enabled";
|
||||
throw new MarshalException(error);
|
||||
}
|
||||
transformElem = DOMUtils.getNextSiblingElement(transformElem);
|
||||
@ -238,7 +239,8 @@ public final class DOMRetrievalMethod extends DOMStructure
|
||||
}
|
||||
|
||||
// guard against RetrievalMethod loops
|
||||
if ((data instanceof NodeSetData) && Utils.secureValidation(context)) {
|
||||
if ((data instanceof NodeSetData) && Utils.secureValidation(context)
|
||||
&& Policy.restrictRetrievalMethodLoops()) {
|
||||
NodeSetData<?> nsd = (NodeSetData<?>)data;
|
||||
Iterator<?> i = nsd.iterator();
|
||||
if (i.hasNext()) {
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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 $
|
||||
@ -45,7 +45,6 @@ import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -55,22 +54,9 @@ import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream
|
||||
*/
|
||||
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 =
|
||||
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 CanonicalizationMethod canonicalizationMethod;
|
||||
private SignatureMethod signatureMethod;
|
||||
@ -158,10 +144,10 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
|
||||
boolean secVal = Utils.secureValidation(context);
|
||||
|
||||
String signatureMethodAlgorithm = signatureMethod.getAlgorithm();
|
||||
if (secVal && ((ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5.equals(signatureMethodAlgorithm)
|
||||
|| ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5.equals(signatureMethodAlgorithm)))) {
|
||||
if (secVal && Policy.restrictAlg(signatureMethodAlgorithm)) {
|
||||
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));
|
||||
|
||||
if (secVal && (refList.size() > MAXIMUM_REFERENCE_COUNT)) {
|
||||
String error = "A maxiumum of " + MAXIMUM_REFERENCE_COUNT + " "
|
||||
+ "references per Manifest are allowed with secure validation";
|
||||
if (secVal && Policy.restrictNumReferences(refList.size())) {
|
||||
String error = "A maximum of " + Policy.maxReferences()
|
||||
+ " references per Manifest are allowed when"
|
||||
+ " secure validation is enabled";
|
||||
throw new MarshalException(error);
|
||||
}
|
||||
refElem = DOMUtils.getNextSiblingElement(refElem);
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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 $
|
||||
@ -73,6 +73,11 @@ public class DOMURIDereferencer implements URIDereferencer {
|
||||
|
||||
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
|
||||
if (uri != null && uri.length() != 0 && uri.charAt(0) == '#') {
|
||||
String id = uri.substring(1);
|
||||
@ -83,12 +88,19 @@ public class DOMURIDereferencer implements URIDereferencer {
|
||||
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 (secVal) {
|
||||
if (secVal && Policy.restrictDuplicateIds()) {
|
||||
Element start = referencedElem.getOwnerDocument().getDocumentElement();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -110,9 +122,9 @@ public class DOMURIDereferencer implements URIDereferencer {
|
||||
|
||||
try {
|
||||
ResourceResolver apacheResolver =
|
||||
ResourceResolver.getInstance(uriAttr, baseURI, secVal);
|
||||
ResourceResolver.getInstance(uriAttr, baseURI, false);
|
||||
XMLSignatureInput in = apacheResolver.resolve(uriAttr,
|
||||
baseURI, secVal);
|
||||
baseURI, false);
|
||||
if (in.isOctetStream()) {
|
||||
return new ApacheOctetStreamData(in);
|
||||
} 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);
|
||||
tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
|
||||
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);
|
||||
n = tmpBuffer.length;
|
||||
|
@ -558,7 +558,7 @@ void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR
|
||||
pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
|
||||
if (pCharArray == NULL) { return; }
|
||||
|
||||
*ckpLength = strlen(pCharArray);
|
||||
*ckpLength = (CK_ULONG) strlen(pCharArray);
|
||||
*ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
|
||||
if (*ckpArray == NULL) {
|
||||
(*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.
|
||||
*
|
||||
* 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
|
||||
(JNIEnv *env, jclass thisClass, jstring jLibName)
|
||||
{
|
||||
void *hModule;
|
||||
const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
|
||||
if (libName == NULL) {
|
||||
return 0L;
|
||||
@ -56,9 +57,9 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
|
||||
|
||||
// look up existing handle only, do not load
|
||||
#if defined(AIX)
|
||||
void *hModule = dlopen(libName, RTLD_LAZY);
|
||||
hModule = dlopen(libName, RTLD_LAZY);
|
||||
#else
|
||||
void *hModule = dlopen(libName, RTLD_NOLOAD);
|
||||
hModule = dlopen(libName, RTLD_NOLOAD);
|
||||
#endif
|
||||
dprintf2("-handle for %s: %u\n", libName, hModule);
|
||||
(*env)->ReleaseStringUTFChars(env, jLibName, libName);
|
||||
|
@ -31,6 +31,9 @@
|
||||
|
||||
#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) {
|
||||
HINSTANCE hModule = (HINSTANCE)jHandle;
|
||||
void *fAddress = GetProcAddress(hModule, functionName);
|
||||
|
@ -24,5 +24,5 @@
|
||||
*/
|
||||
|
||||
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 Set<String> modules;
|
||||
|
||||
public DefaultExecutableImage(Path home, Set<String> modules) {
|
||||
this(home, modules, createArgs(home));
|
||||
}
|
||||
|
||||
private DefaultExecutableImage(Path home, Set<String> modules,
|
||||
List<String> args) {
|
||||
DefaultExecutableImage(Path home, Set<String> modules) {
|
||||
Objects.requireNonNull(home);
|
||||
Objects.requireNonNull(args);
|
||||
if (!Files.exists(home)) {
|
||||
throw new IllegalArgumentException("Invalid image home");
|
||||
}
|
||||
this.home = home;
|
||||
this.modules = Collections.unmodifiableSet(modules);
|
||||
this.args = Collections.unmodifiableList(args);
|
||||
this.args = createArgs(home);
|
||||
}
|
||||
|
||||
private static List<String> createArgs(Path home) {
|
||||
Objects.requireNonNull(home);
|
||||
List<String> javaArgs = new ArrayList<>();
|
||||
javaArgs.add(home.resolve("bin").
|
||||
resolve(getJavaProcessName()).toString());
|
||||
return javaArgs;
|
||||
Path binDir = home.resolve("bin");
|
||||
String java = Files.exists(binDir.resolve("java"))? "java" : "java.exe";
|
||||
return List.of(binDir.resolve(java).toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -130,6 +123,7 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
private final Path root;
|
||||
private final Path mdir;
|
||||
private final Set<String> modules = new HashSet<>();
|
||||
private String targetOsName;
|
||||
|
||||
/**
|
||||
* Default image builder constructor.
|
||||
@ -171,6 +165,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
@Override
|
||||
public void storeFiles(ResourcePool files) {
|
||||
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 -> {
|
||||
if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
try {
|
||||
@ -186,11 +185,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
modules.add(m.name());
|
||||
}
|
||||
});
|
||||
storeFiles(modules, releaseProperties(files));
|
||||
|
||||
storeFiles(modules, release);
|
||||
|
||||
if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
|
||||
// launchers in the bin directory need execute permission
|
||||
Path bin = root.resolve("bin");
|
||||
if (Files.isDirectory(bin)) {
|
||||
Files.list(bin)
|
||||
.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) {
|
||||
throw new PluginException(ex);
|
||||
}
|
||||
@ -226,6 +229,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
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");
|
||||
if (release.isPresent()) {
|
||||
try (InputStream is = release.get().content()) {
|
||||
@ -373,7 +381,7 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
Files.createLink(dstFile, target);
|
||||
}
|
||||
|
||||
private static String nativeDir(String filename) {
|
||||
private String nativeDir(String filename) {
|
||||
if (isWindows()) {
|
||||
if (filename.endsWith(".dll") || filename.endsWith(".diz")
|
||||
|| filename.endsWith(".pdb") || filename.endsWith(".map")) {
|
||||
@ -386,8 +394,8 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isWindows() {
|
||||
return System.getProperty("os.name").startsWith("Windows");
|
||||
private boolean isWindows() {
|
||||
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) {
|
||||
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 null;
|
||||
|
@ -172,7 +172,7 @@ public final class ImagePluginStack {
|
||||
private final Plugin lastSorter;
|
||||
private final List<Plugin> plugins = new ArrayList<>();
|
||||
private final List<ResourcePrevisitor> resourcePrevisitors = new ArrayList<>();
|
||||
|
||||
private final boolean validate;
|
||||
|
||||
public ImagePluginStack() {
|
||||
this(null, Collections.emptyList(), null);
|
||||
@ -181,6 +181,13 @@ public final class ImagePluginStack {
|
||||
public ImagePluginStack(ImageBuilder imageBuilder,
|
||||
List<Plugin> plugins,
|
||||
Plugin lastSorter) {
|
||||
this(imageBuilder, plugins, lastSorter, true);
|
||||
}
|
||||
|
||||
public ImagePluginStack(ImageBuilder imageBuilder,
|
||||
List<Plugin> plugins,
|
||||
Plugin lastSorter,
|
||||
boolean validate) {
|
||||
this.imageBuilder = Objects.requireNonNull(imageBuilder);
|
||||
this.lastSorter = lastSorter;
|
||||
this.plugins.addAll(Objects.requireNonNull(plugins));
|
||||
@ -190,6 +197,7 @@ public final class ImagePluginStack {
|
||||
resourcePrevisitors.add((ResourcePrevisitor) p);
|
||||
}
|
||||
});
|
||||
this.validate = validate;
|
||||
}
|
||||
|
||||
public void operate(ImageProvider provider) throws Exception {
|
||||
@ -268,6 +276,7 @@ public final class ImagePluginStack {
|
||||
frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList();
|
||||
}
|
||||
}
|
||||
|
||||
return resPool;
|
||||
}
|
||||
|
||||
@ -458,7 +467,11 @@ public final class ImagePluginStack {
|
||||
throws Exception {
|
||||
Objects.requireNonNull(original);
|
||||
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 {
|
||||
|
@ -5,7 +5,7 @@
|
||||
* 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 "Classfile" exception as provided
|
||||
* 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
|
||||
|
@ -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;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
@ -32,6 +36,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.misc.JavaLangInvokeAccess;
|
||||
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 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 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_STATIC = "invokeStatic";
|
||||
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_STATIC_INIT = "invokeStaticInit";
|
||||
|
||||
private static final String DELEGATING_METHOD_HANDLE = "java/lang/invoke/DelegatingMethodHandle$Holder";
|
||||
|
||||
private static final String BASIC_FORMS_HANDLE = "java/lang/invoke/LambdaForm$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 INVOKERS_HOLDER = "java/lang/invoke/Invokers$Holder";
|
||||
|
||||
private static final JavaLangInvokeAccess JLIA
|
||||
= SharedSecrets.getJavaLangInvokeAccess();
|
||||
|
||||
List<String> speciesTypes;
|
||||
|
||||
List<String> invokerTypes;
|
||||
|
||||
Map<String, List<String>> dmhMethods;
|
||||
|
||||
public GenerateJLIClassesPlugin() {
|
||||
@ -116,22 +117,30 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
||||
"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.
|
||||
*/
|
||||
public static Map<String, List<String>> defaultDMHMethods() {
|
||||
private static Map<String, List<String>> defaultDMHMethods() {
|
||||
return Map.of(
|
||||
DMH_INVOKE_VIRTUAL, List.of("_L", "L_L", "LI_I", "LL_V"),
|
||||
DMH_INVOKE_SPECIAL, List.of("L_I", "L_L", "LF_L", "LD_L", "LL_L",
|
||||
"L3_L", "L4_L", "L5_L", "L6_L", "L7_L", "LI_I", "LI_L", "LIL_I",
|
||||
"LII_I", "LII_L", "LLI_L", "LLI_I", "LILI_I", "LIIL_L",
|
||||
"LIILL_L", "LIILL_I", "LIIL_I", "LILIL_I", "LILILL_I",
|
||||
"LILII_I", "LI3_I", "LI3L_I", "LI3LL_I", "LI3_L", "LI4_I"),
|
||||
DMH_INVOKE_STATIC, List.of("II_I", "IL_I", "ILIL_I", "ILII_I",
|
||||
"_I", "_L", "_V", "D_L", "F_L", "I_I", "II_L", "LI_L",
|
||||
"L_V", "L_L", "LL_L", "L3_L", "L4_L", "L5_L", "L6_L",
|
||||
"L7_L", "L8_L", "L9_L", "L9I_L", "L9II_L", "L9IIL_L",
|
||||
"L10_L", "L11_L", "L12_L", "L13_L", "L13I_L", "L13II_L")
|
||||
DMH_INVOKE_VIRTUAL, List.of("L_L", "LL_L", "LLI_I", "L3_V"),
|
||||
DMH_INVOKE_SPECIAL, List.of("LL_I", "LL_L", "LLF_L", "LLD_L", "L3_L",
|
||||
"L4_L", "L5_L", "L6_L", "L7_L", "L8_L", "LLI_I", "LLI_L",
|
||||
"LLIL_I", "LLII_I", "LLII_L", "L3I_L", "L3I_I", "LLILI_I",
|
||||
"LLIIL_L", "LLIILL_L", "LLIILL_I", "LLIIL_I", "LLILIL_I",
|
||||
"LLILILL_I", "LLILII_I", "LLI3_I", "LLI3L_I", "LLI3LL_I",
|
||||
"LLI3_L", "LLI4_I"),
|
||||
DMH_INVOKE_STATIC, List.of("LII_I", "LIL_I", "LILIL_I", "LILII_I",
|
||||
"L_I", "L_L", "L_V", "LD_L", "LF_L", "LI_I", "LII_L", "LLI_L",
|
||||
"LL_V", "LL_L", "L3_L", "L4_L", "L5_L", "L6_L", "L7_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) {
|
||||
String mainArgument = config.get(NAME);
|
||||
|
||||
// Enable by default
|
||||
boolean bmhEnabled = true;
|
||||
boolean dmhEnabled = true;
|
||||
if (mainArgument != null) {
|
||||
List<String> args = Arrays.asList(mainArgument.split(","));
|
||||
if (!args.contains(BMH_PARAM)) {
|
||||
bmhEnabled = false;
|
||||
}
|
||||
if (!args.contains(DMH_PARAM)) {
|
||||
dmhEnabled = false;
|
||||
}
|
||||
}
|
||||
if (mainArgument != null && mainArgument.startsWith("@")) {
|
||||
File file = new File(mainArgument.substring(1));
|
||||
if (file.exists()) {
|
||||
speciesTypes = new ArrayList<>();
|
||||
invokerTypes = new ArrayList<>();
|
||||
dmhMethods = new HashMap<>();
|
||||
Stream<String> lines = fileLines(file);
|
||||
|
||||
if (!bmhEnabled) {
|
||||
speciesTypes = List.of();
|
||||
lines.map(line -> line.split(" "))
|
||||
.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 {
|
||||
String args = config.get(BMH_SPECIES_PARAM);
|
||||
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();
|
||||
}
|
||||
|
||||
List<String> bmhSpecies = defaultSpecies();
|
||||
// Expand BMH species signatures
|
||||
speciesTypes = bmhSpecies.stream()
|
||||
.map(type -> expandSignature(type))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// DirectMethodHandles
|
||||
if (!dmhEnabled) {
|
||||
dmhMethods = Map.of();
|
||||
} else {
|
||||
dmhMethods = new HashMap<>();
|
||||
for (String dmhParam : DMH_METHOD_TYPE_MAP.keySet()) {
|
||||
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();
|
||||
invokerTypes = defaultInvokers();
|
||||
validateMethodTypes(invokerTypes);
|
||||
|
||||
dmhMethods = defaultDMHMethods();
|
||||
for (List<String> dmhMethodTypes : dmhMethods.values()) {
|
||||
validateMethodTypes(dmhMethodTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if ("LIJFD".indexOf(c) < 0) {
|
||||
throw new PluginException(
|
||||
@ -228,9 +256,10 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
||||
// Copy all but DMH_ENTRY to out
|
||||
in.transformAndCopy(entry -> {
|
||||
// filter out placeholder entries
|
||||
if (entry.path().equals(DIRECT_METHOD_HANDLE_ENTRY) ||
|
||||
entry.path().equals(DELEGATING_METHOD_HANDLE_ENTRY) ||
|
||||
entry.path().equals(BASIC_FORMS_HANDLE_ENTRY)) {
|
||||
if (entry.path().equals(DIRECT_METHOD_HOLDER_ENTRY) ||
|
||||
entry.path().equals(DELEGATING_METHOD_HOLDER_ENTRY) ||
|
||||
entry.path().equals(INVOKERS_HOLDER_ENTRY) ||
|
||||
entry.path().equals(BASIC_FORMS_HOLDER_ENTRY)) {
|
||||
return null;
|
||||
} else {
|
||||
return entry;
|
||||
@ -265,42 +294,72 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
||||
for (List<String> entry : dmhMethods.values()) {
|
||||
count += entry.size();
|
||||
}
|
||||
MethodType[] methodTypes = new MethodType[count];
|
||||
MethodType[] directMethodTypes = new MethodType[count];
|
||||
int[] dmhTypes = new int[count];
|
||||
int index = 0;
|
||||
for (Map.Entry<String, List<String>> entry : dmhMethods.entrySet()) {
|
||||
String dmhType = entry.getKey();
|
||||
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);
|
||||
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 {
|
||||
byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes(
|
||||
DIRECT_METHOD_HANDLE, methodTypes, dmhTypes);
|
||||
DIRECT_HOLDER, directMethodTypes, dmhTypes);
|
||||
ResourcePoolEntry ndata = ResourcePoolEntry
|
||||
.create(DIRECT_METHOD_HANDLE_ENTRY, bytes);
|
||||
.create(DIRECT_METHOD_HOLDER_ENTRY, bytes);
|
||||
out.add(ndata);
|
||||
|
||||
bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes(
|
||||
DELEGATING_METHOD_HANDLE, methodTypes);
|
||||
ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HANDLE_ENTRY, bytes);
|
||||
DELEGATING_HOLDER, directMethodTypes);
|
||||
ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HOLDER_ENTRY, bytes);
|
||||
out.add(ndata);
|
||||
|
||||
bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HANDLE);
|
||||
ndata = ResourcePoolEntry.create(BASIC_FORMS_HANDLE_ENTRY, bytes);
|
||||
bytes = JLIA.generateInvokersHolderClassBytes(INVOKERS_HOLDER,
|
||||
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);
|
||||
} catch (Exception ex) {
|
||||
throw new PluginException(ex);
|
||||
}
|
||||
}
|
||||
private static final String DIRECT_METHOD_HANDLE_ENTRY =
|
||||
"/java.base/" + DIRECT_METHOD_HANDLE + ".class";
|
||||
private static final String DELEGATING_METHOD_HANDLE_ENTRY =
|
||||
"/java.base/" + DELEGATING_METHOD_HANDLE + ".class";
|
||||
private static final String BASIC_FORMS_HANDLE_ENTRY =
|
||||
"/java.base/" + BASIC_FORMS_HANDLE + ".class";
|
||||
private static final String DIRECT_METHOD_HOLDER_ENTRY =
|
||||
"/java.base/" + DIRECT_HOLDER + ".class";
|
||||
private static final String DELEGATING_METHOD_HOLDER_ENTRY =
|
||||
"/java.base/" + DELEGATING_HOLDER + ".class";
|
||||
private static final String BASIC_FORMS_HOLDER_ENTRY =
|
||||
"/java.base/" + BASIC_FORMS_HOLDER + ".class";
|
||||
private static final String INVOKERS_HOLDER_ENTRY =
|
||||
"/java.base/" + INVOKERS_HOLDER + ".class";
|
||||
|
||||
// Convert LL -> LL, L3 -> LLL
|
||||
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=\
|
||||
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
|
||||
|
||||
@ -68,10 +68,12 @@ exclude-resources.argument=<pattern-list> resources to exclude
|
||||
exclude-resources.description=\
|
||||
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=\
|
||||
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)
|
||||
|
||||
|
@ -165,8 +165,8 @@ class JarFileSystem extends ZipFileSystem {
|
||||
walk(inode.child, process);
|
||||
} else {
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
sun/rmi/runtime/Log/6409194/NoConsoleOutput.java 8164124 windows-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_security
|
||||
|
@ -205,12 +205,13 @@ public class VerifyStackTrace {
|
||||
.replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/")
|
||||
.replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run")
|
||||
.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("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
|
||||
// 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]+", "\\$??");
|
||||
} else {
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -68,6 +68,7 @@ public class NoLoopbackPackets {
|
||||
|
||||
MulticastSocket msock = null;
|
||||
List<SocketAddress> failedGroups = new ArrayList<SocketAddress>();
|
||||
Sender sender = null;
|
||||
try {
|
||||
msock = new MulticastSocket();
|
||||
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("ff02::1:1"), port));
|
||||
|
||||
Thread sender = new Thread(new Sender(groups));
|
||||
sender.setDaemon(true); // we want sender to stop when main thread exits
|
||||
sender.start();
|
||||
sender = new Sender(groups);
|
||||
new Thread(sender).start();
|
||||
|
||||
// Now try to receive multicast packets. we should not see any of them
|
||||
// since we disable loopback mode.
|
||||
@ -107,6 +107,9 @@ public class NoLoopbackPackets {
|
||||
}
|
||||
} finally {
|
||||
if (msock != null) try { msock.close(); } catch (Exception e) {}
|
||||
if (sender != null) {
|
||||
sender.stop();
|
||||
}
|
||||
}
|
||||
|
||||
if (failedGroups.size() > 0) {
|
||||
@ -119,6 +122,7 @@ public class NoLoopbackPackets {
|
||||
|
||||
static class Sender implements Runnable {
|
||||
private List<SocketAddress> sendToGroups;
|
||||
private volatile boolean stop;
|
||||
|
||||
public Sender(List<SocketAddress> groups) {
|
||||
sendToGroups = groups;
|
||||
@ -136,7 +140,7 @@ public class NoLoopbackPackets {
|
||||
|
||||
MulticastSocket msock = new MulticastSocket();
|
||||
msock.setLoopbackMode(true); // disable loopback mode
|
||||
for (;;) {
|
||||
while (!stop) {
|
||||
for (DatagramPacket packet : packets) {
|
||||
msock.send(packet);
|
||||
}
|
||||
@ -147,5 +151,9 @@ public class NoLoopbackPackets {
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -119,19 +119,31 @@ public class Basic {
|
||||
ExecutorService pool = Executors.newCachedThreadPool();
|
||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||
.withCachedThreadPool(pool, rand.nextInt(10));
|
||||
testShutdownWithChannels(pool, group);
|
||||
try {
|
||||
testShutdownWithChannels(pool, group);
|
||||
} finally {
|
||||
group.shutdown();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 100; i++) {
|
||||
int nThreads = 1 + rand.nextInt(8);
|
||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||
.withFixedThreadPool(nThreads, threadFactory);
|
||||
testShutdownWithChannels(null, group);
|
||||
try {
|
||||
testShutdownWithChannels(null, group);
|
||||
} finally {
|
||||
group.shutdown();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 100; i++) {
|
||||
ExecutorService pool = Executors.newCachedThreadPool();
|
||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||
.withThreadPool(pool);
|
||||
testShutdownWithChannels(pool, group);
|
||||
try {
|
||||
testShutdownWithChannels(pool, group);
|
||||
} finally {
|
||||
group.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,19 +176,31 @@ public class Basic {
|
||||
ExecutorService pool = pool = Executors.newCachedThreadPool();
|
||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||
.withCachedThreadPool(pool, rand.nextInt(5));
|
||||
testShutdownNow(pool, group);
|
||||
try {
|
||||
testShutdownNow(pool, group);
|
||||
} finally {
|
||||
group.shutdown();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int nThreads = 1 + rand.nextInt(8);
|
||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||
.withFixedThreadPool(nThreads, threadFactory);
|
||||
testShutdownNow(null, group);
|
||||
try {
|
||||
testShutdownNow(null, group);
|
||||
} finally {
|
||||
group.shutdown();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ExecutorService pool = Executors.newCachedThreadPool();
|
||||
AsynchronousChannelGroup group = AsynchronousChannelGroup
|
||||
.withThreadPool(pool);
|
||||
testShutdownNow(pool, group);
|
||||
try {
|
||||
testShutdownNow(pool, group);
|
||||
} finally {
|
||||
group.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,78 +210,78 @@ public class Basic {
|
||||
AsynchronousChannelGroup group =
|
||||
AsynchronousChannelGroup.withFixedThreadPool(1, threadFactory);
|
||||
|
||||
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
|
||||
AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open(group);
|
||||
try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
|
||||
AsynchronousServerSocketChannel listener =
|
||||
AsynchronousServerSocketChannel.open(group)) {
|
||||
|
||||
// initiate accept
|
||||
listener.bind(new InetSocketAddress(0));
|
||||
Future<AsynchronousSocketChannel> result = listener.accept();
|
||||
// initiate accept
|
||||
listener.bind(new InetSocketAddress(0));
|
||||
Future<AsynchronousSocketChannel> result = listener.accept();
|
||||
|
||||
// shutdown group
|
||||
group.shutdown();
|
||||
if (!group.isShutdown())
|
||||
throw new RuntimeException("Group should be shutdown");
|
||||
// shutdown group
|
||||
group.shutdown();
|
||||
if (!group.isShutdown())
|
||||
throw new RuntimeException("Group should be shutdown");
|
||||
|
||||
// attempt to create another channel
|
||||
try {
|
||||
AsynchronousSocketChannel.open(group);
|
||||
throw new RuntimeException("ShutdownChannelGroupException expected");
|
||||
} catch (ShutdownChannelGroupException x) {
|
||||
// attempt to create another channel
|
||||
try {
|
||||
AsynchronousSocketChannel.open(group);
|
||||
throw new RuntimeException("ShutdownChannelGroupException expected");
|
||||
} 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 {
|
||||
|
@ -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.
|
||||
*
|
||||
* 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 static void main(String[] args) throws Exception {
|
||||
final List<AsynchronousSocketChannel> accepted = new ArrayList<>();
|
||||
|
||||
// create listener to accept connections
|
||||
final AsynchronousServerSocketChannel listener =
|
||||
AsynchronousServerSocketChannel.open()
|
||||
.bind(new InetSocketAddress(0));
|
||||
final List<AsynchronousSocketChannel> accepted = new ArrayList<AsynchronousSocketChannel>();
|
||||
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
|
||||
public void completed(AsynchronousSocketChannel ch, Void att) {
|
||||
synchronized (accepted) {
|
||||
accepted.add(ch);
|
||||
try (final AsynchronousServerSocketChannel listener =
|
||||
AsynchronousServerSocketChannel.open()) {
|
||||
|
||||
listener.bind(new InetSocketAddress(0));
|
||||
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
|
||||
public void completed(AsynchronousSocketChannel ch, Void att) {
|
||||
synchronized (accepted) {
|
||||
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();
|
||||
SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
|
||||
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
|
||||
SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
|
||||
|
||||
test(sa, true, false);
|
||||
test(sa, false, true);
|
||||
test(sa, true, true);
|
||||
|
||||
// clean-up
|
||||
listener.close();
|
||||
synchronized (accepted) {
|
||||
for (AsynchronousSocketChannel ch: accepted) {
|
||||
ch.close();
|
||||
test(sa, true, false);
|
||||
test(sa, false, true);
|
||||
test(sa, true, true);
|
||||
} finally {
|
||||
// clean-up
|
||||
synchronized (accepted) {
|
||||
for (AsynchronousSocketChannel ch: accepted) {
|
||||
ch.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,60 +88,60 @@ public class GroupOfOne {
|
||||
return new Thread(r);
|
||||
}});
|
||||
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:
|
||||
// 1. The read operation fails (expected)
|
||||
// 2. the close/shutdown completes
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
ch.connect(sa, (Void)null, new CompletionHandler<Void,Void>() {
|
||||
public void completed(Void result, Void att) {
|
||||
System.out.println("Connected");
|
||||
|
||||
ch.connect(sa, (Void)null, new CompletionHandler<Void,Void>() {
|
||||
public void completed(Void result, Void att) {
|
||||
System.out.println("Connected");
|
||||
// initiate I/O operation that does not complete (successfully)
|
||||
ByteBuffer buf = ByteBuffer.allocate(100);
|
||||
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)
|
||||
ByteBuffer buf = ByteBuffer.allocate(100);
|
||||
ch.read(buf, (Void)null, new CompletionHandler<Integer,Void>() {
|
||||
public void completed(Integer bytesRead, Void att) {
|
||||
// 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) {
|
||||
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) {
|
||||
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");
|
||||
public void failed(Throwable exc, Void att) {
|
||||
throw new RuntimeException(exc);
|
||||
}
|
||||
});
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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 {
|
||||
// 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
|
||||
final int groupCount = 3 + rand.nextInt(8);
|
||||
AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[groupCount];
|
||||
final AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[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
|
||||
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
|
||||
ch.connect(sa).get();
|
||||
channels[i] = ch;
|
||||
}
|
||||
// create listener to accept connections
|
||||
try (final AsynchronousServerSocketChannel listener =
|
||||
AsynchronousServerSocketChannel.open()) {
|
||||
|
||||
// randomly write to each channel, ensuring that the completion handler
|
||||
// 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();
|
||||
listener.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);
|
||||
|
||||
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
|
||||
done.await();
|
||||
// randomly write to each channel, ensuring that the completion handler
|
||||
// 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
|
||||
for (AsynchronousSocketChannel ch: channels)
|
||||
ch.close();
|
||||
for (AsynchronousChannelGroup group: groups)
|
||||
group.shutdownNow();
|
||||
listener.close();
|
||||
// wait until done
|
||||
done.await();
|
||||
} finally {
|
||||
// clean-up
|
||||
for (AsynchronousSocketChannel ch: channels)
|
||||
ch.close();
|
||||
for (AsynchronousChannelGroup group: groups)
|
||||
group.shutdownNow();
|
||||
|
||||
if (failed.get())
|
||||
throw new RuntimeException("Test failed - see log for details");
|
||||
if (failed.get())
|
||||
throw new RuntimeException("Test failed - see log for details");
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
int nThreads = 1 + rand.nextInt(4);
|
||||
AsynchronousChannelGroup group =
|
||||
AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
|
||||
testRestart(group, 100);
|
||||
group.shutdown();
|
||||
AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
|
||||
try {
|
||||
testRestart(group, 100);
|
||||
} finally {
|
||||
group.shutdown();
|
||||
}
|
||||
|
||||
// group with cached thread pool
|
||||
ExecutorService pool = Executors.newCachedThreadPool(factory);
|
||||
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
|
||||
testRestart(group, 100);
|
||||
group.shutdown();
|
||||
try {
|
||||
testRestart(group, 100);
|
||||
} finally {
|
||||
group.shutdown();
|
||||
}
|
||||
|
||||
// group with custom thread pool
|
||||
group = AsynchronousChannelGroup
|
||||
.withThreadPool(Executors.newFixedThreadPool(1+rand.nextInt(5), factory));
|
||||
testRestart(group, 100);
|
||||
group.shutdown();
|
||||
group = AsynchronousChannelGroup.withThreadPool(
|
||||
Executors.newFixedThreadPool(1+rand.nextInt(5), factory));
|
||||
try {
|
||||
testRestart(group, 100);
|
||||
} finally {
|
||||
group.shutdown();
|
||||
}
|
||||
|
||||
// give time for threads to terminate
|
||||
Thread.sleep(3000);
|
||||
@ -92,45 +101,43 @@ public class Restart {
|
||||
static void testRestart(AsynchronousChannelGroup group, int count)
|
||||
throws Exception
|
||||
{
|
||||
AsynchronousServerSocketChannel listener =
|
||||
AsynchronousServerSocketChannel.open(group)
|
||||
.bind(new InetSocketAddress(0));
|
||||
try (AsynchronousServerSocketChannel listener =
|
||||
AsynchronousServerSocketChannel.open(group)) {
|
||||
|
||||
for (int i=0; i<count; i++) {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
listener.bind(new InetSocketAddress(0));
|
||||
for (int i=0; i<count; i++) {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
|
||||
public void completed(AsynchronousSocketChannel ch, Void att) {
|
||||
try {
|
||||
ch.close();
|
||||
} catch (IOException ignore) { }
|
||||
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
|
||||
public void completed(AsynchronousSocketChannel ch, Void att) {
|
||||
try {
|
||||
ch.close();
|
||||
} catch (IOException ignore) { }
|
||||
|
||||
latch.countDown();
|
||||
latch.countDown();
|
||||
|
||||
// throw error or runtime exception
|
||||
if (rand.nextBoolean()) {
|
||||
throw new Error();
|
||||
} else {
|
||||
throw new RuntimeException();
|
||||
// throw error or runtime exception
|
||||
if (rand.nextBoolean()) {
|
||||
throw new Error();
|
||||
} else {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void failed(Throwable exc, Void att) {
|
||||
}
|
||||
});
|
||||
public void failed(Throwable exc, Void att) {
|
||||
}
|
||||
});
|
||||
|
||||
// establish loopback connection which should cause completion
|
||||
// handler to be invoked.
|
||||
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
|
||||
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
|
||||
InetAddress lh = InetAddress.getLocalHost();
|
||||
ch.connect(new InetSocketAddress(lh, port)).get();
|
||||
ch.close();
|
||||
// establish loopback connection which should cause completion
|
||||
// handler to be invoked.
|
||||
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
|
||||
try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()) {
|
||||
InetAddress lh = InetAddress.getLocalHost();
|
||||
ch.connect(new InetSocketAddress(lh, port)).get();
|
||||
}
|
||||
|
||||
// wait for handler to be invoked
|
||||
latch.await();
|
||||
// wait for handler to be invoked
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,8 +22,8 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4429043 4493595 6332756 6709457
|
||||
* @summary The FileChannel file locking
|
||||
* @bug 4429043 4493595 6332756 6709457 7146506
|
||||
* @summary Test FileChannel file locking
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
@ -33,17 +33,14 @@ import static java.nio.file.StandardOpenOption.*;
|
||||
/**
|
||||
* Testing FileChannel's lock method.
|
||||
*/
|
||||
|
||||
public class Lock {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length > 0) {
|
||||
if(args[0].equals("1")) {
|
||||
MadWriter mw = new MadWriter(args[1], false);
|
||||
} else {
|
||||
MadWriter mw = new MadWriter(args[1], true);
|
||||
}
|
||||
if (args.length == 2) {
|
||||
attemptLock(args[1], args[0].equals("2"));
|
||||
return;
|
||||
} else if (args.length != 0) {
|
||||
throw new RuntimeException("Wrong number of parameters.");
|
||||
}
|
||||
File blah = File.createTempFile("blah", null);
|
||||
blah.deleteOnExit();
|
||||
@ -56,120 +53,128 @@ public class Lock {
|
||||
test2(blah, false);
|
||||
test3(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 {
|
||||
try (RandomAccessFile fis = new RandomAccessFile(blah, "rw")) {
|
||||
FileChannel fc = fis.getChannel();
|
||||
FileLock lock = null;
|
||||
|
||||
// Grab the lock
|
||||
RandomAccessFile fis = new RandomAccessFile(blah, "rw");
|
||||
FileChannel fc = fis.getChannel();
|
||||
FileLock lock = null;
|
||||
|
||||
if (str.equals("1")) {
|
||||
lock = fc.lock(0, 10, false);
|
||||
if (lock == null)
|
||||
throw new RuntimeException("Lock should not return null");
|
||||
try {
|
||||
FileLock lock2 = fc.lock(5, 10, false);
|
||||
throw new RuntimeException("Overlapping locks allowed");
|
||||
} catch (OverlappingFileLockException e) {
|
||||
// Correct result
|
||||
// grab the lock
|
||||
if (str.equals("1")) {
|
||||
lock = fc.lock(0, 10, false);
|
||||
if (lock == null)
|
||||
throw new RuntimeException("Lock should not return null");
|
||||
try {
|
||||
fc.lock(5, 10, false);
|
||||
throw new RuntimeException("Overlapping locks allowed");
|
||||
} catch (OverlappingFileLockException e) {} // correct result
|
||||
}
|
||||
}
|
||||
|
||||
// Exec the tamperer
|
||||
String command = System.getProperty("java.home") +
|
||||
File.separator + "bin" + File.separator + "java";
|
||||
String testClasses = System.getProperty("test.classes");
|
||||
if (testClasses != null)
|
||||
command += " -cp " + testClasses;
|
||||
command += " Lock " + str + " " + blah;
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
// execute the tamperer
|
||||
String command = System.getProperty("java.home") +
|
||||
File.separator + "bin" + File.separator + "java";
|
||||
String testClasses = System.getProperty("test.classes");
|
||||
if (testClasses != null)
|
||||
command += " -cp " + testClasses;
|
||||
command += " Lock " + str + " " + blah;
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
|
||||
BufferedReader in = new BufferedReader
|
||||
(new InputStreamReader(p.getInputStream()));
|
||||
|
||||
String s;
|
||||
int count = 0;
|
||||
while ((s = in.readLine()) != null) {
|
||||
if (!s.equals("good")) {
|
||||
if (File.separatorChar == '/') {
|
||||
// Fails on windows over NFS...
|
||||
throw new RuntimeException("Failed: "+s);
|
||||
// evaluate System.out of child process
|
||||
String s;
|
||||
boolean hasOutput = false;
|
||||
InputStreamReader isr;
|
||||
isr = new InputStreamReader(p.getInputStream());
|
||||
BufferedReader br = new BufferedReader(isr);
|
||||
while ((s = br.readLine()) != null) {
|
||||
// only throw on Unix as windows over NFS fails...
|
||||
if ((File.separatorChar == '/') && !s.equals("good")) {
|
||||
throw new RuntimeException("Failed: " + s);
|
||||
}
|
||||
hasOutput = true;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
in = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
while ((s = in.readLine()) != null) {
|
||||
System.err.println("Error output: " + s);
|
||||
// evaluate System.err in case of System.out of child process
|
||||
// was empty
|
||||
if (!hasOutput) {
|
||||
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
|
||||
if (lock != null) {
|
||||
/* Check multiple releases */
|
||||
lock.release();
|
||||
lock.release();
|
||||
// clean up, check multiple releases
|
||||
if (lock != null) {
|
||||
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 {
|
||||
FileChannel fc1 = new RandomAccessFile(blah, "rw").getChannel();
|
||||
FileChannel fc2 = new RandomAccessFile(blah, "rw").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) {
|
||||
/**
|
||||
* Basic test for FileChannel.lock() and FileChannel.tryLock()
|
||||
*/
|
||||
static void test2(File blah, boolean b) throws Exception {
|
||||
try (RandomAccessFile raf = new RandomAccessFile(blah, "rw")) {
|
||||
FileChannel channel = raf.getChannel();
|
||||
FileLock lock;
|
||||
if (b)
|
||||
lock = channel.lock();
|
||||
else
|
||||
lock = channel.tryLock();
|
||||
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();
|
||||
throw new RuntimeException("Overlapping locks allowed");
|
||||
} catch (OverlappingFileLockException x) {
|
||||
try {
|
||||
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
|
||||
*/
|
||||
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(0L, 1L, false).release();
|
||||
fc.lock().release();
|
||||
@ -182,30 +187,31 @@ public class Lock {
|
||||
fc.lock(0L, 1L, false).release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MadWriter {
|
||||
public MadWriter(String s, boolean b) throws Exception {
|
||||
File f = new File(s);
|
||||
RandomAccessFile fos = new RandomAccessFile(f, "rw");
|
||||
FileChannel fc = fos.getChannel();
|
||||
if (fc.tryLock(10, 10, false) == null) {
|
||||
System.out.println("bad: Failed to grab adjacent lock");
|
||||
/**
|
||||
* Utility method to be run in secondary process which tries to acquire a
|
||||
* lock on a FileChannel
|
||||
*/
|
||||
static void attemptLock(String fileName,
|
||||
boolean expectsLock) throws Exception
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static int checkContentTypes(String[] extensions, String[][] expectedTypes)
|
||||
static int checkContentTypes(String[] extensions, String[] expectedTypes)
|
||||
throws IOException {
|
||||
if (extensions.length != expectedTypes.length) {
|
||||
System.err.println("Parameter array lengths differ");
|
||||
@ -112,27 +112,10 @@ public class Basic {
|
||||
System.err.println("Content type of " + extension
|
||||
+ " cannot be determined");
|
||||
failures++;
|
||||
} else {
|
||||
boolean isTypeFound = false;
|
||||
for (String s : expectedTypes[i]) {
|
||||
if (type.equals(s)) {
|
||||
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++;
|
||||
}
|
||||
} else if (!type.equals(expectedTypes[i])) {
|
||||
System.err.printf("Content type: %s; expected: %s%n",
|
||||
type, expectedTypes);
|
||||
failures++;
|
||||
}
|
||||
} finally {
|
||||
Files.delete(file);
|
||||
@ -174,8 +157,6 @@ public class Basic {
|
||||
|
||||
// Verify that certain media extensions are mapped to the correct type.
|
||||
String[] extensions = new String[]{
|
||||
"aac",
|
||||
"flac",
|
||||
"jpg",
|
||||
"mp3",
|
||||
"mp4",
|
||||
@ -183,15 +164,13 @@ public class Basic {
|
||||
"png",
|
||||
"webm"
|
||||
};
|
||||
String[][] expectedTypes = new String[][] {
|
||||
{"audio/aac", "audio/x-aac", "audio/vnd.dlna.adts"},
|
||||
{"audio/flac", "audio/x-flac"},
|
||||
{"image/jpeg"},
|
||||
{"audio/mpeg"},
|
||||
{"video/mp4"},
|
||||
{"application/pdf"},
|
||||
{"image/png"},
|
||||
{"video/webm"}
|
||||
String[] expectedTypes = new String[] {
|
||||
"image/jpeg",
|
||||
"audio/mpeg",
|
||||
"video/mp4",
|
||||
"application/pdf",
|
||||
"image/png",
|
||||
"video/webm"
|
||||
};
|
||||
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 top = Files.createTempDirectory(testDir, "LotsOfCancels");
|
||||
for (int i=1; i<=16; i++) {
|
||||
int id = i;
|
||||
Path dir = Files.createDirectory(top.resolve("dir-" + i));
|
||||
WatchService watcher = FileSystems.getDefault().newWatchService();
|
||||
pool.submit(() -> handle(dir, watcher));
|
||||
pool.submit(() -> poll(watcher));
|
||||
pool.submit(() -> handle(id, dir, watcher));
|
||||
pool.submit(() -> poll(id, watcher));
|
||||
}
|
||||
} finally {
|
||||
pool.shutdown();
|
||||
@ -74,7 +75,8 @@ public class LotsOfCancels {
|
||||
* Stress the given WatchService, specifically the cancel method, in
|
||||
* 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 {
|
||||
Path file = dir.resolve("anyfile");
|
||||
@ -85,12 +87,15 @@ public class LotsOfCancels {
|
||||
key.cancel();
|
||||
}
|
||||
} finally {
|
||||
System.out.printf("WatchService %d closing ...%n", id);
|
||||
watcher.close();
|
||||
System.out.printf("WatchService %d closed %n", id);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
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
|
||||
* 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 {
|
||||
for (;;) {
|
||||
WatchKey key = watcher.take();
|
||||
@ -108,10 +114,12 @@ public class LotsOfCancels {
|
||||
}
|
||||
}
|
||||
} 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) {
|
||||
e.printStackTrace();
|
||||
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.
|
||||
*
|
||||
* 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.*;
|
||||
|
||||
public class UpdateInterference {
|
||||
|
||||
private static volatile boolean stop;
|
||||
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
final Path root = Files.createTempDirectory("test");
|
||||
final Path foo = root.resolve("foo");
|
||||
@ -43,64 +46,89 @@ public class UpdateInterference {
|
||||
Files.createDirectory(bar);
|
||||
Files.createDirectory(baz);
|
||||
|
||||
final WatchService watcher = root.getFileSystem().newWatchService();
|
||||
final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE);
|
||||
final WatchKey barKey = bar.register(watcher, ENTRY_CREATE);
|
||||
try (final WatchService watcher = root.getFileSystem().newWatchService()) {
|
||||
final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE);
|
||||
final WatchKey barKey = bar.register(watcher, ENTRY_CREATE);
|
||||
|
||||
new Thread() {
|
||||
{ setDaemon(true); }
|
||||
Thread t1 = null;
|
||||
Thread t2 = null;
|
||||
try {
|
||||
t1 = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
final Path temp = Files.createTempFile(foo, "temp", ".tmp");
|
||||
Files.delete(temp);
|
||||
Thread.sleep(10);
|
||||
} catch (IOException | InterruptedException 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);
|
||||
@Override
|
||||
public void run() {
|
||||
while (!stop) {
|
||||
try {
|
||||
final Path temp = Files.createTempFile(foo, "temp", ".tmp");
|
||||
Files.delete(temp);
|
||||
Thread.sleep(10);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
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();
|
||||
|
||||
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 {
|
||||
// clean up
|
||||
Files.delete(foo);
|
||||
Files.delete(bar);
|
||||
Files.delete(baz);
|
||||
Files.delete(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
@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
|
||||
public void test_factory_ofTotalSeconds() {
|
||||
@ -437,6 +452,11 @@ public class TCKZoneOffset extends AbstractDateTimeTest {
|
||||
ZoneOffset.ofTotalSeconds(-18 * 60 * 60 - 1);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions=DateTimeException.class)
|
||||
public void test_factory_ofTotalSeconds_minValue() {
|
||||
ZoneOffset.ofTotalSeconds(Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// from()
|
||||
//-----------------------------------------------------------------------
|
||||
|
@ -359,6 +359,21 @@ public class ConcurrentHashMapTest extends JSR166TestCase {
|
||||
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
|
||||
*/
|
||||
|
@ -80,7 +80,7 @@ public class MultiReleaseJarAPI {
|
||||
}
|
||||
|
||||
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())) {
|
||||
|
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 = .
|
||||
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
* to its child class loader. Also sanity check java.compact2
|
||||
* requires.
|
||||
* @modules java.compact2
|
||||
* @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.ModuleReference;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Module;
|
||||
import java.util.Set;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
|
||||
|
||||
@ -58,8 +61,9 @@ public class VerifyModuleDelegation {
|
||||
.requires(Set.of(PUBLIC), "java.xml")
|
||||
.build();
|
||||
|
||||
private static final Set<ModuleReference> MREFS
|
||||
= ModuleFinder.ofSystem().findAll();
|
||||
private static final Set<ModuleDescriptor> MREFS
|
||||
= Layer.boot().modules().stream().map(Module::getDescriptor)
|
||||
.collect(toSet());
|
||||
|
||||
private void check(ModuleDescriptor md, ModuleDescriptor ref) {
|
||||
assertTrue(md.requires().size() == ref.requires().size());
|
||||
@ -69,7 +73,7 @@ public class VerifyModuleDelegation {
|
||||
@Test
|
||||
public void checkJavaBase() {
|
||||
ModuleDescriptor md =
|
||||
MREFS.stream().map(ModuleReference::descriptor)
|
||||
MREFS.stream()
|
||||
.filter(d -> d.name().equals(JAVA_BASE))
|
||||
.findFirst().orElseThrow(Error::new);
|
||||
|
||||
@ -78,7 +82,7 @@ public class VerifyModuleDelegation {
|
||||
@Test
|
||||
public void checkCompact2() {
|
||||
ModuleDescriptor md =
|
||||
MREFS.stream().map(ModuleReference::descriptor)
|
||||
MREFS.stream()
|
||||
.filter(d -> d.name().equals(JAVA_COMPACT2))
|
||||
.findFirst().orElseThrow(Error::new);
|
||||
check(md, COMPACT2);
|
||||
@ -87,7 +91,7 @@ public class VerifyModuleDelegation {
|
||||
@Test
|
||||
public void checkLoaderDelegation() {
|
||||
Layer boot = Layer.boot();
|
||||
MREFS.stream().map(ModuleReference::descriptor)
|
||||
MREFS.stream()
|
||||
.forEach(md -> md.requires().stream().forEach(req ->
|
||||
{
|
||||
// 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